diff --git a/src/gui_2.py b/src/gui_2.py index 590a550..4771fc3 100644 --- a/src/gui_2.py +++ b/src/gui_2.py @@ -1197,71 +1197,99 @@ class App: imgui.end_popup() def _render_persona_editor_modal(self) -> None: - if not self.show_persona_editor_modal: - return - imgui.set_next_window_size(imgui.ImVec2(400, 350), imgui.Cond_.first_use_ever) - expanded, _ = imgui.begin("Persona Editor", self.show_persona_editor_modal) - if not expanded: - imgui.end() - return - try: - imgui.text("Name:") - imgui.same_line() - imgui.push_item_width(200) - _, self._editing_persona_name = imgui.input_text("##pname", self._editing_persona_name, 128) - imgui.pop_item_width() - imgui.text("Provider:") - imgui.same_line() - providers = ["gemini", "anthropic", "deepseek"] - p_idx = providers.index(self._editing_persona_provider) + 1 if self._editing_persona_provider in providers else 0 - imgui.push_item_width(120) - _, p_idx = imgui.combo("##pprov", p_idx, ["None"] + providers) - self._editing_persona_provider = providers[p_idx - 1] if p_idx > 0 else "" - imgui.pop_item_width() - imgui.text("Model:") - all_models = ["gemini-2.5-flash", "gemini-3.1-pro-preview", "claude-3-5-sonnet", "deepseek-v3"] - m_idx = all_models.index(self._editing_persona_model) + 1 if self._editing_persona_model in all_models else 0 - imgui.push_item_width(150) - _, m_idx = imgui.combo("##pmodel", m_idx, ["None"] + all_models) - self._editing_persona_model = all_models[m_idx - 1] if m_idx > 0 else "" - imgui.pop_item_width() - imgui.text("Temp:") - imgui.same_line() - _, self._editing_persona_temperature = imgui.slider_float("##ptemp", self._editing_persona_temperature, 0.0, 2.0) - imgui.text("MaxTok:") - imgui.same_line() - _, self._editing_persona_max_tokens = imgui.input_int("##pmaxt", self._editing_persona_max_tokens) - imgui.text("Prompt:") - _, self._editing_persona_system_prompt = imgui.input_text_multiline("##pprompt", self._editing_persona_system_prompt, imgui.ImVec2(350, 50)) - if imgui.button("Save##p", imgui.ImVec2(80, 0)): - if self._editing_persona_name.strip(): - try: - persona = models.Persona( - id=self._editing_persona_name.strip(), - name=self._editing_persona_name.strip(), - description=self._editing_persona_description, - provider=self._editing_persona_provider, - model=self._editing_persona_model, - system_prompt=self._editing_persona_system_prompt, - temperature=self._editing_persona_temperature, - max_tokens=self._editing_persona_max_tokens, - tool_preset_id=None, - bias_profile_id=None, - preferred_models=[], - tier_assignments={} - ) - self.controller._cb_save_persona(persona, "project") - self.ai_status = f"Saved: {persona.id}" - self.show_persona_editor_modal = False - except Exception as e: - self.ai_status = f"Error: {e}" - else: - self.ai_status = "Name required" - imgui.same_line() - if imgui.button("Cancel##p", imgui.ImVec2(80, 0)): - self.show_persona_editor_modal = False - finally: - imgui.end() + if not self.show_persona_editor_modal: return + imgui.open_popup("Persona Editor") + opened, self.show_persona_editor_modal = imgui.begin_popup_modal("Persona Editor", self.show_persona_editor_modal) + if opened: + try: + imgui.text("Name:") + imgui.same_line() + imgui.push_item_width(200) + _, self._editing_persona_name = imgui.input_text("##pname", self._editing_persona_name, 128) + imgui.pop_item_width() + imgui.text("Provider:") + imgui.same_line() + providers = ["gemini", "anthropic", "deepseek"] + p_idx = providers.index(self._editing_persona_provider) + 1 if self._editing_persona_provider in providers else 0 + imgui.push_item_width(120) + _, p_idx = imgui.combo("##pprov", p_idx, ["None"] + providers) + self._editing_persona_provider = providers[p_idx - 1] if p_idx > 0 else "" + imgui.pop_item_width() + imgui.text("Model:") + all_models = ["gemini-2.5-flash", "gemini-3.1-pro-preview", "claude-3-5-sonnet", "deepseek-v3"] + m_idx = all_models.index(self._editing_persona_model) + 1 if self._editing_persona_model in all_models else 0 + imgui.push_item_width(150) + _, m_idx = imgui.combo("##pmodel", m_idx, ["None"] + all_models) + self._editing_persona_model = all_models[m_idx - 1] if m_idx > 0 else "" + imgui.pop_item_width() + imgui.text("Temp:") + imgui.same_line() + _, self._editing_persona_temperature = imgui.slider_float("##ptemp", self._editing_persona_temperature, 0.0, 2.0) + imgui.text("MaxTok:") + imgui.same_line() + _, self._editing_persona_max_tokens = imgui.input_int("##pmaxt", self._editing_persona_max_tokens) + + # Tool Preset + imgui.text("Tool Preset:") + imgui.same_line() + preset_names = ["None"] + sorted(self.controller.tool_presets.keys()) + t_idx = preset_names.index(self._editing_persona_tool_preset_id) if hasattr(self, '_editing_persona_tool_preset_id') and self._editing_persona_tool_preset_id in preset_names else 0 + imgui.push_item_width(150) + _, t_idx = imgui.combo("##ptoolpreset", t_idx, preset_names) + self._editing_persona_tool_preset_id = preset_names[t_idx] if t_idx > 0 else None + imgui.pop_item_width() + + # Bias Profile + imgui.text("Bias Profile:") + imgui.same_line() + bias_names = ["None"] + sorted(self.controller.bias_profiles.keys()) + b_idx = bias_names.index(self._editing_persona_bias_profile_id) if hasattr(self, '_editing_persona_bias_profile_id') and self._editing_persona_bias_profile_id in bias_names else 0 + imgui.push_item_width(150) + _, b_idx = imgui.combo("##pbiasprofile", b_idx, bias_names) + self._editing_persona_bias_profile_id = bias_names[b_idx] if b_idx > 0 else None + imgui.pop_item_width() + + imgui.text("Pref Models (JSON):") + _, self._editing_persona_preferred_models = imgui.input_text("##pprefmodels", self._editing_persona_preferred_models, 256) + + imgui.text("Prompt:") + _, self._editing_persona_system_prompt = imgui.input_text_multiline("##pprompt", self._editing_persona_system_prompt, imgui.ImVec2(350, 50)) + if imgui.button("Save##p", imgui.ImVec2(80, 0)): + if self._editing_persona_name.strip(): + try: + import json + pref_models = [] + try: + pref_models = json.loads(self._editing_persona_preferred_models) + if not isinstance(pref_models, list): + pref_models = [] + except: + pass + persona = models.Persona( + name=self._editing_persona_name.strip(), + provider=self._editing_persona_provider or None, + model=self._editing_persona_model or None, + system_prompt=self._editing_persona_system_prompt, + temperature=self._editing_persona_temperature, + max_output_tokens=self._editing_persona_max_tokens, + tool_preset=getattr(self, '_editing_persona_tool_preset_id', None), + bias_profile=getattr(self, '_editing_persona_bias_profile_id', None), + preferred_models=pref_models, + ) + self.controller._cb_save_persona(persona, "project") + self.ai_status = f"Saved: {persona.name}" + self.show_persona_editor_modal = False + imgui.close_current_popup() + except Exception as e: + self.ai_status = f"Error: {e}" + else: + self.ai_status = "Name required" + imgui.same_line() + if imgui.button("Cancel##p", imgui.ImVec2(80, 0)): + self.show_persona_editor_modal = False + imgui.close_current_popup() + finally: + imgui.end_popup() def _render_projects_panel(self) -> None: