mirror of
https://github.com/multica-ai/multica.git
synced 2026-07-05 13:29:44 +02:00
ListRuntimeUsage was aggregating by DATE(atq.created_at) and filtering on atq.created_at. agent_task_queue.created_at is the enqueue timestamp, which drifts from actual token-production time: a task queued at 23:58 and executed at 00:05 was attributed to yesterday; a task sitting in the queue overnight was counted on the queue day. The ?days=N cutoff also became a rolling window (now() - N) instead of a calendar-day boundary, silently clipping the morning of the earliest day returned. Switch bucket + filter to task_usage.created_at (~= task completion / usage-report time) and snap the since cutoff to start-of-day via DATE_TRUNC. Add a regression test covering both scenarios: cross-midnight task attributes to the day tokens were reported, and the earliest day's pre-cutoff rows are still included.
110 lines
3.1 KiB
Go
110 lines
3.1 KiB
Go
// Code generated by sqlc. DO NOT EDIT.
|
|
// versions:
|
|
// sqlc v1.30.0
|
|
// source: runtime_usage.sql
|
|
|
|
package db
|
|
|
|
import (
|
|
"context"
|
|
|
|
"github.com/jackc/pgx/v5/pgtype"
|
|
)
|
|
|
|
const getRuntimeTaskHourlyActivity = `-- name: GetRuntimeTaskHourlyActivity :many
|
|
SELECT EXTRACT(HOUR FROM started_at)::int AS hour, COUNT(*)::int AS count
|
|
FROM agent_task_queue
|
|
WHERE runtime_id = $1 AND started_at IS NOT NULL
|
|
GROUP BY hour
|
|
ORDER BY hour
|
|
`
|
|
|
|
type GetRuntimeTaskHourlyActivityRow struct {
|
|
Hour int32 `json:"hour"`
|
|
Count int32 `json:"count"`
|
|
}
|
|
|
|
func (q *Queries) GetRuntimeTaskHourlyActivity(ctx context.Context, runtimeID pgtype.UUID) ([]GetRuntimeTaskHourlyActivityRow, error) {
|
|
rows, err := q.db.Query(ctx, getRuntimeTaskHourlyActivity, runtimeID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
items := []GetRuntimeTaskHourlyActivityRow{}
|
|
for rows.Next() {
|
|
var i GetRuntimeTaskHourlyActivityRow
|
|
if err := rows.Scan(&i.Hour, &i.Count); err != nil {
|
|
return nil, err
|
|
}
|
|
items = append(items, i)
|
|
}
|
|
if err := rows.Err(); err != nil {
|
|
return nil, err
|
|
}
|
|
return items, nil
|
|
}
|
|
|
|
const listRuntimeUsage = `-- name: ListRuntimeUsage :many
|
|
SELECT
|
|
DATE(tu.created_at) AS date,
|
|
tu.provider,
|
|
tu.model,
|
|
SUM(tu.input_tokens)::bigint AS input_tokens,
|
|
SUM(tu.output_tokens)::bigint AS output_tokens,
|
|
SUM(tu.cache_read_tokens)::bigint AS cache_read_tokens,
|
|
SUM(tu.cache_write_tokens)::bigint AS cache_write_tokens
|
|
FROM task_usage tu
|
|
JOIN agent_task_queue atq ON atq.id = tu.task_id
|
|
WHERE atq.runtime_id = $1
|
|
AND tu.created_at >= DATE_TRUNC('day', $2::timestamptz)
|
|
GROUP BY DATE(tu.created_at), tu.provider, tu.model
|
|
ORDER BY DATE(tu.created_at) DESC, tu.provider, tu.model
|
|
`
|
|
|
|
type ListRuntimeUsageParams struct {
|
|
RuntimeID pgtype.UUID `json:"runtime_id"`
|
|
Since pgtype.Timestamptz `json:"since"`
|
|
}
|
|
|
|
type ListRuntimeUsageRow struct {
|
|
Date pgtype.Date `json:"date"`
|
|
Provider string `json:"provider"`
|
|
Model string `json:"model"`
|
|
InputTokens int64 `json:"input_tokens"`
|
|
OutputTokens int64 `json:"output_tokens"`
|
|
CacheReadTokens int64 `json:"cache_read_tokens"`
|
|
CacheWriteTokens int64 `json:"cache_write_tokens"`
|
|
}
|
|
|
|
// Bucket by tu.created_at (usage report time, ~= task completion time), not
|
|
// atq.created_at (task enqueue time), so tasks that queue one day and execute
|
|
// the next are attributed to the day tokens were actually produced. The since
|
|
// cutoff is truncated to start-of-day so `days=N` yields full calendar days.
|
|
func (q *Queries) ListRuntimeUsage(ctx context.Context, arg ListRuntimeUsageParams) ([]ListRuntimeUsageRow, error) {
|
|
rows, err := q.db.Query(ctx, listRuntimeUsage, arg.RuntimeID, arg.Since)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
items := []ListRuntimeUsageRow{}
|
|
for rows.Next() {
|
|
var i ListRuntimeUsageRow
|
|
if err := rows.Scan(
|
|
&i.Date,
|
|
&i.Provider,
|
|
&i.Model,
|
|
&i.InputTokens,
|
|
&i.OutputTokens,
|
|
&i.CacheReadTokens,
|
|
&i.CacheWriteTokens,
|
|
); err != nil {
|
|
return nil, err
|
|
}
|
|
items = append(items, i)
|
|
}
|
|
if err := rows.Err(); err != nil {
|
|
return nil, err
|
|
}
|
|
return items, nil
|
|
}
|