62af5649fecd8d58a3f409db2cdb42196d489fb1
Re-authors soul-webfix-20260711.patch in El (the patch is a diff against generated C at month-old offsets, so nothing was applied as a patch). Its last two hunks — an unrelated /api/safety-contact implementation — were deliberately not ported; that route already exists and is safety-critical. Activation restores existing design, it does not invent a mechanism: commit8eea1d9(2026-06-09, Tim-approved) made native web_search built-in with no user-facing toggle, and tests/test_agentic_tools.el section 2 still asserts agentic_tools_all() contains it — an assertion main currently fails. The call site was lost when agentic_tools_all() (connector tools, PR #19) replaced agentic_tools_with_web(). Attaching in agentic_tools_all() covers handle_chat_agentic, handle_dharma_room_turn_agentic and agentic_resume. pause_turn handling is included and was genuinely missing: the shipped binary has zero occurrences of it. Without it a paused server-side search returns only the text written so far and the loop treats it as final — a silently truncated answer. final_text now accumulates across resume cycles rather than overwriting (overwriting would discard everything written before the pause). Default tool version is web_search_20250305, NOT the newer _20260209, and that is a measured choice: _20260209's dynamic filtering uses server-side programmatic tool calling, which the API refuses to combine with ADR 0005's stopgap — HTTP 400 invalid_request_error tool_choice.disable_parallel_tool_use: true cannot be used with programmatic tool calling Dropping the stopgap would resurrect neuron#78 bug b (killed runs 3/3 in ADR 0005's own A/B). The basic variant is compatible with the stopgap and returns real results, so neither feature is dropped. Version lives in state key web_search_tool_version; flipping it once the stopgap retires is a config write, no recompile. The fallback also fires on "programmatic tool calling" so a premature flip self-heals loudly instead of dying. Also fixes a real bug this port exposed: json_get is a first-match scanner and a cited text block serialises citations FIRST, so json_get(block,"type") returned the nested citation's type and every citation-bearing block — the ones carrying the searched facts — was silently dropped from the reply. Reply length on the same question: 79 -> 360 chars. Other loop changes: server_tool_use accounting into tools_used, iteration cap 8->12 for pause/resume cycles, max_tokens 4096->16384, container-id carry-forward, API error head logged instead of swallowed, tools_used gated on is_tool_turn so a truncated tool block is not reported as work done. dist/soul.c is deliberately NOT regenerated — the local elc predates Will's last regen (e610a41) and regenerating with an older compiler risks unrelated codegen drift. Source only; regen is Will's. E2E-VERIFIED on a sandbox soul (scratch HOME/engram, dead axon+ISE, explicit NEURON_PORT): live Bentonville weather with tools_used ["web_search"]; the 27-route contract gate PASSes; the parallel-tool stopgap still completes a 3-file mission with no 400; a 3-search 3,486-char answer kept its end sentinel. Honest gap: pause_turn is compiled in but not exercised by a live pause (max_uses:5 caps the server loop below the pause threshold). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Description
Neuron - the canonical CGI substrate. Real soul.el lives here.
34 MiB
Languages
Emacs Lisp
80.2%
Shell
13.4%
Python
4.2%
HTML
1%
Go Template
0.7%
Other
0.5%