Skip to content

feat(runtime): exa_search FunctionTool — make the tool Flash hallucinates real#145

Merged
spashii merged 2 commits into
mainfrom
feat/exa-search-runtime-tool
Jul 14, 2026
Merged

feat(runtime): exa_search FunctionTool — make the tool Flash hallucinates real#145
spashii merged 2 commits into
mainfrom
feat/exa-search-runtime-tool

Conversation

@spashii

@spashii spashii commented Jul 14, 2026

Copy link
Copy Markdown
Member

The finding

30 days of audit logs: Exa's API never failed once (8/8 calls healthy). Every "exa breaks" incident was agent-side, in two modes:

  1. Session-killing tool hallucination (3 crashes). The skill catalog advertises exa-search in every system prompt, but no exa_search tool was registered — Flash pattern-matched the name and emitted exa_search(...) calls the ADK runner had no handler for → unhandled exception → whole session dies with exit 1, no reply to the user (Jul 9 ×2, Jul 13 ×1 — the last one misdiagnosed itself to Cesare as a "document retrieval parsing error"). Sam journaled the root cause on Jul 9 and re-hit it Jul 13: prose can't patch a model prior.
  2. jq-eaten results (2 occurrences). The skill's only curl template piped to jq, which isn't installed in the container — searches succeeded, got billed, output vanished.

The fix

  • exa_search FunctionTool in adk_runner.py with the exact name + query arg Flash already tries to call. httpx (existing dep), results formatted in Python (no shell parsing), Exa error tags surfaced as strings (429/400/402 branchable), empty results phrased as guidance not failure, per-query cost reported. Registered in worker_tools (→ main, worker, pro_executor) and the parallel_workers fanout; mentor stays read-only.
  • Skill rewritten to what prose is for: when/when-not (native tool first), cost discipline, and a jq-banned curl fallback for advanced params — corrected against the 2026-07 Exa API docs (current type enum, conditional response fields, category conflicts).

Verification

  • 5 new tests (signature pin, missing-key error, never-raises-on-connect-failure, FunctionTool wrap, both registration sites); full suite 310 passed; ruff + ruff-S clean.
  • Live-verified against the real API (~$0.02): happy path with cost line, include_domains, and invalid key → error: Exa HTTP 401 [INVALID_API_KEY] as a string.
  • Post-merge check (1 week): the crash signature (exa_search call → session errored) should be extinct in tool_calls/*.jsonl, and no bash entry should contain api.exa.ai … | jq.

Diagnosis produced by a 4-agent research workflow during the 2026-07-14 maintenance follow-up; full write-up available on request.

Tier 3 (runtime). Note: CI will stay red until #143 (trivy/apt-cache fix) merges — same as the rest of the queue.

🤖 Generated with Claude Code

sam-dembrane and others added 2 commits July 14, 2026 11:22
…ates real

30 days of audit logs show Exa itself never failed (8/8 API calls
healthy); every 'exa breaks' incident was agent-side:

1. The skill catalog advertises exa-search in every system prompt but no
   exa_search tool existed — Flash pattern-matched the name to a native
   tool and emitted calls the runner had no handler for, killing the
   whole session with exit 1 (3 crashes: 2026-07-09 x2, 2026-07-13; the
   last one misdiagnosed itself to the user). Sam journaled the root
   cause on 07-09 and re-hit it on 07-13 — prose can't patch a model
   prior, so the tool now exists with the exact name and query arg Flash
   already tries to call.
2. The skill's only curl template piped to jq, which isn't in the
   container — searches succeeded, got billed, and the output was eaten
   (2 occurrences). The tool formats results in Python; the rewritten
   skill bans jq by name and documents the python3 fallback.
3. Skill body drifted from the current Exa API (stale type enum,
   response fields promised unconditionally) — corrected against the
   2026-07 docs.

Registered in worker_tools (main/worker/pro_executor) and the
parallel_workers fanout; mentor stays read-only. Live-verified against
the real API: happy path + include_domains + 401-as-string (~$0.02).

Diagnosis by a 4-agent research workflow, 2026-07-14 maintenance.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@spashii
spashii merged commit 58cdbfe into main Jul 14, 2026
2 checks passed
@spashii
spashii deleted the feat/exa-search-runtime-tool branch July 14, 2026 16:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant