Skip to content

refactor(coderd/x/chatd/chatstate): share one outstanding tool-call scan - #30883

Open
ibetitsmike wants to merge 3 commits into
mainfrom
mike/chatstate-outstanding-tool-calls
Open

ibetitsmike wants to merge 3 commits into
mainfrom
mike/chatstate-outstanding-tool-calls

Conversation

@ibetitsmike

Copy link
Copy Markdown
Collaborator

Cancellation synthesis and the pending-call checks in chatstate each repeated the same scan of the last assistant message. They looked up the message, parsed it, tracked answered calls, and applied the same exclusion rules. This PR keeps one copy of that scan.

  • lastAssistantTurn loads the last assistant message's parts and the set of tool calls already answered, either inside that message (provider-executed results) or by a tool message after it.
  • outstandingToolCalls owns eligibility: tool calls only, no provider-executed calls, no answered calls, and optionally only the chat's dynamic tools. It keeps the no-read fast path when a dynamic-only scan finds no dynamic tools.
  • synthesizePendingToolCancellations and pendingDynamicToolCallIDs now only build cancellation messages or the pending-call map. pendingAllToolCallIDs and outstandingToolCallIDs are deleted; FinishInterruption calls outstandingToolCalls directly.

Behavior is unchanged except for error text on the pending-call paths, which now uses the cancellation path's wording: get last assistant: becomes get last assistant message:, parse assistant: becomes parse assistant message:, and the dynamic-tools parse error gains a parse dynamic tool names: prefix. Nothing in the repo matches on these strings.

Touched functions Before After
Cyclomatic (sum) 49 33
Cognitive (sum) 69 37
Highest CRAP 52.0 (synthesizePendingToolCancellations, cc 23, 62% covered) 11.1 (outstandingToolCalls, cc 11, 89.5% covered)

The diff is +139/-227 across production and tests. Test fixtures now share one chatMessage builder.

Testing

  • The waiting-state cancellation test now covers part order, provider-executed calls, calls answered inline and after, and an unparsable tool row. The A1 CancelRequiresAction matrix case now seeds one dynamic and one non-dynamic call. Breaking any of those behaviors or the dynamic filter fails a test, and the new assertions also pass on the old code.
  • go test ./coderd/x/chatd/..., go test -race ./coderd/x/chatd/chatstate, golangci-lint on chatstate (0 issues), and make pre-commit pass.

Review record

  • Standards and spec review passes (3 rounds each) both ended with PASS. Fixed during review: slice aliasing in the scan, duplicated test fixtures, a stale doc comment, and the unpinned dynamic filter.

Xum opened this PR on behalf of @ibetitsmike.

Cancellation synthesis and the pending-call checks each repeated the
last-assistant lookup, tool-result tracking, and eligibility rules.
outstandingToolCalls now owns that scan; its callers only build
cancellation messages or the pending-call map.
…rom call policy

lastAssistantTurn loads the last assistant message and the tool calls
already answered; outstandingToolCalls keeps the eligibility rules.
Test fixtures share one chatMessage builder, and the waiting-state
cancellation test now covers provider-executed, answered, and
unparsable cases and part order.
CancelRequiresAction from A1 now runs on a seed with one dynamic and
one non-dynamic outstanding call, so dropping the dynamic filter fails
the transition matrix. Also tighten the outstandingToolCalls doc and
build the unparsable test row directly.
@ibetitsmike

Copy link
Copy Markdown
Collaborator Author

@codex review

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 15, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-16T14:10:08.989120Z 65c8dc5 Draft marked ready
ℹ️ 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" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. What shall we delve into next?

Reviewed commit: 65c8dc52cc

ℹ️ 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".

@ibetitsmike
ibetitsmike marked this pull request as ready for review October 16, 2026 14:08
@pr-queue-manager
pr-queue-manager Bot requested a review from hugodutka October 16, 2026 14:09

This branch has not been deployed

No deployments
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