chore(conductor): Mark track 'Saved Tool Presets' as complete
This commit is contained in:
196
src/gui_2.py
196
src/gui_2.py
@@ -6,6 +6,7 @@ import math
|
||||
import json
|
||||
import sys
|
||||
import os
|
||||
import copy
|
||||
from pathlib import Path
|
||||
from tkinter import filedialog, Tk
|
||||
from typing import Optional, Any
|
||||
@@ -96,6 +97,12 @@ class App:
|
||||
self.show_windows.setdefault("Diagnostics", False)
|
||||
self.controller.start_services(self)
|
||||
self.show_preset_manager_modal = False
|
||||
self.show_tool_preset_manager_modal = False
|
||||
self.ui_active_tool_preset = ""
|
||||
self._editing_tool_preset_name = ''
|
||||
self._editing_tool_preset_categories = {}
|
||||
self._editing_tool_preset_scope = 'project'
|
||||
self._selected_tool_preset_idx = -1
|
||||
self._editing_preset_name = ""
|
||||
self._editing_preset_content = ""
|
||||
self._editing_preset_temperature = 0.0
|
||||
@@ -354,6 +361,7 @@ class App:
|
||||
self._render_patch_modal()
|
||||
self._render_save_preset_modal()
|
||||
self._render_preset_manager_modal()
|
||||
self._render_tool_preset_manager_modal()
|
||||
# Auto-save (every 60s)
|
||||
now = time.time()
|
||||
if now - self._last_autosave >= self._autosave_interval:
|
||||
@@ -422,6 +430,7 @@ class App:
|
||||
self._render_provider_panel()
|
||||
if imgui.collapsing_header("System Prompts"):
|
||||
self._render_system_prompts_panel()
|
||||
self._render_agent_tools_panel()
|
||||
self._render_cache_panel()
|
||||
|
||||
imgui.end()
|
||||
@@ -976,6 +985,118 @@ class App:
|
||||
finally:
|
||||
imgui.end_popup()
|
||||
|
||||
def _render_tool_preset_manager_modal(self) -> None:
|
||||
if not self.show_tool_preset_manager_modal: return
|
||||
imgui.open_popup("Tool Preset Manager")
|
||||
opened, self.show_tool_preset_manager_modal = imgui.begin_popup_modal("Tool Preset Manager", self.show_tool_preset_manager_modal)
|
||||
if opened:
|
||||
try:
|
||||
avail = imgui.get_content_region_avail()
|
||||
# Left Column: Listbox
|
||||
imgui.begin_child("tool_preset_list_area", imgui.ImVec2(250, avail.y), True)
|
||||
try:
|
||||
if imgui.button("New Tool Preset", imgui.ImVec2(-1, 0)):
|
||||
self._editing_tool_preset_name = ""
|
||||
self._editing_tool_preset_categories = {}
|
||||
self._editing_tool_preset_scope = "project"
|
||||
self._selected_tool_preset_idx = -1
|
||||
if imgui.is_item_hovered():
|
||||
imgui.set_tooltip("Create a new tool preset configuration.")
|
||||
|
||||
imgui.separator()
|
||||
preset_names = sorted(self.controller.tool_presets.keys())
|
||||
for i, name in enumerate(preset_names):
|
||||
is_selected = (self._selected_tool_preset_idx == i)
|
||||
if imgui.selectable(name, is_selected)[0]:
|
||||
self._selected_tool_preset_idx = i
|
||||
self._editing_tool_preset_name = name
|
||||
preset = self.controller.tool_presets[name]
|
||||
self._editing_tool_preset_categories = copy.deepcopy(preset.categories)
|
||||
finally:
|
||||
imgui.end_child()
|
||||
|
||||
imgui.same_line()
|
||||
|
||||
# Right Column: Edit Area
|
||||
imgui.begin_child("tool_preset_edit_area", imgui.ImVec2(0, avail.y), False)
|
||||
try:
|
||||
p_name = self._editing_tool_preset_name or "(New Tool Preset)"
|
||||
imgui.text_colored(C_IN, f"Editing Tool Preset: {p_name}")
|
||||
imgui.separator()
|
||||
imgui.dummy(imgui.ImVec2(0, 8))
|
||||
|
||||
imgui.text("Name:")
|
||||
_, self._editing_tool_preset_name = imgui.input_text("##edit_tp_name", self._editing_tool_preset_name)
|
||||
imgui.dummy(imgui.ImVec2(0, 8))
|
||||
|
||||
imgui.text("Scope:")
|
||||
if imgui.radio_button("Global", self._editing_tool_preset_scope == "global"):
|
||||
self._editing_tool_preset_scope = "global"
|
||||
imgui.same_line()
|
||||
if imgui.radio_button("Project", self._editing_tool_preset_scope == "project"):
|
||||
self._editing_tool_preset_scope = "project"
|
||||
imgui.dummy(imgui.ImVec2(0, 8))
|
||||
|
||||
imgui.text("Categories & Tools:")
|
||||
imgui.begin_child("tp_categories_scroll", imgui.ImVec2(0, -40), True)
|
||||
try:
|
||||
for cat_name, tools in self._editing_tool_preset_categories.items():
|
||||
if imgui.tree_node(cat_name):
|
||||
for tool_name, config in tools.items():
|
||||
# config can be a string ("auto", "ask") or a dict {"mode": "auto"}
|
||||
if isinstance(config, dict):
|
||||
mode = config.get("mode", "auto")
|
||||
else:
|
||||
mode = str(config)
|
||||
|
||||
if imgui.radio_button(f"Auto##{cat_name}_{tool_name}", mode == "auto"):
|
||||
if isinstance(config, dict): config["mode"] = "auto"
|
||||
else: tools[tool_name] = "auto"
|
||||
imgui.same_line()
|
||||
if imgui.radio_button(f"Ask##{cat_name}_{tool_name}", mode == "ask"):
|
||||
if isinstance(config, dict): config["mode"] = "ask"
|
||||
else: tools[tool_name] = "ask"
|
||||
imgui.same_line()
|
||||
imgui.text(tool_name)
|
||||
imgui.tree_pop()
|
||||
finally:
|
||||
imgui.end_child()
|
||||
|
||||
imgui.dummy(imgui.ImVec2(0, 8))
|
||||
if imgui.button("Save", imgui.ImVec2(100, 0)):
|
||||
if self._editing_tool_preset_name.strip():
|
||||
self.controller._cb_save_tool_preset(
|
||||
self._editing_tool_preset_name.strip(),
|
||||
self._editing_tool_preset_categories,
|
||||
self._editing_tool_preset_scope
|
||||
)
|
||||
self.ai_status = f"Tool preset '{self._editing_tool_preset_name}' saved"
|
||||
if imgui.is_item_hovered():
|
||||
imgui.set_tooltip("Save the current tool preset configuration.")
|
||||
|
||||
imgui.same_line()
|
||||
if imgui.button("Delete", imgui.ImVec2(100, 0)):
|
||||
if self._editing_tool_preset_name.strip():
|
||||
self.controller._cb_delete_tool_preset(
|
||||
self._editing_tool_preset_name.strip(),
|
||||
self._editing_tool_preset_scope
|
||||
)
|
||||
self.ai_status = f"Tool preset '{self._editing_tool_preset_name}' deleted"
|
||||
self._editing_tool_preset_name = ""
|
||||
self._editing_tool_preset_categories = {}
|
||||
self._selected_tool_preset_idx = -1
|
||||
if imgui.is_item_hovered():
|
||||
imgui.set_tooltip("Delete this tool preset permanently.")
|
||||
|
||||
imgui.same_line()
|
||||
if imgui.button("Close", imgui.ImVec2(100, 0)):
|
||||
self.show_tool_preset_manager_modal = False
|
||||
imgui.close_current_popup()
|
||||
finally:
|
||||
imgui.end_child()
|
||||
finally:
|
||||
imgui.end_popup()
|
||||
|
||||
def _render_projects_panel(self) -> None:
|
||||
if self.perf_profiling_enabled: self.perf_monitor.start_component("_render_projects_panel")
|
||||
proj_name = self.project.get("project", {}).get("name", Path(self.active_project_path).stem)
|
||||
@@ -1058,12 +1179,6 @@ class App:
|
||||
ch, self.ui_summary_only = imgui.checkbox("Summary Only (send file structure, not full content)", self.ui_summary_only)
|
||||
ch, self.ui_auto_scroll_comms = imgui.checkbox("Auto-scroll Comms History", self.ui_auto_scroll_comms)
|
||||
ch, self.ui_auto_scroll_tool_calls = imgui.checkbox("Auto-scroll Tool History", self.ui_auto_scroll_tool_calls)
|
||||
if imgui.collapsing_header("Agent Tools"):
|
||||
for t_name in models.AGENT_TOOL_NAMES:
|
||||
val = self.ui_agent_tools.get(t_name, True)
|
||||
ch, val = imgui.checkbox(f"Enable {t_name}", val)
|
||||
if ch:
|
||||
self.ui_agent_tools[t_name] = val
|
||||
if self.perf_profiling_enabled: self.perf_monitor.end_component("_render_projects_panel")
|
||||
|
||||
def _render_track_proposal_modal(self) -> None:
|
||||
@@ -2716,7 +2831,7 @@ def hello():
|
||||
imgui.push_id(f"tier_cfg_{tier}")
|
||||
|
||||
# Provider selection
|
||||
imgui.push_item_width(100)
|
||||
imgui.push_item_width(80)
|
||||
if imgui.begin_combo("##prov", current_provider):
|
||||
for p in PROVIDERS:
|
||||
if imgui.selectable(p, p == current_provider)[0]:
|
||||
@@ -2731,7 +2846,7 @@ def hello():
|
||||
imgui.same_line()
|
||||
|
||||
# Model selection
|
||||
imgui.push_item_width(-1)
|
||||
imgui.push_item_width(150)
|
||||
models_list = self.controller.all_available_models.get(current_provider, [])
|
||||
if imgui.begin_combo("##model", current_model):
|
||||
for model in models_list:
|
||||
@@ -2739,6 +2854,19 @@ def hello():
|
||||
self.mma_tier_usage[tier]["model"] = model
|
||||
imgui.end_combo()
|
||||
imgui.pop_item_width()
|
||||
|
||||
imgui.same_line()
|
||||
|
||||
# Tool Preset selection
|
||||
imgui.push_item_width(-1)
|
||||
current_preset = self.mma_tier_usage[tier].get("tool_preset") or "None"
|
||||
preset_names = ["None"] + sorted(self.controller.tool_presets.keys())
|
||||
if imgui.begin_combo("##preset", current_preset):
|
||||
for preset_name in preset_names:
|
||||
if imgui.selectable(preset_name, current_preset == preset_name)[0]:
|
||||
self.mma_tier_usage[tier]["tool_preset"] = None if preset_name == "None" else preset_name
|
||||
imgui.end_combo()
|
||||
imgui.pop_item_width()
|
||||
|
||||
imgui.pop_id()
|
||||
imgui.separator()
|
||||
@@ -3042,6 +3170,58 @@ def hello():
|
||||
self.show_preset_manager_modal = True
|
||||
imgui.set_item_tooltip("Open preset management modal")
|
||||
ch, self.ui_project_system_prompt = imgui.input_text_multiline("##psp", self.ui_project_system_prompt, imgui.ImVec2(-1, 100))
|
||||
def _render_agent_tools_panel(self) -> None:
|
||||
imgui.text_colored(C_LBL, 'Active Tool Preset')
|
||||
presets = self.controller.tool_presets
|
||||
preset_names = [""] + sorted(list(presets.keys()))
|
||||
|
||||
# Gracefully handle None or missing preset
|
||||
active = getattr(self, "ui_active_tool_preset", "")
|
||||
if active is None: active = ""
|
||||
try:
|
||||
idx = preset_names.index(active)
|
||||
except ValueError:
|
||||
idx = 0
|
||||
|
||||
ch, new_idx = imgui.combo("##tool_preset_select", idx, preset_names)
|
||||
if ch:
|
||||
self.ui_active_tool_preset = preset_names[new_idx]
|
||||
|
||||
imgui.same_line()
|
||||
if imgui.button("Manage Presets##tools"):
|
||||
self.show_tool_preset_manager_modal = True
|
||||
if imgui.is_item_hovered():
|
||||
imgui.set_tooltip("Configure tool availability and default modes.")
|
||||
|
||||
imgui.dummy(imgui.ImVec2(0, 8))
|
||||
active_name = self.ui_active_tool_preset
|
||||
if active_name and active_name in presets:
|
||||
preset = presets[active_name]
|
||||
for cat_name, tools in preset.categories.items():
|
||||
if imgui.tree_node(cat_name):
|
||||
for t_name, t_cfg in tools.items():
|
||||
imgui.text(t_name)
|
||||
imgui.same_line(150)
|
||||
|
||||
# Determine current mode
|
||||
if isinstance(t_cfg, dict):
|
||||
mode = t_cfg.get("mode", "auto")
|
||||
else:
|
||||
mode = str(t_cfg)
|
||||
|
||||
if imgui.radio_button(f"Auto##{cat_name}_{t_name}", mode == "auto"):
|
||||
if isinstance(t_cfg, dict):
|
||||
t_cfg["mode"] = "auto"
|
||||
else:
|
||||
preset.categories[cat_name][t_name] = "auto"
|
||||
imgui.same_line()
|
||||
if imgui.radio_button(f"Ask##{cat_name}_{t_name}", mode == "ask"):
|
||||
if isinstance(t_cfg, dict):
|
||||
t_cfg["mode"] = "ask"
|
||||
else:
|
||||
preset.categories[cat_name][t_name] = "ask"
|
||||
imgui.tree_pop()
|
||||
|
||||
def _render_theme_panel(self) -> None:
|
||||
if self.perf_profiling_enabled: self.perf_monitor.start_component("_render_theme_panel")
|
||||
exp, opened = imgui.begin("Theme", self.show_windows["Theme"])
|
||||
|
||||
Reference in New Issue
Block a user