|
subagents, secrets: an honest result contract, and two leaks closed
A pass over the sub-agent system, plus the two findings from the previous one. Leaks: - `redact_args` / `is_sensitive_key` (navi/tools/_internal/redact.py) mask credential-shaped keys at every log site that prints tool arguments — by key name, for all tools, so a future MCP tool is covered without declaring anything. ssh_exec passwords were sitting in the prod journal in plaintext. - `mcp_servers.d/*.json` are tracked in git and carried the scaffolding machine's absolute paths, so navi-3d/navi-web silently vanished from the toolset off that machine. They now hold project-relative paths, resolved in `McpClient.open_transport` — not at load time, because create_mcp_server round-trips every config file through save_mcp_servers. Sub-agent result contract: - `run_ephemeral` returns a `SubAgentOutcome` (text + status: ok, timeout, max_iterations, thinking_stall, user_stop, context_overflow) instead of `(text, bool)`. Every exit routes through `SubAgentRunner._finish`, so token accounting is never dropped and a partial run always carries a progress report — the stop-after-stream path used to return a bare string. - `spawn_agent` renders its header from the status. Before this, every short run reached the parent as "hit iteration limit", and the parent repeats that diagnosis to the user — a timeout was reported as an iteration limit. - `ContextTooLargeError` no longer kills a sub-agent: the parent compresses its own context, a sub-agent has no session to compress into, so it stops with `context_overflow` and hands back what it did rather than surfacing as "Sub-agent failed: …" with the whole run discarded. - The result is capped at 8000 chars (head and tail kept) so a long run cannot flood the parent's context, and tool arguments in the progress report go through `redact_args`. - The navi-3d calling convention left the runner for the server's own tool schemas — a generic runner should not know one MCP server's path shapes. - Validation moved inside spawn_agent's try: a bad argument is a clean ToolResult the model can read, not an exception in the parent's loop. Tests: 1636 passed, 1 skipped. New: SubAgentOutcome paths and headers, result truncation, context overflow, clean argument failures. |
|---|
|
|
| docs/agent.md |
|---|
| docs/mechanics.md |
|---|
| manuals/create_mcp_server.md |
|---|
| manuals/spawn_agent.md |
|---|
| mcp_servers.d/navi-3d.json |
|---|
| mcp_servers.d/navi-web.json |
|---|
| navi/api/routes/peer.py |
|---|
| navi/core/agent.py |
|---|
| navi/core/subagent_runner.py |
|---|
| navi/core/tool_executor.py |
|---|
| navi/mcp/client.py |
|---|
| navi/mcp/config.py |
|---|
| navi/profiles/developer/system_prompt.txt |
|---|
| navi/tools/_internal/logging_middleware.py |
|---|
| navi/tools/_internal/redact.py 0 → 100644 |
|---|
| navi/tools/create_mcp_server.py |
|---|
| navi/tools/spawn_agent.py |
|---|
| navi/tools/todo.py |
|---|
| tests/unit/core/test_agent.py |
|---|
| tests/unit/core/test_tool_executor.py |
|---|
| tests/unit/mcp/test_config_paths.py 0 → 100644 |
|---|
| tests/unit/test_peer_routes.py |
|---|
| tests/unit/tools/test_redact_args.py 0 → 100644 |
|---|
| tests/unit/tools/test_spawn_agent.py |
|---|