fix(acp): preserve streamed usage on timeout#934
Conversation
There was a problem hiding this comment.
Your trial has ended. Reactivate Greptile to resume code reviews.
54a6c08 to
62c4900
Compare
There was a problem hiding this comment.
Your trial has ended. Reactivate Greptile to resume code reviews.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 54a6c0829d
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
Users Simulation automation review (2026-07-22): blocked on current head The narrow diff and current CI look good, but the core bug is not actually fixed on the production cleanup path:
Passing evidence: focused timeout/native tests passed, repo Thermo-nuclear review: no broad structural or 1k-line blocker; this is a lifecycle correctness blocker. Recommended fix: collect native ACP usage before Moving labels to |
There was a problem hiding this comment.
Your trial has ended. Reactivate Greptile to resume code reviews.
|
Users Simulation automation follow-up (2026-07-22): fixed the production cleanup blocker on current head What changed:
Validation:
The direct code/config blocker from the previous review is resolved. Moving labels to |
|
Users Simulation automation review (2026-07-24): blocked by artifact-fidelity gate on current head What passes:
Why this is still blocked:
Thermo-nuclear review did not find a #934 structural blocker: the PR adds the usage collection at the correct lifecycle point and does not create a new >1k file or spaghetti branch. Label sync: moved AI-generated automation review posted on behalf of Bingran You. |
Problem
Fixes #933.
ACP native usage was only recorded after
session/promptreturned a finalPromptResult. When a prompt hit BenchFlow's wall-clock or idle timeout, the prompt task was cancelled before that return path, so the session could have no usage snapshots and cleanup finalized the rollout asusage_source=unavailablewithtotal_tokens=0.That is wrong for agents that already stream cumulative usage through
session/update: timed-out runs can have real token usage available before cancellation, and BenchFlow should preserve that best-effort lower bound instead of dropping it.Fix
ACPSession.handle_update()to normalize and record usage telemetry carried bysession/updatenotifications.usagepayloads and top-level ACP usage fields, so agents/protocol extensions can send either shape.Rollout.cleanup()beforedisconnect()clears the live session, so timeout/error paths that skipped the normal execution commit still promote the latest session snapshot.Rollout.disconnect()ordering and verifies_sessionis cleared after usage is preserved.mcpinuv.lockfrom1.27.2to1.28.1after CIpip-auditflaggedCVE-2026-59950; this is a lock-only security update required for the same PR checks to pass.Regression coverage
test_acp_session_records_usage_from_session_updatecovers update-time usage capture.test_cleanup_collects_update_usage_after_timed_out_promptcovers the production cleanup path so streamed usage is collected before disconnect clears the session.mcplock refresh.Validation
Local validation on current head
3bacd9e42cb92de585ffaa35ffa6c9db281a4e7e:uv sync --extra dev --extra sandbox-daytona --lockeduv run python -m pytest tests/test_native_acp_usage.py tests/test_acp.py::TestIdleTimeoutDiagnostics::test_wall_clock_timeout_records_terminal_diagnostic tests/test_acp.py::TestIdleTimeoutDiagnostics::test_wall_clock_timeout_with_pending_tool_stays_partial -q-> 10 passeduv run python -m pytest tests/test_native_acp_usage.py tests/test_acp.py -q-> 91 passeduv run python -m pytest tests/test_acp_mcp_servers.py tests/test_task_config.py::test_task_config_accepts_mcp_tool_filter_surface-> 16 passed on earlier same-PR head after themcplock refreshuv run ruff check .uv run ruff check src/benchflow/rollout/__init__.py tests/test_native_acp_usage.pyuv run ruff format --check src/benchflow/rollout/__init__.py tests/test_native_acp_usage.pyuv run ty check src/git diff --checkuv export --locked --extra dev --extra sandbox-daytona --extra sandbox-modal --format requirements-txt --no-hashes --output-file /tmp/req-audit-pr934-exact && uv run --with pip-audit pip-audit -r /tmp/req-audit-pr934-exact --no-deps --disable-pip --ignore-vuln GHSA-537c-gmf6-5ccf-> no known vulnerabilities found on earlier same-PR head after the lock refreshCurrent-head GitHub validation:
testpassedpip-auditpassedmanifest-parity / paritypassedintegration-light / detect-scopepassedintegration-scope / detect-scopepassedintegration-light / rollout-smokepassedintegration-scopematrix/final-review jobs skipped by scopeArtifact validation from run
29922386377:integration-light-jobsand validated with.agents/skills/benchflow-experiment-review/scripts/validate_run_artifacts.py /tmp/pr934-artifacts.6gAhD8/integration-light-jobs --json.results.jsonltraining-ready, reward present, 323,363 tokens, 17 tool calls, 27 ACP events, and 18/18 LLM responses with usage.Notes
This is intentionally narrow. It does not invent a new partial-usage source type or claim exact provider-cost accounting for every cancellation path. It preserves trusted native ACP usage when an ACP agent has already provided it before timeout, and leaves provider-response telemetry authoritative when available.