Tighten tool surface consistency

Four passes of audit-and-patch on the tool surface, condensed.

Tool API shape:
- Todo tools collapse to a single list-based form (one arg per tool,
  always a list, no dual-mode validator). Result-field names line up
  across the family — created_count / updated_count / marked_count /
  deleted_count, and _mark returns a single "marked" key plus the new
  status instead of marked_done / marked_pending.
- list_notes splits the overloaded total_count into filtered_count
  (matches) and total_count (grand total), matching list_todos. All
  three notes mutations now echo total_count and note_id.
- finish_scan drops the machine-code error strings; a single human
  "error" key carries the reason on every failure path.
- scope_rules delete echoes a message so the renderer's success
  branch has something to surface.

Failure-key unification: every tool now uses {"success": False,
"error": "..."} on failure paths. Touched thinking, web_search,
reporting, and finish. Trailing periods on error strings swept clean
across the whole tool tree.

Tool prompts (docstring re-imports vs main):
- create_vulnerability_report re-imports the CWE reference catalog,
  multi-part fix rules, fix_before/fix_after PR-suggestion mechanics,
  the COMMON MISTAKES list, the informational-vs-actionable
  distinction, and file-path examples.
- web_search re-imports concrete example queries.
- list_sitemap docstring fixed hasDescendants -> has_descendants
  (the camelCase reference never matched our snake_case schema).
- create_agent.skills description "Comma-separated" -> "List of".
- factory.py module docstring no longer claims there's no runtime
  skill-loading tool. agents_graph module docstring lists stop_agent.
- system_prompt nudges loading the matching skill before guessing
  payloads or syntax from memory.

TUI:
- proxy_renderer was reading stale field names from the pre-SDK
  schema (requests / total_count / statusCode / matches /
  showing_lines); now reads entries / page_info / status_code / hits
  / page+total_lines. Three proxy operations were rendering empty
  before this.
- Idle-pane placeholder text trimmed to "Loading...".

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
0xallam
2026-05-26 12:16:47 -07:00
parent 763df86f17
commit 054eedf53f
13 changed files with 224 additions and 96 deletions
+4 -4
View File
@@ -998,9 +998,7 @@ class StrixTUIApp(App): # type: ignore[misc]
self,
) -> tuple[Any, str | None]:
if not self.selected_agent_id:
return self._get_chat_placeholder_content(
"Select an agent from the tree to see its activity.", "placeholder-no-agent"
)
return self._get_chat_placeholder_content("Loading...", "placeholder-no-agent")
events = self._gather_agent_events(self.selected_agent_id)
@@ -1353,7 +1351,9 @@ class StrixTUIApp(App): # type: ignore[misc]
def _agent_vulnerability_count(self, agent_id: str) -> int:
return sum(
1 for vuln in self.report_state.vulnerability_reports if vuln.get("agent_id") == agent_id
1
for vuln in self.report_state.vulnerability_reports
if vuln.get("agent_id") == agent_id
)
def _gather_agent_events(self, agent_id: str) -> list[dict[str, Any]]: