feat(coderd/x/chatd): record live tool execution stamps in the message part buffer - #28361
Merged
jaaydenh merged 5 commits intoAug 25, 2026
Merged
Conversation
This was referenced Aug 20, 2026
jaaydenh
force-pushed
the
jaayden/codagt-928-stack-3-buffer-tool-execution-stamps
branch
from
August 20, 2026 09:11
811952c to
3b2d2ac
Compare
jaaydenh
marked this pull request as ready for review
August 20, 2026 09:29
jaaydenh
force-pushed
the
jaayden/codagt-928-stack-3-buffer-tool-execution-stamps
branch
from
August 20, 2026 11:28
3b2d2ac to
b61961c
Compare
jaaydenh
force-pushed
the
jaayden/codagt-928-stack-3-buffer-tool-execution-stamps
branch
from
August 20, 2026 13:05
b61961c to
47213ae
Compare
jaaydenh
force-pushed
the
jaayden/codagt-928-stack-3-buffer-tool-execution-stamps
branch
from
August 21, 2026 09:25
47213ae to
154eeda
Compare
jaaydenh
force-pushed
the
jaayden/codagt-928-stack-3-buffer-tool-execution-stamps
branch
from
August 22, 2026 07:06
154eeda to
f4b3d16
Compare
jaaydenh
force-pushed
the
jaayden/codagt-928-stack-3-buffer-tool-execution-stamps
branch
from
August 24, 2026 09:52
f807ad1 to
75793c2
Compare
hugodutka
approved these changes
Aug 24, 2026
jaaydenh
force-pushed
the
jaayden/codagt-928-stack-3-buffer-tool-execution-stamps
branch
from
August 24, 2026 15:24
b23cdd4 to
46ba64c
Compare
jaaydenh
force-pushed
the
jaayden/codagt-928-stack-3-buffer-tool-execution-stamps
branch
from
August 24, 2026 15:49
46ba64c to
ce28900
Compare
jaaydenh
force-pushed
the
jaayden/codagt-928-stack-3-buffer-tool-execution-stamps
branch
from
August 24, 2026 18:03
ce28900 to
6fa8922
Compare
jaaydenh
force-pushed
the
jaayden/codagt-928-stack-3-buffer-tool-execution-stamps
branch
from
August 25, 2026 09:09
6fa8922 to
d2866f0
Compare
jaaydenh
added a commit
that referenced
this pull request
Aug 25, 2026
…ocalTools (#28359) **Stack**: **#28359 (this PR)** → #28360 → #28361 → #28362 `chatloop.ToolExecutionOutcome` only wrapped a `PersistedStep`, so callers had to reach through `outcome.Step` for every field. `ExecuteLocalTools` now returns the `PersistedStep` directly and the wrapper type is deleted. No behavior change. First of a four-PR stack that makes local tool execution count toward Coder Agent runtime (splitting #28211). This refactor keeps the rename noise out of the feature PRs. Refs CODAGT-928 (https://linear.app/codercom/issue/CODAGT-928/track-local-tool-execution-for-agent-runtime).
jaaydenh
force-pushed
the
jaayden/codagt-928-stack-3-buffer-tool-execution-stamps
branch
from
August 25, 2026 09:31
d2866f0 to
6470820
Compare
Base automatically changed from
jaayden/codagt-928-stack-2-bill-completed-tool-batches
to
main
August 25, 2026 09:40
…e part buffer Interrupted local tool batches bill nothing today because nobody tracks when each call actually starts and finishes. Buffer episodes now record per-occurrence start and completion stamps while local tools execute. Occurrences are keyed by unresolved-call position, so gaps left by rejected calls and duplicate tool-call IDs stay distinct. partitionAmbiguousToolCalls returns the allowed calls' input positions, and generation translates dispatch-order callbacks back through them. Nothing reads the stamps yet; a follow-up bills interrupted batches on their synthesized cancellation rows.
…ecorder interface
Co-authored-by: Hugo Dutka <[email protected]>
Co-authored-by: Hugo Dutka <[email protected]>
jaaydenh
added a commit
that referenced
this pull request
Aug 25, 2026
) **Stack**: #28359 → **#28360 (this PR)** → #28361 → #28362 ## Summary Completed local tool batches now count toward Coder Agent runtime (`chat_messages.runtime_ms`, the source of truth for `hb_agent_runtime_v1`), excluding sub-agent orchestration tools to avoid double counting, and without multiplying runtime for parallel tool calls. Second of a four-PR stack splitting #28211. Stacked on #28359. Refs CODAGT-928 (https://linear.app/codercom/issue/CODAGT-928/track-local-tool-execution-for-agent-runtime). ## Problem Agent runtime previously measured only model invocation wall clock (stream open to fully consumed). Time spent executing local tools between steps, including file operations, terminal commands, workspace provisioning, and MCP tools, was deliberately excluded, which undercounts the product definition of "actively processing a task". Naive inclusion has two hazards: a batch of parallel tool calls would bill N windows for one wall-clock wait, and `wait_agent` would re-bill child agents that already bill their own model and tool time. ## Fix Each completed local tool batch bills one window: the union of the billed tools' execution intervals, persisted as `runtime_ms` on a dedicated usage record appended after the batch's tool-result rows. The record is a tool-role message with `visibility='model'`, so it never reaches the API, SSE, or clients, and prompt replay drops it because its single internal `tool-batch-usage` part converts to no provider content. Its content carries an audit payload (`billed_ms`, `billed_calls`) so the billed window is inspectable after the fact; real tool-result rows never carry batch-level runtime. Concurrent calls all start at batch start, so 5 parallel 10s reads bill 10s, not 50s; serial calls (`SerialToolCalls`) count only from their own launch, so unbilled waits before them do not count. Sub-agent orchestration tools (`spawn_agent`, `wait_agent`, `message_agent`, `interrupt_agent`, `list_agents`, `list_subagent_models`, plus the deprecated `close_agent` alias) never extend the window: every chat, including children, applies the same rules to its own runtime, so a parent's `wait_agent` window would double count. A lone `wait_agent` bills 0 and appends no usage record; `execute` 10s in parallel with `wait_agent` 60s bills 10s. A test pins the unbilled set to the registered sub-agent tool catalog so they cannot drift. `GetTotalChatMessageRuntimeMsInRange` already sums `runtime_ms` role-agnostically, so the usage record is picked up with no schema, query, or cron changes. Client-executed dynamic tools, external agents, parked/idle time, and retry backoff remain unbilled. Interrupted batches still bill only the model window; the rest of the stack adds partial-window billing via the same usage record. `ExecuteLocalToolsOptions` also gains an optional `ToolBillingRecorder` (`RecordStart`/`RecordComplete`) observing per-occurrence dispatch-order execution stamps. This PR wires no recorder; the next PR in the stack connects it to the message part buffer for interrupt billing. **NOTE**: Reported agent runtime (`hb_agent_runtime_v1`) increases from deploy forward. There is no backfill and no feature flag.
jaaydenh
force-pushed
the
jaayden/codagt-928-stack-3-buffer-tool-execution-stamps
branch
from
August 25, 2026 09:40
6470820 to
585bae9
Compare
jaaydenh
deleted the
jaayden/codagt-928-stack-3-buffer-tool-execution-stamps
branch
August 25, 2026 09:57
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stack: #28359 → #28360 → #28361 (this PR) → #28362
During local tool execution, buffer episodes now record when each tool-call occurrence actually starts and finishes, via
RecordToolStart/RecordToolCompletion/ToolCompletionson the message part buffer. Occurrences are keyed by unresolved-call position, so gaps left by rejected calls and duplicate tool-call IDs stay distinct:partitionAmbiguousToolCallsadditionally returns the allowed calls' input positions, and generation'schatloop.ToolBillingRecorderimplementation translates dispatch-order stamps back through them.Mechanism only: nothing reads the stamps yet. The final PR in the stack uses them to bill interrupted tool batches on a dedicated usage record committed alongside their synthesized cancellation rows.
Third of a four-PR stack splitting #28211. Stacked on #28360. Refs CODAGT-928 (https://linear.app/codercom/issue/CODAGT-928/track-local-tool-execution-for-agent-runtime).