feat(coderd/x/chatd/chatstate): add hook-aware transitions and queued policy#27428
feat(coderd/x/chatd/chatstate): add hook-aware transitions and queued policy#27428ibetitsmike wants to merge 1 commit into
Conversation
|
Warning This pull request is not mergeable via GitHub because a downstack PR is open. Once all requirements are satisfied, merge this PR as a stack on Graphite.
This stack of pull requests is managed by Graphite. Learn more about stacking. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 9fefafe6dc
ℹ️ 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".
fb591a8 to
cdabebf
Compare
9fefafe to
e0b7344
Compare
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e0b7344a0f
ℹ️ 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".
e0b7344 to
a05cf3c
Compare
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a05cf3ceb6
ℹ️ 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".
cdabebf to
fb7db50
Compare
a05cf3c to
841eefb
Compare
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 841eefb780
ℹ️ 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".
… policy Threads hook effects through chat state transitions: prefix messages and narrowed tool policies persist with queued prompts and apply at promotion, messages carry turn IDs, CreateChatWithID supports caller-minted chat IDs with an initial hook tool policy, CompleteRequiresAction accepts suffix messages, and FailIdle moves a waiting chat to the error state when a hook dispatch fails outside an owned run.
841eefb to
e08f7af
Compare
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e08f7affcd
ℹ️ 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".
| return EditMessageResult{}, err | ||
| } | ||
| cancellationMessages, err := tx.insertMessages(cancels) | ||
| cancellationMessages, err := tx.insertMessages(append(cancels, input.PrefixMessages...)) |
There was a problem hiding this comment.
Stamp prefix messages with the edited turn ID
When EditMessage is called with hook PrefixMessages that do not already carry input.TurnID, these rows are inserted with a NULL or stale turn_id; the next edit only removes stale prefixes by matching the target message's TurnID above, so old hook context can remain in the model prompt next to the replacement. The queued-promotion path explicitly stamps prefixes with the queued prompt's turn ID for this reason, so the edit path, and the analogous direct-send path, should stamp prefixes before insertion.
Useful? React with 👍 / 👎.
| - `Interrupt(reason)` requests cancellation of an active generation or closes pending dynamic-tool action. It preserves queued backlog. | ||
| - `CompleteRequiresAction(results)` inserts submitted tool-result messages, clears `requires_action_deadline_at`, and lands in `running`. It preserves queued messages. | ||
| - `RequestCompaction` records a manual compaction request on an idle chat by setting `compaction_requested_at` and landing in `running` without inserting any message. The chat worker picks the chat up like any other running chat and consumes the request. See [Manual compaction](#manual-compaction). | ||
| - `FailIdle(err)` moves a waiting chat to `error` and persists `last_error = err` without requiring runner ownership. Used when a blocking lifecycle hook dispatch fails while handling `SendMessage` or `EditMessage`, before any generation starts. |
There was a problem hiding this comment.
Document the new hook state in the architecture guide
This architecture update only adds FailIdle, but the commit also makes turn_id, queued hook_prefix, and hook_allowed_tools part of promotion, edit cleanup, and policy narrowing semantics. Leaving those fields out of the state-machine spec means future chatd work will still read that queued execution state is only position and created_by, with no mention of deferred hook context or tool-policy narrowing. Please update the architecture doc for those state changes too.
AGENTS.md reference: AGENTS.md:L90-L93
Useful? React with 👍 / 👎.

Stack Context
Chat lifecycle hooks stack: #27427 (DB schema) -> #27401 (dispatch backend) -> #27428 (this) -> #27429 (chatd wiring) -> #27430 (API + UI).
What
State-machine primitives that hook responses need, with no hook dispatch here:
hook_prefixandhook_allowed_toolsso hook effects apply at promotion time, not queue time; policies can only narrow on promotion.NarrowHookAllowedTools: intersection semantics for allowed-tools policies (NULL means unrestricted).FailIdlefor idle-chat error termination.Why
These transitions are pure state-machine mechanics, testable without any hook plumbing (see the transition matrix tests). Keeping them below #27429 makes the chatd diff reviewable as "dispatch + response application" only.