Skip to content

fix(claudecode): unwrap JSON envelope in agentic responses#218

Merged
kris-hansen merged 1 commit into
mainfrom
fix/claudecode-extract-result
Apr 26, 2026
Merged

fix(claudecode): unwrap JSON envelope in agentic responses#218
kris-hansen merged 1 commit into
mainfrom
fix/claudecode-extract-result

Conversation

@kris-hansen
Copy link
Copy Markdown
Owner

Summary

Agentic loops were exiting after a single iteration with reason "Agent signaled context exhaustion or documented remaining work" even when the agent had clearly stated next-iteration plans.

Root cause: SendPromptAgentic calls the Claude CLI with --output-format json but returned the entire envelope as the response. The exit-condition regex then matched on metadata, not agent prose:

  • (?i)context[_\s]*(limit|exhaust|full|window) matched \"contextWindow\":200000 in the envelope's usage object.

Reproduced with the user's jPOS analysis loop — the agent's iteration 2 reply ended with "Next iteration focus: ..." yet the loop exited. Confirmed by replaying the patterns over the literal stdout in .comanda/ANALYSIS_LOG.md.

A secondary consequence: configured step output files received the JSON blob instead of the agent's prose, making activity logs unreadable.

Fix

Add extractClaudeCodeResult(stdout string) string that JSON-decodes the envelope and returns just result. Pass-through cases (empty, non-JSON, malformed, empty result) return the input unchanged so:

  • SendPrompt/SendPromptWithFile (no --output-format json) are unaffected.
  • Future Claude CLI format changes degrade gracefully instead of erroring.

Wired into SendPromptAgentic only.

Test plan

  • New TestExtractClaudeCodeResult covers: real envelope (incl. contextWindow metadata), plain text, empty, malformed JSON, envelope with empty result, leading whitespace
  • go test ./utils/... green
  • Replay of the original failing run's stdout through the extractor: zero exit-pattern matches against the resulting prose (was 1 false match before)

🤖 Generated with Claude Code

`SendPromptAgentic` invokes the Claude CLI with `--output-format json`
and was returning the entire envelope (`{"type":"result",...,
"result":"...","usage":{"contextWindow":200000,...}}`) as the agent's
reply. Two consequences:

1. Loop exit-condition regexes saw model metadata. The
   `(?i)context[_\s]*(...|window)` pattern matched `"contextWindow":200000`
   and exited agentic loops as "context exhaustion" after a single
   iteration, even though the agent had only just begun the work.
2. Output files configured for the step received the JSON blob instead
   of the agent's prose, making activity logs unreadable.

Add `extractClaudeCodeResult` to parse the envelope and return only the
`result` field, with safe pass-through for non-JSON / malformed /
empty-result inputs so non-agentic call sites and future format changes
degrade gracefully. Wire it into `SendPromptAgentic`; leave `SendPrompt`
and `SendPromptWithFile` alone (they don't request JSON output).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@kris-hansen kris-hansen merged commit 9e7449c into main Apr 26, 2026
4 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