mirror of
https://github.com/coder/coder.git
synced 2026-06-03 04:58:23 +00:00
206 lines
6.9 KiB
SQL
206 lines
6.9 KiB
SQL
-- name: InsertChatDebugRun :one
|
|
INSERT INTO chat_debug_runs (
|
|
chat_id,
|
|
root_chat_id,
|
|
parent_chat_id,
|
|
model_config_id,
|
|
trigger_message_id,
|
|
history_tip_message_id,
|
|
kind,
|
|
status,
|
|
provider,
|
|
model,
|
|
summary,
|
|
started_at,
|
|
updated_at,
|
|
finished_at
|
|
)
|
|
VALUES (
|
|
@chat_id::uuid,
|
|
sqlc.narg('root_chat_id')::uuid,
|
|
sqlc.narg('parent_chat_id')::uuid,
|
|
sqlc.narg('model_config_id')::uuid,
|
|
sqlc.narg('trigger_message_id')::bigint,
|
|
sqlc.narg('history_tip_message_id')::bigint,
|
|
@kind::text,
|
|
@status::text,
|
|
sqlc.narg('provider')::text,
|
|
sqlc.narg('model')::text,
|
|
COALESCE(sqlc.narg('summary')::jsonb, '{}'::jsonb),
|
|
COALESCE(sqlc.narg('started_at')::timestamptz, NOW()),
|
|
COALESCE(sqlc.narg('updated_at')::timestamptz, NOW()),
|
|
sqlc.narg('finished_at')::timestamptz
|
|
)
|
|
RETURNING *;
|
|
|
|
-- name: UpdateChatDebugRun :one
|
|
-- Uses COALESCE so that passing NULL from Go means "keep the
|
|
-- existing value." This is intentional: debug rows follow a
|
|
-- write-once-finalize pattern where fields are set at creation
|
|
-- or finalization and never cleared back to NULL.
|
|
UPDATE chat_debug_runs
|
|
SET
|
|
root_chat_id = COALESCE(sqlc.narg('root_chat_id')::uuid, root_chat_id),
|
|
parent_chat_id = COALESCE(sqlc.narg('parent_chat_id')::uuid, parent_chat_id),
|
|
model_config_id = COALESCE(sqlc.narg('model_config_id')::uuid, model_config_id),
|
|
trigger_message_id = COALESCE(sqlc.narg('trigger_message_id')::bigint, trigger_message_id),
|
|
history_tip_message_id = COALESCE(sqlc.narg('history_tip_message_id')::bigint, history_tip_message_id),
|
|
status = COALESCE(sqlc.narg('status')::text, status),
|
|
provider = COALESCE(sqlc.narg('provider')::text, provider),
|
|
model = COALESCE(sqlc.narg('model')::text, model),
|
|
summary = COALESCE(sqlc.narg('summary')::jsonb, summary),
|
|
finished_at = COALESCE(sqlc.narg('finished_at')::timestamptz, finished_at),
|
|
updated_at = NOW()
|
|
WHERE id = @id::uuid
|
|
AND chat_id = @chat_id::uuid
|
|
RETURNING *;
|
|
|
|
-- name: InsertChatDebugStep :one
|
|
INSERT INTO chat_debug_steps (
|
|
run_id,
|
|
chat_id,
|
|
step_number,
|
|
operation,
|
|
status,
|
|
history_tip_message_id,
|
|
assistant_message_id,
|
|
normalized_request,
|
|
normalized_response,
|
|
usage,
|
|
attempts,
|
|
error,
|
|
metadata,
|
|
started_at,
|
|
updated_at,
|
|
finished_at
|
|
)
|
|
SELECT
|
|
@run_id::uuid,
|
|
run.chat_id,
|
|
@step_number::int,
|
|
@operation::text,
|
|
@status::text,
|
|
sqlc.narg('history_tip_message_id')::bigint,
|
|
sqlc.narg('assistant_message_id')::bigint,
|
|
COALESCE(sqlc.narg('normalized_request')::jsonb, '{}'::jsonb),
|
|
sqlc.narg('normalized_response')::jsonb,
|
|
sqlc.narg('usage')::jsonb,
|
|
COALESCE(sqlc.narg('attempts')::jsonb, '[]'::jsonb),
|
|
sqlc.narg('error')::jsonb,
|
|
COALESCE(sqlc.narg('metadata')::jsonb, '{}'::jsonb),
|
|
COALESCE(sqlc.narg('started_at')::timestamptz, NOW()),
|
|
COALESCE(sqlc.narg('updated_at')::timestamptz, NOW()),
|
|
sqlc.narg('finished_at')::timestamptz
|
|
FROM chat_debug_runs run
|
|
WHERE run.id = @run_id::uuid
|
|
AND run.chat_id = @chat_id::uuid
|
|
RETURNING *;
|
|
|
|
-- name: UpdateChatDebugStep :one
|
|
-- Uses COALESCE so that passing NULL from Go means "keep the
|
|
-- existing value." This is intentional: debug rows follow a
|
|
-- write-once-finalize pattern where fields are set at creation
|
|
-- or finalization and never cleared back to NULL.
|
|
UPDATE chat_debug_steps
|
|
SET
|
|
status = COALESCE(sqlc.narg('status')::text, status),
|
|
history_tip_message_id = COALESCE(sqlc.narg('history_tip_message_id')::bigint, history_tip_message_id),
|
|
assistant_message_id = COALESCE(sqlc.narg('assistant_message_id')::bigint, assistant_message_id),
|
|
normalized_request = COALESCE(sqlc.narg('normalized_request')::jsonb, normalized_request),
|
|
normalized_response = COALESCE(sqlc.narg('normalized_response')::jsonb, normalized_response),
|
|
usage = COALESCE(sqlc.narg('usage')::jsonb, usage),
|
|
attempts = COALESCE(sqlc.narg('attempts')::jsonb, attempts),
|
|
error = COALESCE(sqlc.narg('error')::jsonb, error),
|
|
metadata = COALESCE(sqlc.narg('metadata')::jsonb, metadata),
|
|
finished_at = COALESCE(sqlc.narg('finished_at')::timestamptz, finished_at),
|
|
updated_at = NOW()
|
|
WHERE id = @id::uuid
|
|
AND chat_id = @chat_id::uuid
|
|
RETURNING *;
|
|
|
|
-- name: GetChatDebugRunsByChatID :many
|
|
-- Returns the most recent debug runs for a chat, ordered newest-first.
|
|
-- Callers must supply an explicit limit to avoid unbounded result sets.
|
|
SELECT *
|
|
FROM chat_debug_runs
|
|
WHERE chat_id = @chat_id::uuid
|
|
ORDER BY started_at DESC, id DESC
|
|
LIMIT @limit_val::int;
|
|
|
|
-- name: GetChatDebugRunByID :one
|
|
SELECT *
|
|
FROM chat_debug_runs
|
|
WHERE id = @id::uuid;
|
|
|
|
-- name: GetChatDebugStepsByRunID :many
|
|
SELECT *
|
|
FROM chat_debug_steps
|
|
WHERE run_id = @run_id::uuid
|
|
ORDER BY step_number ASC, started_at ASC;
|
|
|
|
-- name: DeleteChatDebugDataByChatID :execrows
|
|
DELETE FROM chat_debug_runs
|
|
WHERE chat_id = @chat_id::uuid;
|
|
|
|
-- name: DeleteChatDebugDataAfterMessageID :execrows
|
|
WITH affected_runs AS (
|
|
SELECT DISTINCT run.id
|
|
FROM chat_debug_runs run
|
|
WHERE run.chat_id = @chat_id::uuid
|
|
AND (
|
|
run.history_tip_message_id > @message_id::bigint
|
|
OR run.trigger_message_id > @message_id::bigint
|
|
)
|
|
|
|
UNION
|
|
|
|
SELECT DISTINCT step.run_id AS id
|
|
FROM chat_debug_steps step
|
|
WHERE step.chat_id = @chat_id::uuid
|
|
AND (
|
|
step.assistant_message_id > @message_id::bigint
|
|
OR step.history_tip_message_id > @message_id::bigint
|
|
)
|
|
)
|
|
DELETE FROM chat_debug_runs
|
|
WHERE chat_id = @chat_id::uuid
|
|
AND id IN (SELECT id FROM affected_runs);
|
|
|
|
-- name: FinalizeStaleChatDebugRows :one
|
|
-- Marks orphaned in-progress rows as interrupted so they do not stay
|
|
-- in a non-terminal state forever. The NOT IN list must match the
|
|
-- terminal statuses defined by ChatDebugStatus in codersdk/chats.go.
|
|
--
|
|
-- The steps CTE also catches steps whose parent run was just finalized
|
|
-- (via run_id IN), because PostgreSQL data-modifying CTEs share the
|
|
-- same snapshot and cannot see each other's row updates. Without this,
|
|
-- a step with a recent updated_at would survive its run's finalization
|
|
-- and remain in 'in_progress' state permanently.
|
|
WITH finalized_runs AS (
|
|
UPDATE chat_debug_runs
|
|
SET
|
|
status = 'interrupted',
|
|
updated_at = NOW(),
|
|
finished_at = NOW()
|
|
WHERE updated_at < @updated_before::timestamptz
|
|
AND finished_at IS NULL
|
|
AND status NOT IN ('completed', 'error', 'interrupted')
|
|
RETURNING id
|
|
), finalized_steps AS (
|
|
UPDATE chat_debug_steps
|
|
SET
|
|
status = 'interrupted',
|
|
updated_at = NOW(),
|
|
finished_at = NOW()
|
|
WHERE (
|
|
updated_at < @updated_before::timestamptz
|
|
OR run_id IN (SELECT id FROM finalized_runs)
|
|
)
|
|
AND finished_at IS NULL
|
|
AND status NOT IN ('completed', 'error', 'interrupted')
|
|
RETURNING 1
|
|
)
|
|
SELECT
|
|
(SELECT COUNT(*) FROM finalized_runs)::bigint AS runs_finalized,
|
|
(SELECT COUNT(*) FROM finalized_steps)::bigint AS steps_finalized;
|