Skip to content

Converge deployed agent state: gutter-strip fix, parallel-web 1.x migration, runtime fixes - #2

Merged
BrianLi009 merged 7 commits into
mainfrom
dev/brian/jsondecode-retry-fix
Jun 9, 2026
Merged

Converge deployed agent state: gutter-strip fix, parallel-web 1.x migration, runtime fixes#2
BrianLi009 merged 7 commits into
mainfrom
dev/brian/jsondecode-retry-fix

Conversation

@BrianLi009

Copy link
Copy Markdown

What

Merges the long-running deployed branch back to main. Production (Modal mounts the local working tree) has been running ahead of main since April; this PR makes main match what actually ships, plus one new fix.

New fix

  • write_file strips pasted read-tool line-number gutters (tools/file_operations.py, tools/file_tools.py). read_file returns LINE_NUM|CONTENT; models occasionally copy blocks from a read result into write_file verbatim, persisting the NNN| gutter into the file — this corrupted the <style> block + visible text of three shipped report HTMLs. The patch path already strips this format; write_file did not. The stripper fires only on the unmistakable signature (>=4 prefixed lines, >=50% of non-empty lines, >=90% sequentially increasing), so markdown tables / shell pipes / id|value data pass through untouched. When it fires it logs and returns a corrective notice to the model.

Previously deployed-but-uncommitted

  • parallel-web 1.x API migration (tools/web_tools.py): search/extract moved off .beta, basic/advanced modes, no max_results kwarg, full_content by default. Running in deployment since the 1.0 breakage.
  • fix(agent): runtime fixes for single-agent conference report pipeline (Apr 11)
  • fix(agent): retry on JSONDecodeError instead of aborting (Jun 5)

Merged in

  • origin/main (Gurneesh's granular API timeout, user notes tools, sandbox improvements) — one trivial formatting conflict in run_agent.py, resolved keeping identical semantics.

Testing

  • py_compile on all touched files
  • Gutter stripper verified against the three real corrupted production artifacts (byte-identical to manual repair) and against false-positive cases (markdown tables, shell pipes, pipe-delimited data — all untouched)

🤖 Generated with Claude Code

BrianLi009 and others added 7 commits April 11, 2026 02:19
Cap invalid-JSON retries at 6 total and inject execute_code fallback
when write_file fails on large HTML content. Add thread-local
set_sandbox_env/get_sandbox_env helpers required by
src/api/conference_report.py so per-request Modal handlers can
override child subprocess env without polluting process globals.
Allow execute_code in subagents (same large-file rationale) and add
a 5-minute wall-clock timeout per subagent task via ThreadPoolExecutor.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
json.JSONDecodeError subclasses ValueError, so an unparseable provider
response (truncated body, gateway HTML, or an SSE mismatch on a large/slow
request) was bucketed as a non-retryable "local validation error" and
aborted on attempt 1. Exclude JSONDecodeError from that bucket so transient
parse failures retry with backoff like other transient API errors.

Surfaced by a ~221K-token report-generation call that returned an
unparseable body and hard-failed instead of retrying.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…basic/advanced modes)

parallel-web 1.0 moved search/extract from the .beta namespace to the
top-level client, replaced fast/one-shot/agentic modes with basic/advanced,
dropped max_results (results now sliced client-side), and returns
full_content by default. This has been running in deployment (Modal mounts
the working tree) since the 1.0 breakage; committing so main matches what
ships.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
read_file returns 'LINE_NUM|CONTENT' lines; models sometimes copy blocks
from a read result into write_file content verbatim, persisting the gutter
into the file — it corrupts <style> blocks and renders as visible junk
(shipped broken report HTML to users three times). The patch path already
strips this format (patch_parser._apply_update); write_file did not.

strip_pasted_line_numbers() fires only on the unmistakable signature:
>=4 prefixed lines covering >=50% of non-empty lines with >=90%
sequentially increasing numbers — markdown tables, shell pipes, and
'id|value' data files pass through untouched. write_file_tool logs a
warning and returns a corrective notice to the model when it fires.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… fixes

The parallel/tavily failover dispatched URLs before the website-policy
check, which only lived inside the Firecrawl fall-through loop — blocked
hosts sailed straight to the new backends, and redirected final URLs were
only re-checked on the Firecrawl path. Hoist the policy check into the
pre-dispatch filter (alongside SSRF) and re-check final URLs uniformly on
every backend's results. Gate the Firecrawl fall-through on client
constructibility instead of env sniffing (equivalent in prod; the client
raises when unconfigured).

Also: add force=True to the invalid-JSON retry-cap error vprint, and
update test_blocked_tools_constant for the deliberate execute_code
allowance in subagents (b0bf702) with an explicit companion assertion.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The cache used a constant '__default__' key and the disabled-policy fast
path returned early without checking key or TTL — after HERMES_HOME
changed at runtime, a stale 'disabled' entry from the previous home
failed-open the new home's blocklist (and vice versa could serve stale
blocks). Key the cache on the resolved default config path and make the
fast path require key + freshness. Surfaced by CI once web_extract began
calling check_website_access pre-dispatch.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@BrianLi009
BrianLi009 merged commit 51b4c99 into main Jun 9, 2026
2 of 3 checks passed
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