feat: remove native chat cost tracking in favor of AI Gateway cost data (#27330)

## Stack Context

This stack makes AI Gateway data and budgets the source of truth for AI
spend controls.

1. Re-back the per-chat cost endpoint with AI Gateway data (#27328,
merged).
2. Remove native chat usage limits (#27329, merged).
3. **This PR, now based on `main`:** remove native chat cost tracking
and its dedicated admin UI.

## Summary

Removes native per-message price calculation, model pricing fields, cost
persistence, aggregate cost queries, and admin cost API types. It also
deletes the Analytics and Spend pages plus their legacy redirects. The
AI Gateway-backed per-chat cost row and compact budget indicators
remain.

The spend documentation is renamed to `spend-management.md` and updated
for the remaining surfaces, group budget APIs, CSV export, upgrade
handling for native pricing and cost history, and the absence of a
deployment-wide spend dashboard. The per-chat cost API documents that
data follows AI Gateway retention and reports zero after all matching
requests are purged.

No schema is dropped in this release. `chat_messages.total_cost_micros`
remains nullable and unwritten so replicas from the previous release can
continue inserting messages during rolling upgrades. #27600 tracks
removal after the compatibility window.

> Mux prepared this PR on Mike's behalf.
This commit is contained in:
Michael Suchacz
2026-08-04 12:27:38 +02:00
committed by GitHub
parent 0b8b48913f
commit 6b8f820493
72 changed files with 159 additions and 5303 deletions
+1 -485
View File
@@ -6992,30 +6992,6 @@ func (q *sqlQuerier) CountChatQueuedMessages(ctx context.Context, chatID uuid.UU
return count, err
}
const countEnabledModelsWithoutPricing = `-- name: CountEnabledModelsWithoutPricing :one
SELECT COUNT(*)::bigint AS count
FROM chat_model_configs
WHERE enabled = TRUE
AND deleted = FALSE
AND (
options->'cost' IS NULL
OR options->'cost' = 'null'::jsonb
OR (
(options->'cost'->>'input_price_per_million_tokens' IS NULL)
AND (options->'cost'->>'output_price_per_million_tokens' IS NULL)
)
)
`
// Counts enabled, non-deleted model configs that lack both input and
// output pricing in their JSONB options.cost configuration.
func (q *sqlQuerier) CountEnabledModelsWithoutPricing(ctx context.Context) (int64, error) {
row := q.db.QueryRowContext(ctx, countEnabledModelsWithoutPricing)
var count int64
err := row.Scan(&count)
return count, err
}
const deleteAllChatHeartbeats = `-- name: DeleteAllChatHeartbeats :exec
DELETE FROM chat_heartbeats WHERE chat_id = $1::uuid
`
@@ -7705,398 +7681,6 @@ func (q *sqlQuerier) GetChatByIDForUpdate(ctx context.Context, id uuid.UUID) (Ch
return i, err
}
const getChatCostPerChat = `-- name: GetChatCostPerChat :many
WITH chat_costs AS (
SELECT
COALESCE(c.root_chat_id, c.id) AS root_chat_id,
COALESCE(SUM(cm.total_cost_micros), 0)::bigint AS total_cost_micros,
COUNT(*) FILTER (
WHERE cm.input_tokens IS NOT NULL
OR cm.output_tokens IS NOT NULL
OR cm.reasoning_tokens IS NOT NULL
OR cm.cache_creation_tokens IS NOT NULL
OR cm.cache_read_tokens IS NOT NULL
)::bigint AS message_count,
COALESCE(SUM(cm.input_tokens), 0)::bigint AS total_input_tokens,
COALESCE(SUM(cm.output_tokens), 0)::bigint AS total_output_tokens,
COALESCE(SUM(cm.cache_read_tokens), 0)::bigint AS total_cache_read_tokens,
COALESCE(SUM(cm.cache_creation_tokens), 0)::bigint AS total_cache_creation_tokens,
COALESCE(SUM(cm.runtime_ms), 0)::bigint AS total_runtime_ms
FROM chat_messages cm
JOIN chats c ON c.id = cm.chat_id
WHERE c.owner_id = $1::uuid
AND cm.role = 'assistant'
AND cm.created_at >= $2::timestamptz
AND cm.created_at < $3::timestamptz
GROUP BY COALESCE(c.root_chat_id, c.id)
)
SELECT
cc.root_chat_id,
COALESCE(rc.title, '') AS chat_title,
cc.total_cost_micros,
cc.message_count,
cc.total_input_tokens,
cc.total_output_tokens,
cc.total_cache_read_tokens,
cc.total_cache_creation_tokens,
cc.total_runtime_ms
FROM chat_costs cc
LEFT JOIN chats rc ON rc.id = cc.root_chat_id
ORDER BY cc.total_cost_micros DESC
`
type GetChatCostPerChatParams struct {
OwnerID uuid.UUID `db:"owner_id" json:"owner_id"`
StartDate time.Time `db:"start_date" json:"start_date"`
EndDate time.Time `db:"end_date" json:"end_date"`
}
type GetChatCostPerChatRow struct {
RootChatID uuid.UUID `db:"root_chat_id" json:"root_chat_id"`
ChatTitle string `db:"chat_title" json:"chat_title"`
TotalCostMicros int64 `db:"total_cost_micros" json:"total_cost_micros"`
MessageCount int64 `db:"message_count" json:"message_count"`
TotalInputTokens int64 `db:"total_input_tokens" json:"total_input_tokens"`
TotalOutputTokens int64 `db:"total_output_tokens" json:"total_output_tokens"`
TotalCacheReadTokens int64 `db:"total_cache_read_tokens" json:"total_cache_read_tokens"`
TotalCacheCreationTokens int64 `db:"total_cache_creation_tokens" json:"total_cache_creation_tokens"`
TotalRuntimeMs int64 `db:"total_runtime_ms" json:"total_runtime_ms"`
}
// Per-root-chat cost breakdown for a single user within a date range.
// Groups by root_chat_id so forked chats roll up under their root.
// Only counts assistant-role messages.
func (q *sqlQuerier) GetChatCostPerChat(ctx context.Context, arg GetChatCostPerChatParams) ([]GetChatCostPerChatRow, error) {
rows, err := q.db.QueryContext(ctx, getChatCostPerChat, arg.OwnerID, arg.StartDate, arg.EndDate)
if err != nil {
return nil, err
}
defer rows.Close()
var items []GetChatCostPerChatRow
for rows.Next() {
var i GetChatCostPerChatRow
if err := rows.Scan(
&i.RootChatID,
&i.ChatTitle,
&i.TotalCostMicros,
&i.MessageCount,
&i.TotalInputTokens,
&i.TotalOutputTokens,
&i.TotalCacheReadTokens,
&i.TotalCacheCreationTokens,
&i.TotalRuntimeMs,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Close(); err != nil {
return nil, err
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const getChatCostPerModel = `-- name: GetChatCostPerModel :many
SELECT
cmc.id AS model_config_id,
cmc.display_name,
COALESCE(ap.type::text, '')::text AS provider,
cmc.model,
COALESCE(SUM(cm.total_cost_micros), 0)::bigint AS total_cost_micros,
COUNT(*) FILTER (
WHERE cm.input_tokens IS NOT NULL
OR cm.output_tokens IS NOT NULL
OR cm.reasoning_tokens IS NOT NULL
OR cm.cache_creation_tokens IS NOT NULL
OR cm.cache_read_tokens IS NOT NULL
)::bigint AS message_count,
COALESCE(SUM(cm.input_tokens), 0)::bigint AS total_input_tokens,
COALESCE(SUM(cm.output_tokens), 0)::bigint AS total_output_tokens,
COALESCE(SUM(cm.cache_read_tokens), 0)::bigint AS total_cache_read_tokens,
COALESCE(SUM(cm.cache_creation_tokens), 0)::bigint AS total_cache_creation_tokens,
COALESCE(SUM(cm.runtime_ms), 0)::bigint AS total_runtime_ms
FROM
chat_messages cm
JOIN
chats c ON c.id = cm.chat_id
JOIN
chat_model_configs cmc ON cmc.id = cm.model_config_id
LEFT JOIN
ai_providers ap ON ap.id = cmc.ai_provider_id
WHERE
c.owner_id = $1::uuid
AND cm.role = 'assistant'
AND cm.created_at >= $2::timestamptz
AND cm.created_at < $3::timestamptz
GROUP BY
cmc.id, cmc.display_name, ap.type, cmc.model
ORDER BY
total_cost_micros DESC
`
type GetChatCostPerModelParams struct {
OwnerID uuid.UUID `db:"owner_id" json:"owner_id"`
StartDate time.Time `db:"start_date" json:"start_date"`
EndDate time.Time `db:"end_date" json:"end_date"`
}
type GetChatCostPerModelRow struct {
ModelConfigID uuid.UUID `db:"model_config_id" json:"model_config_id"`
DisplayName string `db:"display_name" json:"display_name"`
Provider string `db:"provider" json:"provider"`
Model string `db:"model" json:"model"`
TotalCostMicros int64 `db:"total_cost_micros" json:"total_cost_micros"`
MessageCount int64 `db:"message_count" json:"message_count"`
TotalInputTokens int64 `db:"total_input_tokens" json:"total_input_tokens"`
TotalOutputTokens int64 `db:"total_output_tokens" json:"total_output_tokens"`
TotalCacheReadTokens int64 `db:"total_cache_read_tokens" json:"total_cache_read_tokens"`
TotalCacheCreationTokens int64 `db:"total_cache_creation_tokens" json:"total_cache_creation_tokens"`
TotalRuntimeMs int64 `db:"total_runtime_ms" json:"total_runtime_ms"`
}
// Per-model cost breakdown for a single user within a date range.
// Only counts assistant-role messages that have a model_config_id.
func (q *sqlQuerier) GetChatCostPerModel(ctx context.Context, arg GetChatCostPerModelParams) ([]GetChatCostPerModelRow, error) {
rows, err := q.db.QueryContext(ctx, getChatCostPerModel, arg.OwnerID, arg.StartDate, arg.EndDate)
if err != nil {
return nil, err
}
defer rows.Close()
var items []GetChatCostPerModelRow
for rows.Next() {
var i GetChatCostPerModelRow
if err := rows.Scan(
&i.ModelConfigID,
&i.DisplayName,
&i.Provider,
&i.Model,
&i.TotalCostMicros,
&i.MessageCount,
&i.TotalInputTokens,
&i.TotalOutputTokens,
&i.TotalCacheReadTokens,
&i.TotalCacheCreationTokens,
&i.TotalRuntimeMs,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Close(); err != nil {
return nil, err
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const getChatCostPerUser = `-- name: GetChatCostPerUser :many
WITH chat_cost_users AS (
SELECT
c.owner_id AS user_id,
u.username,
u.name,
u.avatar_url,
COALESCE(SUM(cm.total_cost_micros), 0)::bigint AS total_cost_micros,
COUNT(*) FILTER (
WHERE cm.input_tokens IS NOT NULL
OR cm.output_tokens IS NOT NULL
OR cm.reasoning_tokens IS NOT NULL
OR cm.cache_creation_tokens IS NOT NULL
OR cm.cache_read_tokens IS NOT NULL
)::bigint AS message_count,
COUNT(DISTINCT COALESCE(c.root_chat_id, c.id))::bigint AS chat_count,
COALESCE(SUM(cm.input_tokens), 0)::bigint AS total_input_tokens,
COALESCE(SUM(cm.output_tokens), 0)::bigint AS total_output_tokens,
COALESCE(SUM(cm.cache_read_tokens), 0)::bigint AS total_cache_read_tokens,
COALESCE(SUM(cm.cache_creation_tokens), 0)::bigint AS total_cache_creation_tokens,
COALESCE(SUM(cm.runtime_ms), 0)::bigint AS total_runtime_ms
FROM
chat_messages cm
JOIN
chats c ON c.id = cm.chat_id
JOIN
users u ON u.id = c.owner_id
WHERE
cm.role = 'assistant'
AND cm.created_at >= $3::timestamptz
AND cm.created_at < $4::timestamptz
AND (
$5::text = ''
OR u.username ILIKE '%' || $5::text || '%'
OR u.name ILIKE '%' || $5::text || '%'
)
GROUP BY
c.owner_id,
u.username,
u.name,
u.avatar_url
)
SELECT
user_id,
username,
name,
avatar_url,
total_cost_micros,
message_count,
chat_count,
total_input_tokens,
total_output_tokens,
total_cache_read_tokens,
total_cache_creation_tokens,
total_runtime_ms,
COUNT(*) OVER()::bigint AS total_count
FROM
chat_cost_users
ORDER BY
total_cost_micros DESC,
username ASC
LIMIT
$2::int
OFFSET
$1::int
`
type GetChatCostPerUserParams struct {
PageOffset int32 `db:"page_offset" json:"page_offset"`
PageLimit int32 `db:"page_limit" json:"page_limit"`
StartDate time.Time `db:"start_date" json:"start_date"`
EndDate time.Time `db:"end_date" json:"end_date"`
Username string `db:"username" json:"username"`
}
type GetChatCostPerUserRow struct {
UserID uuid.UUID `db:"user_id" json:"user_id"`
Username string `db:"username" json:"username"`
Name string `db:"name" json:"name"`
AvatarURL string `db:"avatar_url" json:"avatar_url"`
TotalCostMicros int64 `db:"total_cost_micros" json:"total_cost_micros"`
MessageCount int64 `db:"message_count" json:"message_count"`
ChatCount int64 `db:"chat_count" json:"chat_count"`
TotalInputTokens int64 `db:"total_input_tokens" json:"total_input_tokens"`
TotalOutputTokens int64 `db:"total_output_tokens" json:"total_output_tokens"`
TotalCacheReadTokens int64 `db:"total_cache_read_tokens" json:"total_cache_read_tokens"`
TotalCacheCreationTokens int64 `db:"total_cache_creation_tokens" json:"total_cache_creation_tokens"`
TotalRuntimeMs int64 `db:"total_runtime_ms" json:"total_runtime_ms"`
TotalCount int64 `db:"total_count" json:"total_count"`
}
// Deployment-wide per-user cost rollup within a date range.
// Only counts assistant-role messages.
func (q *sqlQuerier) GetChatCostPerUser(ctx context.Context, arg GetChatCostPerUserParams) ([]GetChatCostPerUserRow, error) {
rows, err := q.db.QueryContext(ctx, getChatCostPerUser,
arg.PageOffset,
arg.PageLimit,
arg.StartDate,
arg.EndDate,
arg.Username,
)
if err != nil {
return nil, err
}
defer rows.Close()
var items []GetChatCostPerUserRow
for rows.Next() {
var i GetChatCostPerUserRow
if err := rows.Scan(
&i.UserID,
&i.Username,
&i.Name,
&i.AvatarURL,
&i.TotalCostMicros,
&i.MessageCount,
&i.ChatCount,
&i.TotalInputTokens,
&i.TotalOutputTokens,
&i.TotalCacheReadTokens,
&i.TotalCacheCreationTokens,
&i.TotalRuntimeMs,
&i.TotalCount,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Close(); err != nil {
return nil, err
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const getChatCostSummary = `-- name: GetChatCostSummary :one
SELECT
COALESCE(SUM(cm.total_cost_micros), 0)::bigint AS total_cost_micros,
COUNT(*) FILTER (
WHERE cm.total_cost_micros IS NOT NULL
)::bigint AS priced_message_count,
COUNT(*) FILTER (
WHERE cm.total_cost_micros IS NULL
AND (
cm.input_tokens IS NOT NULL
OR cm.output_tokens IS NOT NULL
OR cm.reasoning_tokens IS NOT NULL
OR cm.cache_creation_tokens IS NOT NULL
OR cm.cache_read_tokens IS NOT NULL
)
)::bigint AS unpriced_messages_having_usage_count,
COALESCE(SUM(cm.input_tokens), 0)::bigint AS total_input_tokens,
COALESCE(SUM(cm.output_tokens), 0)::bigint AS total_output_tokens,
COALESCE(SUM(cm.cache_read_tokens), 0)::bigint AS total_cache_read_tokens,
COALESCE(SUM(cm.cache_creation_tokens), 0)::bigint AS total_cache_creation_tokens,
COALESCE(SUM(cm.runtime_ms), 0)::bigint AS total_runtime_ms
FROM
chat_messages cm
JOIN
chats c ON c.id = cm.chat_id
WHERE
c.owner_id = $1::uuid
AND cm.role = 'assistant'
AND cm.created_at >= $2::timestamptz
AND cm.created_at < $3::timestamptz
`
type GetChatCostSummaryParams struct {
OwnerID uuid.UUID `db:"owner_id" json:"owner_id"`
StartDate time.Time `db:"start_date" json:"start_date"`
EndDate time.Time `db:"end_date" json:"end_date"`
}
type GetChatCostSummaryRow struct {
TotalCostMicros int64 `db:"total_cost_micros" json:"total_cost_micros"`
PricedMessageCount int64 `db:"priced_message_count" json:"priced_message_count"`
UnpricedMessagesHavingUsageCount int64 `db:"unpriced_messages_having_usage_count" json:"unpriced_messages_having_usage_count"`
TotalInputTokens int64 `db:"total_input_tokens" json:"total_input_tokens"`
TotalOutputTokens int64 `db:"total_output_tokens" json:"total_output_tokens"`
TotalCacheReadTokens int64 `db:"total_cache_read_tokens" json:"total_cache_read_tokens"`
TotalCacheCreationTokens int64 `db:"total_cache_creation_tokens" json:"total_cache_creation_tokens"`
TotalRuntimeMs int64 `db:"total_runtime_ms" json:"total_runtime_ms"`
}
// Aggregate cost summary for a single user within a date range.
// Only counts assistant-role messages.
func (q *sqlQuerier) GetChatCostSummary(ctx context.Context, arg GetChatCostSummaryParams) (GetChatCostSummaryRow, error) {
row := q.db.QueryRowContext(ctx, getChatCostSummary, arg.OwnerID, arg.StartDate, arg.EndDate)
var i GetChatCostSummaryRow
err := row.Scan(
&i.TotalCostMicros,
&i.PricedMessageCount,
&i.UnpricedMessagesHavingUsageCount,
&i.TotalInputTokens,
&i.TotalOutputTokens,
&i.TotalCacheReadTokens,
&i.TotalCacheCreationTokens,
&i.TotalRuntimeMs,
)
return i, err
}
const getChatDiffStatusByChatID = `-- name: GetChatDiffStatusByChatID :one
SELECT
chat_id, url, pull_request_state, changes_requested, additions, deletions, changed_files, refreshed_at, stale_at, created_at, updated_at, git_branch, git_remote_origin, pull_request_title, pull_request_draft, author_login, author_avatar_url, base_branch, pr_number, commits, approved, reviewer_count, head_branch
@@ -8340,7 +7924,6 @@ SELECT
COALESCE(SUM(cm.reasoning_tokens), 0)::bigint AS total_reasoning_tokens,
COALESCE(SUM(cm.cache_creation_tokens), 0)::bigint AS total_cache_creation_tokens,
COALESCE(SUM(cm.cache_read_tokens), 0)::bigint AS total_cache_read_tokens,
COALESCE(SUM(cm.total_cost_micros), 0)::bigint AS total_cost_micros,
COALESCE(SUM(cm.runtime_ms), 0)::bigint AS total_runtime_ms,
COUNT(DISTINCT cm.model_config_id)::bigint AS distinct_model_count,
COUNT(*) FILTER (WHERE cm.compressed)::bigint AS compressed_message_count
@@ -8362,7 +7945,6 @@ type GetChatMessageSummariesPerChatRow struct {
TotalReasoningTokens int64 `db:"total_reasoning_tokens" json:"total_reasoning_tokens"`
TotalCacheCreationTokens int64 `db:"total_cache_creation_tokens" json:"total_cache_creation_tokens"`
TotalCacheReadTokens int64 `db:"total_cache_read_tokens" json:"total_cache_read_tokens"`
TotalCostMicros int64 `db:"total_cost_micros" json:"total_cost_micros"`
TotalRuntimeMs int64 `db:"total_runtime_ms" json:"total_runtime_ms"`
DistinctModelCount int64 `db:"distinct_model_count" json:"distinct_model_count"`
CompressedMessageCount int64 `db:"compressed_message_count" json:"compressed_message_count"`
@@ -8392,7 +7974,6 @@ func (q *sqlQuerier) GetChatMessageSummariesPerChat(ctx context.Context, created
&i.TotalReasoningTokens,
&i.TotalCacheCreationTokens,
&i.TotalCacheReadTokens,
&i.TotalCostMicros,
&i.TotalRuntimeMs,
&i.DistinctModelCount,
&i.CompressedMessageCount,
@@ -8855,67 +8436,6 @@ func (q *sqlQuerier) GetChatModelConfigsForTelemetry(ctx context.Context) ([]Get
return items, nil
}
const getChatModelUsageCostByChatID = `-- name: GetChatModelUsageCostByChatID :one
WITH RECURSIVE target AS (
SELECT $1::uuid AS chat_id
), subtree AS (
SELECT chat_id AS id FROM target
UNION ALL
SELECT c.id
FROM chats c
JOIN subtree s ON c.parent_chat_id = s.id
), costs AS (
SELECT
COALESCE(SUM(cm.total_cost_micros), 0)::bigint AS total_cost_micros,
COUNT(*) FILTER (
WHERE cm.total_cost_micros IS NOT NULL
)::bigint AS priced_message_count,
COUNT(*) FILTER (
WHERE cm.total_cost_micros IS NULL
AND (
cm.input_tokens IS NOT NULL
OR cm.output_tokens IS NOT NULL
OR cm.reasoning_tokens IS NOT NULL
OR cm.cache_creation_tokens IS NOT NULL
OR cm.cache_read_tokens IS NOT NULL
)
)::bigint AS unpriced_messages_having_usage_count
FROM chat_messages cm
JOIN subtree s ON s.id = cm.chat_id
WHERE cm.role = 'assistant'
)
SELECT
t.chat_id,
costs.total_cost_micros,
costs.priced_message_count,
costs.unpriced_messages_having_usage_count
FROM target t
CROSS JOIN costs
`
type GetChatModelUsageCostByChatIDRow struct {
ChatID uuid.UUID `db:"chat_id" json:"chat_id"`
TotalCostMicros int64 `db:"total_cost_micros" json:"total_cost_micros"`
PricedMessageCount int64 `db:"priced_message_count" json:"priced_message_count"`
UnpricedMessagesHavingUsageCount int64 `db:"unpriced_messages_having_usage_count" json:"unpriced_messages_having_usage_count"`
}
// Assistant-message cost rolled up over the requested chat's subtree: the
// chat itself plus every descendant reachable through parent_chat_id. A
// root chat therefore reports its whole tree, while a subagent chat
// reports only its own spend plus any nested subagents it spawned.
func (q *sqlQuerier) GetChatModelUsageCostByChatID(ctx context.Context, chatID uuid.UUID) (GetChatModelUsageCostByChatIDRow, error) {
row := q.db.QueryRowContext(ctx, getChatModelUsageCostByChatID, chatID)
var i GetChatModelUsageCostByChatIDRow
err := row.Scan(
&i.ChatID,
&i.TotalCostMicros,
&i.PricedMessageCount,
&i.UnpricedMessagesHavingUsageCount,
)
return i, err
}
const getChatQueuedMessageByID = `-- name: GetChatQueuedMessageByID :one
SELECT id, chat_id, content, created_at, model_config_id, position, created_by, reasoning_effort FROM chat_queued_messages
WHERE id = $1::bigint AND chat_id = $2::uuid
@@ -10645,7 +10165,6 @@ inserted AS (
cache_read_tokens,
context_limit,
compressed,
total_cost_micros,
runtime_ms
)
SELECT
@@ -10666,8 +10185,7 @@ inserted AS (
NULLIF(($14::bigint[])[allocated.ord], 0),
NULLIF(($15::bigint[])[allocated.ord], 0),
($16::boolean[])[allocated.ord],
NULLIF(($17::bigint[])[allocated.ord], 0),
NULLIF(($18::bigint[])[allocated.ord], 0)
NULLIF(($17::bigint[])[allocated.ord], 0)
FROM allocated
RETURNING id, chat_id, model_config_id, created_at, role, content, visibility, input_tokens, output_tokens, total_tokens, reasoning_tokens, cache_creation_tokens, cache_read_tokens, context_limit, compressed, created_by, content_version, total_cost_micros, runtime_ms, deleted, provider_response_id, revision, reasoning_effort, search_tsv
)
@@ -10693,7 +10211,6 @@ type InsertChatMessagesParams struct {
CacheReadTokens []int64 `db:"cache_read_tokens" json:"cache_read_tokens"`
ContextLimit []int64 `db:"context_limit" json:"context_limit"`
Compressed []bool `db:"compressed" json:"compressed"`
TotalCostMicros []int64 `db:"total_cost_micros" json:"total_cost_micros"`
RuntimeMs []int64 `db:"runtime_ms" json:"runtime_ms"`
}
@@ -10745,7 +10262,6 @@ func (q *sqlQuerier) InsertChatMessages(ctx context.Context, arg InsertChatMessa
pq.Array(arg.CacheReadTokens),
pq.Array(arg.ContextLimit),
pq.Array(arg.Compressed),
pq.Array(arg.TotalCostMicros),
pq.Array(arg.RuntimeMs),
)
if err != nil {