Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
5552aa2
feat: add chat lifecycle hook dispatch backend
ibetitsmike Jul 21, 2026
8bd38b0
fix(coderd/x/chathooks): derive persisted tool metadata from hook pay…
ibetitsmike Jul 22, 2026
ceec097
fix(coderd/x/chathooks): retry mid-body hook connection errors
ibetitsmike Jul 22, 2026
bee45f3
fix(coderd/x/chathooks): reject deny input overrides and redact log-o…
ibetitsmike Jul 22, 2026
2f225b6
fix(codersdk): reject chat hook URLs with fragments or userinfo
ibetitsmike Jul 22, 2026
3fc031f
fix(codersdk): reject hostless chat hook URLs
ibetitsmike Jul 22, 2026
4000006
fix(coderd/database): lock purge candidates before deleting hook disp…
ibetitsmike Jul 22, 2026
6ea005e
refactor(coderd/x/chathooks): spell byte limits as literal numbers
ibetitsmike Jul 22, 2026
e2f44d9
refactor(coderd/x/chathooks): type dispatch results as a string enum
ibetitsmike Jul 22, 2026
fb7db69
refactor(coderd/x/chathooks): drop redundant comments and fix New doc
ibetitsmike Jul 22, 2026
6de8710
refactor(coderd/x/chathooks): merge Dispatch and DispatchWithID
ibetitsmike Jul 22, 2026
5ba56ed
fix(coderd/x/chathooks): persist dispatch rows when the caller cancel…
ibetitsmike Jul 22, 2026
9815749
fix(coderd/x/chathooks): reject tool events without tool identity
ibetitsmike Jul 22, 2026
40c5d9a
refactor(codersdk/agenthooks): extract shared ChatRef from hook metadata
ibetitsmike Jul 22, 2026
01ed9a1
fix(coderd/x/chathooks): stop persisting null deny input overrides
ibetitsmike Jul 22, 2026
9715746
feat(coderd): wire chat lifecycle hooks into chatd
ibetitsmike Jul 22, 2026
9bd77e6
refactor(coderd/x/chatd): drop redundant event tool metadata assignments
ibetitsmike Jul 22, 2026
49b96a2
fix(coderd/x/chatd): persist API hook dispatch failures with the hook…
ibetitsmike Jul 22, 2026
5d27fff
refactor(coderd/x/chatd): apply hook review feedback to dispatch and …
ibetitsmike Jul 22, 2026
9c76cfb
refactor(coderd/x/chatd): split EndChat into a single-chat transition…
ibetitsmike Jul 22, 2026
874d219
chore(coderd/x/chatd): remove redundant lifecycle comments
ibetitsmike Jul 22, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions cli/testdata/coder_server_--help.golden
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,20 @@ Configure the background chat processing daemon.
Force chat debug logging on for every chat, bypassing the runtime
admin and user opt-in settings.

--chat-hook-enabled bool, $CODER_CHAT_HOOK_ENABLED (default: true)
Whether to dispatch chat agent lifecycle hooks when a hook URL is
configured. Requires the agent-lifecycle-hooks experiment.

--chat-hook-secret string, $CODER_CHAT_HOOK_SECRET
Shared secret used to sign chat agent lifecycle hook JWTs.

--chat-hook-timeout duration, $CODER_CHAT_HOOK_TIMEOUT (default: 1.5s)
Maximum time to wait for a chat agent lifecycle hook response.

--chat-hook-url url, $CODER_CHAT_HOOK_URL
HTTPS URL to receive chat agent lifecycle hook events. Hooks are
disabled when unset. Requires the agent-lifecycle-hooks experiment.

CLIENT OPTIONS:
These options change the behavior of how clients interact with the Coder.
Clients include the Coder CLI, Coder Desktop, IDE extensions, and the web UI.
Expand Down
11 changes: 11 additions & 0 deletions cli/testdata/server-config.yaml.golden
Original file line number Diff line number Diff line change
Expand Up @@ -803,6 +803,17 @@ chat:
# opt-in settings.
# (default: false, type: bool)
debugLoggingEnabled: false
# HTTPS URL to receive chat agent lifecycle hook events. Hooks are disabled when
# unset. Requires the agent-lifecycle-hooks experiment.
# (default: <unset>, type: url)
hookURL:
# Maximum time to wait for a chat agent lifecycle hook response.
# (default: 1.5s, type: duration)
hookTimeout: 1.5s
# Whether to dispatch chat agent lifecycle hooks when a hook URL is configured.
# Requires the agent-lifecycle-hooks experiment.
# (default: true, type: bool)
hookEnabled: true
# Deprecated: AI Gateway routing is now the only routing path. Setting this value
# has no effect. This option will be removed in a future release.
# (default: true, type: bool)
Expand Down
48 changes: 43 additions & 5 deletions coderd/apidoc/docs.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

48 changes: 43 additions & 5 deletions coderd/apidoc/swagger.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

24 changes: 24 additions & 0 deletions coderd/coderd.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ import (
"github.com/coder/coder/v2/coderd/x/chatd"
"github.com/coder/coder/v2/coderd/x/chatd/chatprovider"
"github.com/coder/coder/v2/coderd/x/chatd/mcpclient"
"github.com/coder/coder/v2/coderd/x/chathooks"
"github.com/coder/coder/v2/coderd/x/gitsync"
"github.com/coder/coder/v2/codersdk"
"github.com/coder/coder/v2/codersdk/drpcsdk"
Expand Down Expand Up @@ -878,6 +879,28 @@ func New(options *Options) *API {
// the chat daemon stays nil and chat HTTP handlers return a
// service-unavailable error with a clear remediation message.
if options.DeploymentValues.AI.BridgeConfig.Enabled.Value() {
var hookDispatcher *chathooks.Dispatcher
chatConfig := options.DeploymentValues.AI.Chat
hooksConfigured := chatConfig.HookURL.String() != "" && chatConfig.HookEnabled.Value()
hooksExperimentEnabled := experiments.Enabled(codersdk.ExperimentAgentLifecycleHooks)
if hooksConfigured && !hooksExperimentEnabled {
options.Logger.Warn(ctx, "chat lifecycle hooks are configured but inactive; enable the agent-lifecycle-hooks experiment to activate them",
slog.F("experiment", codersdk.ExperimentAgentLifecycleHooks),
)
}
if hooksConfigured && hooksExperimentEnabled {
hookDispatcher = chathooks.New(
options.Logger,
options.Database,
nil,
chatConfig.HookURL.String(),
chatConfig.HookSecret.Value(),
chatConfig.HookTimeout.Value(),
api.DeploymentID,
buildinfo.Version(),
options.PrometheusRegistry,
)
}
api.chatDaemon = chatd.New(options.Pubsub, chatd.Config{
Logger: options.Logger.Named("chatd"),
Database: options.Database,
Expand All @@ -897,6 +920,7 @@ func New(options *Options) *API {
StartWorkspace: api.chatStartWorkspace,
StopWorkspace: api.chatStopWorkspace,
WebpushDispatcher: options.WebPushDispatcher,
HookDispatcher: hookDispatcher,
UsageTracker: options.WorkspaceUsageTracker,
PrometheusRegistry: options.PrometheusRegistry,
OIDCTokenSource: oidcMCPSrc,
Expand Down
Loading
Loading