Skip to content

feat: add chat automations (autochat)#23184

Draft
kylecarbs wants to merge 3 commits intomainfrom
kylecarbs/autochat
Draft

feat: add chat automations (autochat)#23184
kylecarbs wants to merge 3 commits intomainfrom
kylecarbs/autochat

Conversation

@kylecarbs
Copy link
Member

What

Adds a new autochat system that allows users to create automations that trigger chat creation via webhooks or cron schedules.

Why

Enables use cases like:

  • CI failure remediation: GitHub webhook fires on check suite failure → automation creates a chat that investigates and pushes a fix.
  • Scheduled code audits: Cron-triggered automations run weekly dependency checks, test coverage analysis, etc.
  • Event-driven agent workflows: Any system that can send an HTTP POST can trigger an agent chat.

How

Database

  • chat_automations table: stores automation definitions (trigger type, webhook secret, cron schedule, model config, prompt template).
  • chat_automation_runs table: tracks individual executions with status lifecycle (pending → running → completed/failed).
  • automation_id column on chats: links automation-spawned chats back to their automation. Default query excludes these from the normal chat list.

API Routes

All under /api/v2/chats/automations:

Method Path Auth Description
GET / Session List user's automations
POST / Session Create automation (returns webhook secret once)
GET /{id} Session Get automation (secret masked)
PUT /{id} Session Update automation
DELETE /{id} Session Delete automation
POST /{id}/trigger Session Manual fire
POST /{id}/rotate-secret Session Rotate webhook secret
GET /{id}/runs Session List runs
POST /{id}/webhook HMAC Webhook ingress (unauthenticated)

Core Package: coderd/chatd/autochat/

  • executor.go: Fire() checks concurrency limits, renders prompt template, creates chat via chatd.CreateChat(), records run.
  • webhook.go: HMAC-SHA256 verification supporting X-Hub-Signature-256 (GitHub native) and X-Coder-Signature.
  • render.go: Go text/template with restricted funcmap. Webhook data: {{.Body}}, {{.Headers}}. Cron data: {{.ScheduledAt}}.
  • cron.go: Background executor on 30s ticker using quartz.Clock for testability.

Security

  • Per-automation HMAC-SHA256 webhook secret (32 random bytes, hex-encoded).
  • Secret returned only on creation; masked on all subsequent reads.
  • Constant-time comparison via hmac.Equal to prevent timing attacks.
  • Raw body read before JSON parsing to preserve HMAC integrity.

Permissions

Automation-spawned chats run as automation.OwnerID — same RBAC as if the creator typed the message in the UI. No privilege escalation.

Tests

  • autochat/render_test.go: 10 tests covering substitution, nested maps, error cases, funcmap.
  • autochat/webhook_test.go: 10 tests covering HMAC verification, header fallback, secret generation, masking.

Adds a new 'autochat' system that allows users to create automations
that trigger chat creation via webhooks or cron schedules. This enables
use cases like CI failure remediation, scheduled code audits, and
event-driven agent workflows.

Key components:
- Database: chat_automations and chat_automation_runs tables, plus
  automation_id column on chats for filtering automation-spawned chats
  out of the normal chat list.
- API: Full CRUD under /api/v2/chats/automations with webhook ingress
  at /api/v2/chats/automations/{id}/webhook (unauthenticated, secured
  by HMAC-SHA256 signature verification).
- autochat package (coderd/chatd/autochat/):
  - executor.go: Core Fire() function that checks concurrency limits,
    renders prompt templates, and creates chats via chatd.
  - webhook.go: HMAC-SHA256 signature verification supporting both
    X-Hub-Signature-256 (GitHub) and X-Coder-Signature headers.
  - render.go: Go text/template prompt rendering with restricted
    funcmap for webhook body/headers and cron schedule data.
  - cron.go: Background executor on a 30s ticker that fires due
    cron-triggered automations.
- SDK types and client methods in codersdk/chatautomations.go.
- Middleware for extracting automation params from URL.

Automation-spawned chats run as the automation creator (OwnerID),
inheriting their RBAC permissions. The existing chatd.Server background
loop picks up pending chats with zero changes to the chat runtime.
david-fraley added a commit that referenced this pull request Mar 17, 2026
Covers four improvement areas:
1. Granular status reporting (needs_user_attention, message, uri)
2. Outbound webhook subscriptions (building on #23184 infra)
3. Structured output for iterative development
4. Admin API and governance gaps

Grounded in customer feedback from CoreWeave, QRT, Figma, Schonfeld,
BMW, MDA, and OCBC.
@kylecarbs kylecarbs marked this pull request as draft March 17, 2026 21:00
Move all chat automation HTTP handlers from the standalone
chatautomations.go into chats.go to keep the chat API surface in
one file, matching the project convention.

Fixes from code review:
- Add dbauthz.AsSystemRestricted(ctx) for the unauthenticated
  webhook endpoint's DB call.
- Add cron schedule validation via cron.Weekly() in create handler.
- Fix swagger: update [patch] → [put], 201 → 202 on webhook.
- Add EXPERIMENTAL comments to all automation handlers.
- Use dbtime.Now() instead of time.Now() in executor.
- Remove dead ChatCreator interface from executor.go.
- Log errors instead of silently discarding in executor failure path.
- Name executor logger ("autochat").
- Validate non-empty webhook secret in VerifyWebhookSignature.
- Normalize hex case in signature verification.
- Convert promptFuncMap from mutable package-level var to function.
- Use literal expected value in FuncPipeline test.
- Add empty-string test case for MaskSecret.
- Fix collapsed lines and indentation in coderd.go (gofmt).
- Implement all 11 dbauthz methods for chat automations using
  rbac.ResourceChat scoped to the automation owner. No more panics.
- Thread AutomationID from autochat.CreateChatOptions through
  chatd.CreateOptions to database.InsertChatParams so automation-
  spawned chats are properly tagged.
- Add watchRunCompletion goroutine that subscribes to chat status
  change events via pubsub and marks runs as completed/failed when
  the chat reaches a terminal state.
- Pass pubsub to autochat.Executor for event subscription.
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