mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
Adds a persisted whole-chat summary that backs the chat summary popover. A new nullable `chats.summary` column is populated in the background after a successful root-chat turn and pushed to clients via a new `chat_summary_change` watch event (distinct from `summary_change`, which is bound to `last_turn_summary`), so the popover reads `chat.summary` straight off the loaded `Chat` with no extra query. This is the data source for the popover and per-chat cost UI built in #26649; the popover can consume `chat.summary` once this lands (the field is nullable, so merge order does not matter). ## How it works - **Generation** runs in the existing successful-turn finalize hook, detached from the request so the user's turn is never blocked. A cadence gate generates the first summary after one completed turn, then regenerates every three turns, using the `chats.summary_generated_at` freshness marker. Generation reads compaction-aware history, renders it to a bounded plain-text transcript (short transcripts are skipped), and asks for a 1-3 sentence summary via structured output. Failures never clear an existing summary. - **Staleness** is guarded by `history_version` (mirroring `last_turn_summary`), so a background write racing a newer turn loses while worker lifecycle transitions cannot reject a fresh write. - **Model selection** uses the chat's configured model. ## Deferred to follow-ups - **Cost accounting**: the `chat_messages.cost_source` discriminator and summary/title usage recording were removed from this PR so summary persistence is not blocked by hidden accounting rows advancing `history_version`. Title usage recording stays on main's `InsertChatMessages` path. - **Model override**: deployment-wide summary generation model selection is split into #26803; the base feature always uses the chat model. ## Notes - Migration `000540` adds `chats.summary` and `chats.summary_generated_at`, and recreates `chats_expanded` to expose the new columns. - Root chats only; shared viewers pick up the summary on their next refetch (live watch events are owner-only). Refs #26649 --------- Co-authored-by: Cursor <cursoragent@cursor.com>
58 lines
1.5 KiB
SQL
58 lines
1.5 KiB
SQL
-- Drop the view before the columns it references, then recreate it without
|
|
-- the summary columns, matching the 000549 chats_expanded definition.
|
|
DROP VIEW IF EXISTS chats_expanded;
|
|
|
|
ALTER TABLE chats
|
|
DROP COLUMN summary,
|
|
DROP COLUMN summary_generated_at;
|
|
|
|
CREATE VIEW chats_expanded AS
|
|
SELECT c.id,
|
|
c.owner_id,
|
|
c.workspace_id,
|
|
c.title,
|
|
c.status,
|
|
c.worker_id,
|
|
c.started_at,
|
|
c.heartbeat_at,
|
|
c.created_at,
|
|
c.updated_at,
|
|
c.parent_chat_id,
|
|
c.root_chat_id,
|
|
c.last_model_config_id,
|
|
c.last_reasoning_effort,
|
|
c.archived,
|
|
c.last_error,
|
|
c.mode,
|
|
c.mcp_server_ids,
|
|
c.labels,
|
|
c.build_id,
|
|
c.agent_id,
|
|
c.pin_order,
|
|
c.last_read_message_id,
|
|
c.dynamic_tools,
|
|
c.organization_id,
|
|
c.plan_mode,
|
|
c.client_type,
|
|
c.last_turn_summary,
|
|
c.snapshot_version,
|
|
c.history_version,
|
|
c.queue_version,
|
|
c.generation_attempt,
|
|
c.retry_state,
|
|
c.retry_state_version,
|
|
c.runner_id,
|
|
c.requires_action_deadline_at,
|
|
COALESCE(root.user_acl, c.user_acl) AS user_acl,
|
|
COALESCE(root.group_acl, c.group_acl) AS group_acl,
|
|
owner.username AS owner_username,
|
|
owner.name AS owner_name,
|
|
c.context_aggregate_hash,
|
|
c.context_dirty_since,
|
|
c.context_dirty_resources,
|
|
c.context_error,
|
|
c.compaction_requested_at
|
|
FROM ((chats c
|
|
LEFT JOIN chats root ON ((root.id = COALESCE(c.root_chat_id, c.parent_chat_id))))
|
|
JOIN visible_users owner ON ((owner.id = c.owner_id)));
|