Skip to content

fix(#6806): capture num_turns from incomplete Claude streams - #7687

Open
fullsend-ai-coder[bot] wants to merge 3 commits into
mainfrom
agent/6806-incremental-num-turns
Open

fullsend-ai-coder[bot] wants to merge 3 commits into
mainfrom
agent/6806-incremental-num-turns

Conversation

@fullsend-ai-coder

Copy link
Copy Markdown
Contributor

Summary

Claude Code review (and other) runs that crash or are killed after producing valid output no longer report num_turns: 0 in metrics.json. The runner now counts message_start events on the stream and carries that running total on TokensEvent, the same incremental channel already used for token counts.

Related Issue

This is the remaining gap from #6806 after #6908/#6938 captured token counters on cancelled/killed Claude runs. Those PRs left NumTurns and TotalCostUSD sourced only from the terminal ResultEvent.

Changes

  • Count message_start events in parseClaudeStream and attach the running turn count to TokensEvent.
  • Fold TokensEvent.NumTurns into RunMetrics via a shared applyClaudeMetrics helper (used by both ClaudeRuntime.Run and progressParser). A later ResultEvent still overwrites with authoritative totals.
  • Document that num_turns has this fallback in docs/cli/run.md.
  • Cost is unchanged. Claude Code only reports total_cost_usd on the terminal result line, and fullsend does not estimate cost from token counts (Cost data contract). Incomplete streams still persist total_cost_usd: 0.

This does not revive the synthetic-ResultEvent approach from closed PR #6808. Turns ride the existing TokensEvent snapshot, matching the #6908 architecture for tokens.

Testing

  • New regression: incomplete multi-turn stream reports NumTurns == 3 and TotalCostUSD == 0
  • Broken-pipe / cancelled-run tests assert non-zero turns
  • message_start without message_delta still emits a deferred TokensEvent with NumTurns
  • ResultEvent still overwrites the incremental snapshot
  • go test ./internal/runtime/ and targeted ./internal/cli/ aggregation tests pass
  • go vet ./internal/runtime/ ./internal/cli/
  • applyClaudeMetrics is 100% covered; parseClaudeStream is 93.2%

Checklist

  • PR title follows Conventional Commits (fix(#6806): ...)
  • Commits are not signed off (autonomous agent, DCO-exempt)
  • I wrote this contribution myself and can explain all changes in it

Closes #6806

Post-script verification

  • Branch is not main/master (agent/6806-incremental-num-turns)
  • Secret scan passed (gitleaks — fbf65c8b8c717d74fa6033519658851efaba91f9..HEAD)
  • PR body secret scan passed (gitleaks — no-git)

Claude Code only reports num_turns on the terminal result NDJSON line.
When the process exits abnormally after doing work (exit_code -1),
metrics.json recorded num_turns: 0 even though token counts already
survive via TokensEvent (#6905).

Count message_start events and carry the running turn count on
TokensEvent so incomplete streams still populate num_turns. Dollar
cost stays zero: the runtime does not report incremental cost, and
fullsend does not estimate it from token counts.

Note: pre-commit could not fetch remote hook repositories (HTTP 403).
Local equivalents were run: gofmt, go vet, trailing-whitespace,
end-of-file, lint-docs-links, lychee, lint-broken-symlinks, and
scan-secrets.

Closes #6806
@fullsend-ai-coder
fullsend-ai-coder Bot requested a review from a team as a code owner September 24, 2026 19:11
@fullsend-ai-coder fullsend-ai-coder Bot added the ready-for-review Triggers review agent dispatch label Sep 24, 2026
@fullsend-ai-review

fullsend-ai-review Bot commented Sep 24, 2026 •

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 7:13 PM UTC · Completed 7:27 PM UTC

Commit: 13c77fa · View workflow run →

Runtime: pi · Model: sonnet → claude-sonnet-5 · Effort: high · Cost: $4.66

@github-actions

github-actions Bot commented Sep 24, 2026 •

Copy link
Copy Markdown

Site preview

Preview: https://f9401bec-site.fullsend-ai.workers.dev

Commit: 7e03869e10d4b1db2a3dba4ed6fc9038788ba2df

@codecov

codecov Bot commented Sep 24, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 96.96970% with 1 line in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
internal/runtime/claude.go 0.00% 1 Missing ⚠️

📢 Thoughts on this report? Let us know!

@fullsend-ai-review fullsend-ai-review Bot added the risk/moderate PR risk: moderate label Sep 24, 2026
@fullsend-ai-review

fullsend-ai-review Bot commented Sep 24, 2026 •

Copy link
Copy Markdown

Risk Assessment: moderate (2/5)

Details

Moderate risk: focused 7-file bug fix with strong test coverage by a bot author, offset by high churn and coupling in modified CLI and runtime files (unchanged from prior review; anchored).

Previous run

Risk Assessment: moderate (2/5)

Details

Moderate risk: focused 7-file bug fix with strong test coverage by a bot author, offset by high churn and coupling in modified CLI and runtime files.

Previous run (2)

Risk Assessment: moderate (2/5)

Details

Moderate risk: focused 7-file bug fix with strong test coverage by a bot author, offset by high churn and coupling in modified CLI and runtime files.

@fullsend-ai-review

fullsend-ai-review Bot commented Sep 24, 2026 •

Copy link
Copy Markdown

Looks good to me

Previous run

Looks good to me

Previous run (2)

Review

Findings

Low

  • [api-shape-pattern] internal/runtime/claude_progress.go:541 — applyClaudeMetrics dereferences metrics without a nil guard. Its counterpart applyCodexMetrics (internal/runtime/codex_progress.go:668-671) returns immediately on nil. This PR extracted the Claude fold into a package-level helper used from ClaudeRuntime.Run and progressParser; both still panic on a nil *RunMetrics. No current production or test call site passes nil (internal/cli/run.go uses var metrics ...; rt.Run(..., &metrics), and ClaudeRuntime{}.Run tests do the same), so this is a defensive consistency gap, not a live crash.
    Remediation: Add if metrics == nil { return } at the start of applyClaudeMetrics to match applyCodexMetrics.

Next steps:

  • /fs-fix — agent addresses review findings automatically
  • /fs-fix <your instruction> — agent fixes with your specific guidance
  • Push commits directly — review re-runs automatically on push
  • /fs-fix-stop — disable automatic fix runs for this PR

fullsend-ai-review[bot]

This comment was marked as outdated.

@fullsend-ai-coder

fullsend-ai-coder Bot commented Sep 24, 2026 •

Copy link
Copy Markdown
Contributor Author

🤖 Finished Fix · ✅ Success · Started 7:28 PM UTC · Completed 7:38 PM UTC

Commit: 13c77fa · View workflow run →

Runtime: claude · Model: sonnet → claude-sonnet-5 · Effort: high · Cost: $1.43

Add the same nil check applyCodexMetrics already has. No current call
site passes nil, so this is a defensive consistency fix, not a live
crash fix, per review feedback on PR #7687.

Addresses #7687
@fullsend-ai-coder

Copy link
Copy Markdown
Contributor Author

🔧 Fix agent — iteration 1 (bot-triggered)

Added the missing nil guard to applyClaudeMetrics to match applyCodexMetrics's defensive pattern, plus a regression test asserting it does not panic on a nil *RunMetrics.

Fixed (1):

  1. applyClaudeMetrics dereferences metrics without a nil guard, unlike its counterpart applyCodexMetrics (internal/runtime/claude_progress.go): Added an if metrics == nil { return } guard at the top of applyClaudeMetrics, matching applyCodexMetrics. Verified no current call site (ClaudeRuntime.Run, progressParser) passes nil, so this is a defensive consistency fix rather than a live-crash fix, as the review itself noted. Added a regression line to the existing TestApplyClaudeMetricsTokensEventSetsTurns test asserting applyClaudeMetrics(nil, ResultEvent{}) does not panic, mirroring applyCodexMetrics's existing nil test.

Tests: passed

CI inspections (13):

  1. test (passing, success): CI unit/integration test job passed on the pre-fix head SHA.
  2. commit-lint (passing, success): Commit message linting passed.
  3. web (passing, success): Web/docs build job passed.
  4. test-sandbox-darwin (passing, success): Darwin sandbox test job passed.
  5. codecov/patch (passing, success): Patch coverage check passed.
  6. functional-tests (passing, success): Functional test suite passed.
  7. gate (E2E Tests) (passing, success): E2E gate job passed.
  8. gate (Functional Tests) (passing, success): Functional-tests gate job passed.
  9. behaviour (passing, success): Behaviour test suite passed.
  10. e2e (passing, success): E2E test suite passed.
  11. build (passing, success): Docs site build job passed.
  12. vouch-gate (passing, success): Contributor vouch gate passed.
  13. DCO (passing, success): DCO check passed (autonomous commits exempt).

Next steps:

  • /fs-review — request a re-review of the changes
  • /fs-fix <your instruction> — run another fix pass with specific guidance
  • Push commits directly — review re-runs automatically on push
    Updated by fullsend fix agent

@fullsend-ai-review

fullsend-ai-review Bot commented Sep 24, 2026 •

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 7:40 PM UTC · Completed 7:50 PM UTC

Commit: 3e04bd5 · View workflow run →

Runtime: pi · Model: sonnet → claude-sonnet-5 · Effort: high · Cost: $2.67

fullsend-ai-review[bot]

This comment was marked as outdated.

@fullsend-ai-review fullsend-ai-review Bot added the ready-for-merge All reviewers approved — ready to merge label Sep 24, 2026
@fullsend-ai-review

fullsend-ai-review Bot commented Sep 27, 2026 •

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 6:49 PM UTC · Completed 7:02 PM UTC

Commit: 7e03869 · View workflow run →

Runtime: pi · Model: sonnet → claude-sonnet-5 · Effort: high · Cost: $2.81

@fullsend-ai-review
fullsend-ai-review Bot dismissed their stale review September 27, 2026 19:02

Superseded by updated review

This branch was successfully deployed

1 active and 1 inactive deployments
site-preview — 7e03869e Deployed Sep 27, 2026 by github-actions[bot]
dev — 7e03869e Deployed Sep 27, 2026 by ifireball via behaviour #14238
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ready-for-merge All reviewers approved — ready to merge ready-for-review Triggers review agent dispatch risk/moderate PR risk: moderate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Review agent metrics zeroed when agent process exits with error after writing valid output

1 participant