@sixb/sqlite 0.1.5 → 0.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agents/rows.d.ts +7 -4
- package/dist/agents/rows.d.ts.map +1 -1
- package/dist/agents/runs.d.ts +3 -2
- package/dist/agents/runs.d.ts.map +1 -1
- package/dist/agents/threads.d.ts.map +1 -1
- package/dist/ai-cost-groups.d.ts +5 -0
- package/dist/ai-cost-groups.d.ts.map +1 -0
- package/dist/ai-cost-storage.d.ts +2 -1
- package/dist/ai-cost-storage.d.ts.map +1 -1
- package/dist/ai-limit-storage.d.ts +35 -0
- package/dist/ai-limit-storage.d.ts.map +1 -0
- package/dist/ai-usage-storage.d.ts +1 -0
- package/dist/ai-usage-storage.d.ts.map +1 -1
- package/dist/auth-storage/access-tokens.d.ts +1 -1
- package/dist/auth-storage/access-tokens.d.ts.map +1 -1
- package/dist/auth-storage/auth-storage.d.ts +4 -1
- package/dist/auth-storage/auth-storage.d.ts.map +1 -1
- package/dist/auth-storage/device-authorizations.d.ts +29 -0
- package/dist/auth-storage/device-authorizations.d.ts.map +1 -0
- package/dist/auth-storage/rows.d.ts +19 -1
- package/dist/auth-storage/rows.d.ts.map +1 -1
- package/dist/auth-storage/shared.d.ts +1 -1
- package/dist/auth-storage/shared.d.ts.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1937 -387
- package/dist/index.js.map +20 -17
- package/dist/migrations.d.ts.map +1 -1
- package/dist/ontology-storage/materialization-state.d.ts +7 -3
- package/dist/ontology-storage/materialization-state.d.ts.map +1 -1
- package/dist/ontology-storage/materializations.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/agents/rows.ts +36 -9
- package/src/agents/runs.ts +152 -13
- package/src/agents/threads.ts +2 -17
- package/src/ai-cost-groups.ts +100 -0
- package/src/ai-cost-storage.ts +67 -25
- package/src/ai-limit-storage.ts +981 -0
- package/src/ai-usage-storage.ts +24 -1
- package/src/auth-storage/access-tokens.ts +77 -68
- package/src/auth-storage/auth-storage.ts +80 -1
- package/src/auth-storage/device-authorizations.ts +153 -0
- package/src/auth-storage/rows.ts +41 -0
- package/src/auth-storage/shared.ts +1 -0
- package/src/index.ts +6 -0
- package/src/migrations/029-model-accounting.sql +79 -0
- package/src/migrations/030-ai-usage-limits.sql +100 -0
- package/src/migrations/031-subagent-runs.sql +231 -0
- package/src/migrations/032-conversation-run-spec.sql +78 -0
- package/src/migrations/033-retire-agent-definitions.sql +89 -0
- package/src/migrations/034-device-authorizations.sql +22 -0
- package/src/migrations.ts +18 -0
- package/src/ontology-storage/materialization-state.ts +53 -33
- package/src/ontology-storage/materializations.ts +4 -5
- package/src/workflow-run-storage.ts +8 -8
package/src/ai-cost-storage.ts
CHANGED
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
parseAiModelCallCostDetails,
|
|
11
11
|
toAccountingItem,
|
|
12
12
|
} from "@sixb/core/internal/ai-cost-storage-provider"
|
|
13
|
+
import { normalizeModelProviderIds } from "@sixb/core/models"
|
|
13
14
|
import type { ReadonlyJsonObject } from "@sixb/core/storage"
|
|
14
15
|
import {
|
|
15
16
|
type AiAccountingOverview,
|
|
@@ -20,9 +21,13 @@ import {
|
|
|
20
21
|
type AiModelCallUsageRecord,
|
|
21
22
|
type ListAiModelCallAccountingInput,
|
|
22
23
|
type ListAiModelCallAccountingResult,
|
|
24
|
+
type ListAiModelCallGroupsInput,
|
|
25
|
+
type ListAiModelCallGroupsResult,
|
|
23
26
|
type QueryAiAccountingOverviewInput,
|
|
24
27
|
type SummarizeAiCostExecutionsInput,
|
|
25
28
|
} from "@sixb/core/storage"
|
|
29
|
+
import { listAiModelCallGroups } from "./ai-cost-groups"
|
|
30
|
+
import { requestedReasoningFromRow } from "./ai-usage-storage"
|
|
26
31
|
import { isUniqueConstraintError } from "./storage-errors"
|
|
27
32
|
import { runImmediateTransaction, type SqliteStoreConnection } from "./transactions"
|
|
28
33
|
|
|
@@ -30,6 +35,12 @@ import { runImmediateTransaction, type SqliteStoreConnection } from "./transacti
|
|
|
30
35
|
export class SqliteAiCostStorage implements AiCostStorage {
|
|
31
36
|
constructor(private readonly connection: SqliteStoreConnection) {}
|
|
32
37
|
|
|
38
|
+
async listModelCallGroups(
|
|
39
|
+
input: ListAiModelCallGroupsInput
|
|
40
|
+
): Promise<ListAiModelCallGroupsResult> {
|
|
41
|
+
return listAiModelCallGroups(this.connection, input)
|
|
42
|
+
}
|
|
43
|
+
|
|
33
44
|
async recordModelCallCost(input: AiModelCallCostRecord): Promise<void> {
|
|
34
45
|
const record = normalizeAiModelCallCostRecord(input)
|
|
35
46
|
runImmediateTransaction(this.connection.db, () => {
|
|
@@ -176,13 +187,15 @@ const SQLITE_ACCOUNTING_LIST_COUNT_SQL = `
|
|
|
176
187
|
const SQLITE_ACCOUNTING_LIST_PAGE_SQL = `
|
|
177
188
|
SELECT usage.*,
|
|
178
189
|
CASE
|
|
179
|
-
WHEN direct_agent.
|
|
190
|
+
WHEN direct_agent.kind = 'conversation' THEN 'agent'
|
|
191
|
+
WHEN direct_agent.kind = 'subagent' THEN 'subagent'
|
|
180
192
|
WHEN workflow_agent.node_run_id IS NOT NULL THEN 'workflowAgent'
|
|
181
193
|
ELSE NULL
|
|
182
194
|
END AS attribution_kind,
|
|
183
|
-
|
|
195
|
+
workflow_node.node_id AS attribution_agent_step_id,
|
|
184
196
|
direct_agent.id AS attribution_agent_run_id,
|
|
185
197
|
direct_agent.thread_id AS attribution_thread_id,
|
|
198
|
+
direct_agent.parent_run_id AS attribution_parent_run_id,
|
|
186
199
|
workflow_agent.node_run_id AS attribution_node_run_id,
|
|
187
200
|
workflow_node.workflow_id AS attribution_workflow_id,
|
|
188
201
|
workflow_node.workflow_run_id AS attribution_workflow_run_id,
|
|
@@ -231,7 +244,12 @@ const SQLITE_ACCOUNTING_OVERVIEW_SQL = `
|
|
|
231
244
|
usage.text_output_tokens,
|
|
232
245
|
usage.reasoning_output_tokens,
|
|
233
246
|
usage.reporting_status,
|
|
234
|
-
|
|
247
|
+
CASE
|
|
248
|
+
WHEN direct_agent.kind = 'conversation' THEN 'agent'
|
|
249
|
+
WHEN workflow_agent.node_run_id IS NOT NULL THEN 'workflowAgent'
|
|
250
|
+
ELSE NULL
|
|
251
|
+
END AS attribution_agent_kind,
|
|
252
|
+
workflow_node.node_id AS attribution_agent_step_id,
|
|
235
253
|
workflow_node.workflow_id AS attribution_workflow_id,
|
|
236
254
|
CASE
|
|
237
255
|
WHEN cost.status = 'rated' THEN 'rated'
|
|
@@ -256,11 +274,11 @@ const SQLITE_ACCOUNTING_OVERVIEW_SQL = `
|
|
|
256
274
|
AND (? IS NULL OR usage.provider_id = ?)
|
|
257
275
|
AND (? IS NULL OR usage.requested_model_id = ?)
|
|
258
276
|
), expanded AS (
|
|
259
|
-
SELECT 'totals' AS dimension, NULL AS key_1, NULL AS key_2, NULL AS bucket_start,
|
|
277
|
+
SELECT 'totals' AS dimension, NULL AS key_1, NULL AS key_2, NULL AS key_3, NULL AS bucket_start,
|
|
260
278
|
classified.*
|
|
261
279
|
FROM classified
|
|
262
280
|
UNION ALL
|
|
263
|
-
SELECT 'series', NULL, NULL,
|
|
281
|
+
SELECT 'series', NULL, NULL, NULL,
|
|
264
282
|
CASE ?
|
|
265
283
|
WHEN 'hour' THEN strftime('%Y-%m-%dT%H:00:00.000Z', occurred_at)
|
|
266
284
|
WHEN 'day' THEN strftime('%Y-%m-%dT00:00:00.000Z', occurred_at)
|
|
@@ -273,17 +291,18 @@ const SQLITE_ACCOUNTING_OVERVIEW_SQL = `
|
|
|
273
291
|
classified.*
|
|
274
292
|
FROM classified
|
|
275
293
|
UNION ALL
|
|
276
|
-
SELECT 'model', provider_id, requested_model_id, NULL, classified.* FROM classified
|
|
294
|
+
SELECT 'model', provider_id, requested_model_id, NULL, NULL, classified.* FROM classified
|
|
277
295
|
UNION ALL
|
|
278
|
-
SELECT 'agent',
|
|
279
|
-
FROM classified WHERE
|
|
296
|
+
SELECT 'agent', attribution_agent_kind, attribution_workflow_id, attribution_agent_step_id, NULL, classified.*
|
|
297
|
+
FROM classified WHERE attribution_agent_kind IS NOT NULL
|
|
280
298
|
UNION ALL
|
|
281
|
-
SELECT 'workflow', attribution_workflow_id, NULL, NULL, classified.*
|
|
299
|
+
SELECT 'workflow', attribution_workflow_id, NULL, NULL, NULL, classified.*
|
|
282
300
|
FROM classified WHERE attribution_workflow_id IS NOT NULL
|
|
283
301
|
)
|
|
284
302
|
SELECT dimension,
|
|
285
303
|
key_1,
|
|
286
304
|
key_2,
|
|
305
|
+
key_3,
|
|
287
306
|
bucket_start,
|
|
288
307
|
amount_currency,
|
|
289
308
|
CAST(COUNT(*) AS TEXT) AS model_call_count,
|
|
@@ -313,7 +332,7 @@ const SQLITE_ACCOUNTING_OVERVIEW_SQL = `
|
|
|
313
332
|
CAST(SUM((amount_nanos / 1000000) % 1000000) AS TEXT) AS amount_middle,
|
|
314
333
|
CAST(SUM(amount_nanos % 1000000) AS TEXT) AS amount_low
|
|
315
334
|
FROM expanded
|
|
316
|
-
GROUP BY dimension, key_1, key_2, bucket_start, amount_currency
|
|
335
|
+
GROUP BY dimension, key_1, key_2, key_3, bucket_start, amount_currency
|
|
317
336
|
`
|
|
318
337
|
|
|
319
338
|
function accountingListFilterParameters(
|
|
@@ -355,6 +374,7 @@ interface UsageRow {
|
|
|
355
374
|
readonly call_id: string
|
|
356
375
|
readonly provider_id: string
|
|
357
376
|
readonly requested_model_id: string
|
|
377
|
+
readonly requested_reasoning: string | null
|
|
358
378
|
readonly response_model_id: string | null
|
|
359
379
|
readonly response_id: string
|
|
360
380
|
readonly input_tokens: number | null
|
|
@@ -367,15 +387,17 @@ interface UsageRow {
|
|
|
367
387
|
readonly reasoning_output_tokens: number | null
|
|
368
388
|
readonly reporting_status: AiModelCallUsageRecord["usage"]["reportingStatus"]
|
|
369
389
|
readonly raw_usage: string | null
|
|
390
|
+
readonly provider_ids: string | null
|
|
370
391
|
readonly occurred_at: string
|
|
371
392
|
readonly recorded_at: string
|
|
372
393
|
}
|
|
373
394
|
|
|
374
395
|
interface JoinedRow extends UsageRow {
|
|
375
|
-
readonly attribution_kind: "agent" | "workflowAgent" | null
|
|
376
|
-
readonly
|
|
396
|
+
readonly attribution_kind: "agent" | "subagent" | "workflowAgent" | null
|
|
397
|
+
readonly attribution_agent_step_id: string | null
|
|
377
398
|
readonly attribution_agent_run_id: string | null
|
|
378
399
|
readonly attribution_thread_id: string | null
|
|
400
|
+
readonly attribution_parent_run_id: string | null
|
|
379
401
|
readonly attribution_node_run_id: string | null
|
|
380
402
|
readonly attribution_workflow_id: string | null
|
|
381
403
|
readonly attribution_workflow_run_id: string | null
|
|
@@ -394,6 +416,7 @@ interface AggregateRow {
|
|
|
394
416
|
readonly dimension: AiAccountingAggregateFragment["dimension"]
|
|
395
417
|
readonly key_1: string | null
|
|
396
418
|
readonly key_2: string | null
|
|
419
|
+
readonly key_3: string | null
|
|
397
420
|
readonly bucket_start: string | null
|
|
398
421
|
readonly amount_currency: string | null
|
|
399
422
|
readonly model_call_count: string
|
|
@@ -436,7 +459,12 @@ function aggregateFragmentFromRow(row: AggregateRow): AiAccountingAggregateFragm
|
|
|
436
459
|
row.dimension === "model"
|
|
437
460
|
? { providerId: required(row.key_1), modelId: required(row.key_2) }
|
|
438
461
|
: row.dimension === "agent"
|
|
439
|
-
? {
|
|
462
|
+
? {
|
|
463
|
+
agentKind: required(row.key_1) as "agent" | "workflowAgent",
|
|
464
|
+
...(row.key_1 === "workflowAgent"
|
|
465
|
+
? { workflowId: required(row.key_2), agentStepId: required(row.key_3) }
|
|
466
|
+
: {}),
|
|
467
|
+
}
|
|
440
468
|
: row.dimension === "workflow"
|
|
441
469
|
? { workflowId: required(row.key_1) }
|
|
442
470
|
: row.dimension === "series"
|
|
@@ -510,17 +538,22 @@ function accountingItemFromRow(row: JoinedRow): AiAccountingRecordSetItem {
|
|
|
510
538
|
: row.attribution_kind === "agent"
|
|
511
539
|
? {
|
|
512
540
|
kind: "agent" as const,
|
|
513
|
-
agentId: required(row.attribution_agent_id),
|
|
514
541
|
agentRunId: required(row.attribution_agent_run_id),
|
|
515
542
|
threadId: required(row.attribution_thread_id),
|
|
516
543
|
}
|
|
517
|
-
:
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
544
|
+
: row.attribution_kind === "subagent"
|
|
545
|
+
? {
|
|
546
|
+
kind: "subagent" as const,
|
|
547
|
+
subagentRunId: required(row.attribution_agent_run_id),
|
|
548
|
+
parentRunId: required(row.attribution_parent_run_id),
|
|
549
|
+
}
|
|
550
|
+
: {
|
|
551
|
+
kind: "workflowAgent" as const,
|
|
552
|
+
agentStepId: required(row.attribution_agent_step_id),
|
|
553
|
+
nodeRunId: required(row.attribution_node_run_id),
|
|
554
|
+
workflowId: required(row.attribution_workflow_id),
|
|
555
|
+
workflowRunId: required(row.attribution_workflow_run_id),
|
|
556
|
+
}
|
|
524
557
|
return {
|
|
525
558
|
usage,
|
|
526
559
|
...(attribution ? { attribution } : {}),
|
|
@@ -537,7 +570,13 @@ function usageFromRow(row: UsageRow, requesterGroupIds: readonly string[]): AiMo
|
|
|
537
570
|
callId: row.call_id,
|
|
538
571
|
requesterGroupIds,
|
|
539
572
|
providerId: row.provider_id,
|
|
573
|
+
...(row.provider_ids === null
|
|
574
|
+
? {}
|
|
575
|
+
: { providerIds: normalizeModelProviderIds(JSON.parse(row.provider_ids)) }),
|
|
540
576
|
requestedModelId: row.requested_model_id,
|
|
577
|
+
...(row.requested_reasoning === null
|
|
578
|
+
? {}
|
|
579
|
+
: { requestedReasoning: requestedReasoningFromRow(row.requested_reasoning) }),
|
|
541
580
|
...(row.response_model_id === null ? {} : { responseModelId: row.response_model_id }),
|
|
542
581
|
responseId: row.response_id,
|
|
543
582
|
usage: {
|
|
@@ -610,14 +649,15 @@ function costRecord(input: {
|
|
|
610
649
|
ratedAt: string
|
|
611
650
|
}): AiModelCallCostRecord {
|
|
612
651
|
const details = parseAiModelCallCostDetails(input.details)
|
|
652
|
+
const priceSource =
|
|
653
|
+
details.priceSource === undefined
|
|
654
|
+
? undefined
|
|
655
|
+
: { ...details.priceSource, observedAt: new Date(details.priceSource.observedAt) }
|
|
613
656
|
const base = {
|
|
657
|
+
...(details.estimate === undefined ? {} : { estimate: details.estimate }),
|
|
614
658
|
projectId: input.projectId,
|
|
615
659
|
usageRecordId: input.usageId,
|
|
616
660
|
pricingContext: details.pricingContext,
|
|
617
|
-
priceSource: {
|
|
618
|
-
...details.priceSource,
|
|
619
|
-
observedAt: new Date(details.priceSource.observedAt),
|
|
620
|
-
},
|
|
621
661
|
ratedAt: new Date(input.ratedAt),
|
|
622
662
|
}
|
|
623
663
|
if (input.status === "rated") {
|
|
@@ -625,6 +665,7 @@ function costRecord(input: {
|
|
|
625
665
|
...base,
|
|
626
666
|
status: "rated",
|
|
627
667
|
billingIdentity: { providerId: required(input.providerId), modelId: required(input.modelId) },
|
|
668
|
+
priceSource: required(priceSource),
|
|
628
669
|
money: { currency: required(input.currency), amountNanos: required(input.amountNanos) },
|
|
629
670
|
components: required(details.components),
|
|
630
671
|
})
|
|
@@ -635,6 +676,7 @@ function costRecord(input: {
|
|
|
635
676
|
...(input.providerId && input.modelId
|
|
636
677
|
? { billingIdentity: { providerId: input.providerId, modelId: input.modelId } }
|
|
637
678
|
: {}),
|
|
679
|
+
...(priceSource === undefined ? {} : { priceSource }),
|
|
638
680
|
reason: required(input.reason) as Extract<
|
|
639
681
|
AiModelCallCostRecord,
|
|
640
682
|
{ status: "unpriceable" }
|