ai botched the agent personal track. needs a redo by gemini 3.1

This commit is contained in:
2026-03-10 12:30:09 -04:00
parent 478d91a6e1
commit e3d5e0ed2e
5 changed files with 278 additions and 9 deletions

View File

@@ -716,8 +716,21 @@ class AppController:
payload = task.get("payload", {})
ticket_id = payload.get("ticket_id")
start_time = payload.get("timestamp")
persona_id = payload.get("persona_id")
model = payload.get("model")
if ticket_id and start_time:
self._ticket_start_times[ticket_id] = start_time
if ticket_id and (persona_id or model):
stream_id = f"Tier 3 (Worker): {ticket_id}"
meta_info = f"[STARTED] Ticket: {ticket_id}"
if model:
meta_info += f" | Model: {model}"
if persona_id:
meta_info += f" | Persona: {persona_id}"
meta_info += "\n" + "="*50 + "\n"
if stream_id not in self.mma_streams:
self.mma_streams[stream_id] = ""
self.mma_streams[stream_id] = meta_info + self.mma_streams[stream_id]
elif action == "ticket_completed":
payload = task.get("payload", {})
ticket_id = payload.get("ticket_id")
@@ -1885,6 +1898,14 @@ class AppController:
self.tool_preset_manager.delete_bias_profile(name, scope)
self.bias_profiles = self.tool_preset_manager.load_all_bias_profiles()
def _cb_save_persona(self, persona: models.Persona, scope: str = "project") -> None:
self.persona_manager.save_persona(persona, scope)
self.personas = self.persona_manager.load_all_personas()
def _cb_delete_persona(self, persona_id: str, scope: str = "project") -> None:
self.persona_manager.delete_persona(persona_id, scope)
self.personas = self.persona_manager.load_all_personas()
def _cb_load_track(self, track_id: str) -> None:
state = project_manager.load_track_state(track_id, self.ui_files_base_dir)
if state:

View File

@@ -98,8 +98,24 @@ class App:
self.controller.start_services(self)
self.show_preset_manager_modal = False
self.show_tool_preset_manager_modal = False
self.show_persona_editor_modal = False
self.ui_active_tool_preset = ""
self.ui_active_bias_profile = ""
self.ui_active_persona = ""
self._editing_persona_name = ""
self._editing_persona_description = ""
self._editing_persona_provider = ""
self._editing_persona_model = ""
self._editing_persona_system_prompt = ""
self._editing_persona_temperature = 0.7
self._editing_persona_max_tokens = 4096
self._editing_persona_tool_preset_id = ""
self._editing_persona_bias_profile_id = ""
self._editing_persona_preferred_models = "[]"
self._editing_persona_tier_assignments = "{}"
self._editing_persona_is_new = True
self._persona_editor_opened = False
self._personas_list: dict[str, dict] = {}
self._editing_bias_profile_name = ""
self._editing_bias_profile_tool_weights = "" # JSON
self._editing_bias_profile_cat_mults = "" # JSON
@@ -371,6 +387,7 @@ class App:
self._render_save_preset_modal()
self._render_preset_manager_modal()
self._render_tool_preset_manager_modal()
self._render_persona_editor_modal()
# Auto-save (every 60s)
now = time.time()
if now - self._last_autosave >= self._autosave_interval:
@@ -1179,6 +1196,74 @@ class App:
finally:
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()
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)
@@ -1982,13 +2067,76 @@ def hello():
imgui.text("Persona")
if not hasattr(self, 'ui_active_persona'):
self.ui_active_persona = ""
personas = getattr(self.controller, 'personas', {})
if imgui.begin_combo("##persona", self.ui_active_persona or "None"):
if imgui.selectable("None", not self.ui_active_persona)[0]:
self.ui_active_persona = ""
for pname in sorted(getattr(self.controller, 'personas', {}).keys()):
for pname in sorted(personas.keys()):
if imgui.selectable(pname, pname == self.ui_active_persona)[0]:
self.ui_active_persona = pname
if pname in personas:
persona = personas[pname]
self._editing_persona_name = persona.name
self._editing_persona_description = persona.description or ""
self._editing_persona_provider = persona.provider or ""
self._editing_persona_model = persona.model or ""
self._editing_persona_system_prompt = persona.system_prompt or ""
self._editing_persona_temperature = persona.temperature or 0.7
self._editing_persona_max_tokens = persona.max_tokens or 4096
self._editing_persona_tool_preset_id = persona.tool_preset_id or ""
self._editing_persona_bias_profile_id = persona.bias_profile_id or ""
import json
self._editing_persona_preferred_models = json.dumps(persona.preferred_models) if persona.preferred_models else "[]"
self._editing_persona_tier_assignments = json.dumps(persona.tier_assignments) if persona.tier_assignments else "{}"
self._editing_persona_is_new = False
if persona.provider and persona.provider in self.controller.PROVIDERS:
self.current_provider = persona.provider
if persona.model:
self.current_model = persona.model
if persona.temperature is not None:
ai_client.temperature = persona.temperature
if persona.max_tokens:
ai_client.max_output_tokens = persona.max_tokens
if persona.system_prompt:
ai_client.system_instruction = persona.system_prompt
if persona.tool_preset_id:
self.ui_active_tool_preset = persona.tool_preset_id
ai_client.set_tool_preset(persona.tool_preset_id)
if persona.bias_profile_id:
self.ui_active_bias_profile = persona.bias_profile_id
ai_client.set_bias_profile(persona.bias_profile_id)
imgui.end_combo()
imgui.same_line()
if imgui.button("Edit##persona"):
if self.ui_active_persona and self.ui_active_persona in personas:
persona = personas[self.ui_active_persona]
self._editing_persona_name = persona.name
self._editing_persona_description = persona.description or ""
self._editing_persona_provider = persona.provider or ""
self._editing_persona_model = persona.model or ""
self._editing_persona_system_prompt = persona.system_prompt or ""
self._editing_persona_temperature = persona.temperature or 0.7
self._editing_persona_max_tokens = persona.max_tokens or 4096
self._editing_persona_tool_preset_id = persona.tool_preset_id or ""
self._editing_persona_bias_profile_id = persona.bias_profile_id or ""
import json
self._editing_persona_preferred_models = json.dumps(persona.preferred_models) if persona.preferred_models else "[]"
self._editing_persona_tier_assignments = json.dumps(persona.tier_assignments) if persona.tier_assignments else "{}"
self._editing_persona_is_new = False
else:
self._editing_persona_name = ""
self._editing_persona_description = ""
self._editing_persona_provider = self.current_provider
self._editing_persona_model = self.current_model
self._editing_persona_system_prompt = ""
self._editing_persona_temperature = 0.7
self._editing_persona_max_tokens = 4096
self._editing_persona_tool_preset_id = ""
self._editing_persona_bias_profile_id = ""
self._editing_persona_preferred_models = "[]"
self._editing_persona_tier_assignments = "{}"
self._editing_persona_is_new = True
self.show_persona_editor_modal = True
if self.current_provider == "gemini_cli":
imgui.separator()
@@ -2972,6 +3120,20 @@ def hello():
imgui.end_combo()
imgui.pop_item_width()
imgui.same_line()
# Persona selection
imgui.push_item_width(150)
current_persona = self.mma_tier_usage[tier].get("persona") or "None"
personas = getattr(self.controller, 'personas', {})
persona_options = ["None"] + sorted(personas.keys())
if imgui.begin_combo("##persona", current_persona):
for persona_name in persona_options:
if imgui.selectable(persona_name, current_persona == persona_name)[0]:
self.mma_tier_usage[tier]["persona"] = None if persona_name == "None" else persona_name
imgui.end_combo()
imgui.pop_item_width()
imgui.pop_id()
imgui.separator()
self._render_ticket_queue()
@@ -3002,6 +3164,17 @@ def hello():
imgui.text(f"Target: {ticket.get('target_file', '')}")
deps = ticket.get('depends_on', [])
imgui.text(f"Depends on: {', '.join(deps)}")
personas = getattr(self.controller, 'personas', {})
current_persona = ticket.get('persona_id', '')
imgui.text("Persona Override:")
imgui.same_line()
persona_options = ["None"] + sorted(personas.keys())
current_idx = persona_options.index(current_persona) + 1 if current_persona in persona_options else 0
_, current_idx = imgui.combo(f"##ticket_persona_{ticket.get('id')}", current_idx, persona_options)
if current_idx > 0:
ticket['persona_id'] = None if persona_options[current_idx] == "None" else persona_options[current_idx]
else:
ticket['persona_id'] = ""
if imgui.button(f"Mark Complete##{self.ui_selected_ticket_id}"):
ticket['status'] = 'done'
self._push_mma_state_update()

View File

@@ -127,10 +127,10 @@ class ConductorEngine:
self.track = track
self.event_queue = event_queue
self.tier_usage = {
"Tier 1": {"input": 0, "output": 0, "model": "gemini-3.1-pro-preview", "tool_preset": None},
"Tier 2": {"input": 0, "output": 0, "model": "gemini-3-flash-preview", "tool_preset": None},
"Tier 3": {"input": 0, "output": 0, "model": "gemini-2.5-flash-lite", "tool_preset": None},
"Tier 4": {"input": 0, "output": 0, "model": "gemini-2.5-flash-lite", "tool_preset": None},
"Tier 1": {"input": 0, "output": 0, "model": "gemini-3.1-pro-preview", "tool_preset": None, "persona": None},
"Tier 2": {"input": 0, "output": 0, "model": "gemini-3-flash-preview", "tool_preset": None, "persona": None},
"Tier 3": {"input": 0, "output": 0, "model": "gemini-2.5-flash-lite", "tool_preset": None, "persona": None},
"Tier 4": {"input": 0, "output": 0, "model": "gemini-2.5-flash-lite", "tool_preset": None, "persona": None},
}
self.dag = TrackDAG(self.track.tickets)
self.engine = ExecutionEngine(self.dag, auto_queue=auto_queue)
@@ -311,7 +311,7 @@ class ConductorEngine:
model_name=model_name,
messages=[],
tool_preset=self.tier_usage["Tier 3"]["tool_preset"],
persona_id=ticket.persona_id
persona_id=ticket.persona_id or self.tier_usage["Tier 3"].get("persona")
)
context_files = ticket.context_requirements if ticket.context_requirements else None
@@ -328,7 +328,7 @@ class ConductorEngine:
with self._workers_lock:
self._active_workers[ticket.id] = spawned
ticket.status = "in_progress"
_queue_put(self.event_queue, "ticket_started", {"ticket_id": ticket.id, "timestamp": time.time()})
_queue_put(self.event_queue, "ticket_started", {"ticket_id": ticket.id, "timestamp": time.time(), "persona_id": context.persona_id, "model": model_name})
print(f"Executing ticket {ticket.id}: {ticket.description}")
self._push_state(active_tier=f"Tier 3 (Worker): {ticket.id}")