feat: add chat lifecycle hook dispatch backend by ibetitsmike · Pull Request #27401 · coder/coder · GitHub
Skip to content

feat: add chat lifecycle hook dispatch backend - #27401

Merged
ibetitsmike merged 33 commits into
mainfrom
mike/chat-hooks/backend
Jul 28, 2026
Merged

feat: add chat lifecycle hook dispatch backend#27401
ibetitsmike merged 33 commits into
mainfrom
mike/chat-hooks/backend

Conversation

@ibetitsmike

@ibetitsmike ibetitsmike commented Jul 22, 2026

Copy link
Copy Markdown
Collaborator

Adds the chat lifecycle hook wire contract and dispatch plumbing, first PR of the lifecycle hooks stack (followed by #27428, #27429, #27430).

  • codersdk/x/agenthooks: event and response wire types, JWT creation and verification with the shared secret (HS256, request body digest, expiry and not-before freshness checks), and an HTTP handler helper so consumers only implement the events they use. The codersdk/x location marks the consumer SDK as experimental.
  • coderd/x/agenthooks/dispatch: a stateless dispatcher that signs and posts hook events, enforces a concurrency cap under one configured timeout that bounds both the capacity wait and both post attempts, retries one connection failure with the same JWT, sends a distinctive coderd-agenthooks/<version> User-Agent, and records Prometheus metrics. Delivery is at least once; consumers own durable decision state, audit records, and deduplication keyed by the stable payload identifiers. Nothing is persisted by Coder.
  • Response bodies decode strictly: unknown fields, duplicate JSON keys (including inside input_override), and trailing data fail the dispatch closed as protocol errors instead of silently reading as allow.
  • coderd/util/xnet: shared timeout and connection error classification used by the dispatcher retry logic. Transient HTTP/2 stream aborts count as connection errors, so the documented single retry also applies to h2 consumers, which is the shape Go's default transport negotiates against any TLS consumer. Deterministic protocol failures stay terminal. Only the struct form of a stream error is matched, because net/http bundles its own HTTP/2 types and h2_error.go bridges only that shape.
  • scripts/agenthooks-server: a reference consumer that logs events and demonstrates consumer-owned pre-tool decision deduplication. It requires an explicitly configured JWT audience rather than deriving one from the request, and its startup output names the mode it is running in so an operator can see that the example policy flags need -log-only=false.
  • scripts/apitypings: generate TypeScript types for the hook wire contract.

Dispatch failures log without the error's stack frames, since a failed dispatch is an expected, operator-visible condition.

Nothing dispatches these events yet; chatd wiring lands in #27429.

This PR was written by Mux, an AI coding agent, on Mike's behalf.

@ibetitsmike
ibetitsmike requested a review from Emyrk as a code owner July 22, 2026 00:13
@github-actions

github-actions Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Copy link
Copy Markdown
Collaborator Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 5552aa2811

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

Comment thread coderd/x/chathooks/dispatcher.go Outdated
@ibetitsmike

Copy link
Copy Markdown
Collaborator Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 8bd38b0b44

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

Comment thread coderd/x/chathooks/dispatcher.go Outdated
@ibetitsmike

Copy link
Copy Markdown
Collaborator Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ceec097949

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

Comment thread coderd/x/chathooks/dispatcher.go Outdated
Comment thread scripts/agenthooks-server/main.go Outdated
@ibetitsmike

Copy link
Copy Markdown
Collaborator Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: bee45f3413

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

Comment thread codersdk/deployment.go Outdated
Comment thread docs/manifest.json Outdated
@ibetitsmike

Copy link
Copy Markdown
Collaborator Author

@codex review

@coderagents

coderagents Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Documentation Check

Updates Needed

  • docs/admin/setup/chat-lifecycle-hooks.md - Document the CODER_CHAT_HOOK_URL well-formedness constraints (must include a host, no fragment, no userinfo). (No longer applicable: the deployment config surface (CODER_CHAT_HOOK_*) and the chat-lifecycle-hooks.md operator page were removed from this PR in a2f6d68. This PR is now backend building blocks only (SDK wire types, dispatcher, reference consumer, metrics); the config and its docs move to the stacked wiring PR feat: wire chat lifecycle hooks into chatd #27275.)

No documentation changes are needed in this PR as currently scoped. The only user-facing docs surface remaining is the coderd_chatd_hook_* Prometheus metrics in docs/admin/integrations/prometheus.md, which are present and accurate.


Automated review via Coder Agents

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 2f225b6148

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

Comment thread codersdk/deployment.go Outdated
@ibetitsmike

Copy link
Copy Markdown
Collaborator Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 3fc031fcb9

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

Comment thread coderd/database/queries/chats.sql Outdated
@ibetitsmike

Copy link
Copy Markdown
Collaborator Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 400000678c

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

Comment thread docs/admin/setup/chat-lifecycle-hooks.md Outdated
@ibetitsmike

Copy link
Copy Markdown
Collaborator Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 400000678c

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

Comment thread docs/admin/setup/chat-lifecycle-hooks.md Outdated
@ibetitsmike

Copy link
Copy Markdown
Collaborator Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Breezy!

Reviewed commit: 400000678c

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

Comment thread coderd/x/chathooks/dispatcher.go Outdated
Comment thread coderd/x/chathooks/dispatcher.go Outdated
Comment thread coderd/x/chathooks/dispatcher.go Outdated
Comment thread coderd/x/chathooks/dispatcher.go Outdated
Comment thread coderd/x/chathooks/dispatcher.go Outdated
Comment thread coderd/x/chathooks/dispatcher.go Outdated
Comment thread coderd/x/chathooks/dispatcher.go Outdated
Comment thread coderd/x/chathooks/dispatcher.go Outdated
Comment thread coderd/x/agenthooks/dispatch/dispatcher.go
@ibetitsmike

Copy link
Copy Markdown
Collaborator Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 40c5d9ae3a

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

Comment thread coderd/x/chathooks/dispatcher.go Outdated
Comment thread coderd/database/migrations/000551_chat_hook_dispatches.up.sql Outdated
…one lock

The remembered-decision lookup, the policy decision, and the store each
took the mutex separately, so concurrent duplicate deliveries of the same
tool_use_id could both miss the cache, both decide, and overwrite each
other's entry. decidePreToolUse now performs all three under one lock.
… mode

Log-only mode is on by default and short-circuits both the deny decision
and the prompt override, so -deny-tool-pattern and -redact-prompt-pattern
had no effect unless -log-only=false was also passed. Prompt redaction
still rewrote the log entry, which made the flag look like it worked. The
help text now states the requirement, and startup reports the effective
mode and warns when a pattern is set while log-only is on.
@ibetitsmike
ibetitsmike force-pushed the mike/chat-hooks/backend branch from 29e417e to bed88ee Compare July 27, 2026 11:10
@linear-code

linear-code Bot commented Jul 27, 2026

Copy link
Copy Markdown

CODAGT-868

@ibetitsmike

Copy link
Copy Markdown
Collaborator Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: bed88ee3fc

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

Comment thread docs/admin/integrations/prometheus.md
The algorithm-confusion test now matches *jose.ErrUnexpectedSignatureAlgorithm
and pins the offending algorithm. The time-bound cases assert their message and
carry a consistent claim window, so the "expired" case exercises the expiry
branch instead of the not-before-after-expiry ordering check.

Drop the handler test's called flag; each callback is the only producer of the
response message already asserted above it.
prepareAndPost returned both an agenthooks.Response and a dispatchOutcome
carrying one, leaving callers to guess which to inspect. It now returns the
outcome alone; Dispatch reads outcome.response, which is what finish already
records. Behavior is unchanged: every early return sets outcome.err, and
newError turns that into a non-nil error before the response is read.

Also fold the capacity-wait floor into max(min(...), 0). The clamp stays
because dispatch.New accepts an unvalidated duration even though deployment
validation constrains it, and notes that json/v2 would retire
rejectDuplicateKeys.
@ibetitsmike

Copy link
Copy Markdown
Collaborator Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Can't wait for the next one!

Reviewed commit: a4db78c0dd

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

Dispatch retried only errors that xnet.IsConnectionError recognized, so an
aborted response was retried over HTTP/1.1 but classified as a protocol error
over HTTP/2, failing the turn. Go's default transport negotiates h2 against any
TLS consumer, so this is the common deployment shape.

Only transient stream codes are retryable; deterministic protocol failures stay
terminal. net/http bundles its own HTTP/2 types and h2_error.go bridges only the
struct form of a stream error, so that is the single reachable match.

Also log dispatch failures without the error's stack frames, since a failed
dispatch is an expected operator-visible condition.
@ibetitsmike

Copy link
Copy Markdown
Collaborator Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

@ibetitsmike
ibetitsmike merged commit 8ea2586 into main Jul 28, 2026
35 of 37 checks passed
@ibetitsmike
ibetitsmike deleted the mike/chat-hooks/backend branch July 28, 2026 11:59
@github-actions github-actions Bot locked and limited conversation to collaborators Jul 28, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants