@sixb/sqlite 0.1.25 → 0.2.0
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/agent-storage.d.ts +8 -3
- package/dist/agents/agent-storage.d.ts.map +1 -1
- package/dist/agents/computers.d.ts +22 -0
- package/dist/agents/computers.d.ts.map +1 -0
- package/dist/agents/messages.d.ts.map +1 -1
- package/dist/agents/rows.d.ts +6 -0
- package/dist/agents/rows.d.ts.map +1 -1
- package/dist/agents/runs.d.ts +2 -1
- package/dist/agents/runs.d.ts.map +1 -1
- package/dist/agents/threads.d.ts +4 -1
- package/dist/agents/threads.d.ts.map +1 -1
- package/dist/agents/token-rates.d.ts +13 -0
- package/dist/agents/token-rates.d.ts.map +1 -0
- package/dist/ai-accounting-filters.d.ts +14 -0
- package/dist/ai-accounting-filters.d.ts.map +1 -0
- package/dist/ai-cost-groups.d.ts +1 -1
- package/dist/ai-cost-groups.d.ts.map +1 -1
- package/dist/ai-cost-storage.d.ts.map +1 -1
- package/dist/index.js +465 -63
- package/dist/index.js.map +17 -14
- package/dist/migrations.d.ts.map +1 -1
- package/dist/objects/query-compiler.d.ts.map +1 -1
- package/dist/ontology-storage/commits.d.ts.map +1 -1
- package/dist/ontology-storage/materializations.d.ts +2 -1
- package/dist/ontology-storage/materializations.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/agents/agent-storage.ts +10 -3
- package/src/agents/computers.ts +112 -0
- package/src/agents/messages.ts +13 -0
- package/src/agents/rows.ts +14 -0
- package/src/agents/runs.ts +52 -4
- package/src/agents/threads.ts +108 -4
- package/src/agents/token-rates.ts +90 -0
- package/src/ai-accounting-filters.ts +51 -0
- package/src/ai-cost-groups.ts +52 -14
- package/src/ai-cost-storage.ts +101 -39
- package/src/migrations/080-agent-run-cancel-requests.sql +3 -0
- package/src/migrations/081-agent-thread-runs-on.sql +4 -0
- package/src/migrations/082-agent-token-rates.sql +17 -0
- package/src/migrations/083-agent-computer-sessions.sql +27 -0
- package/src/migrations.ts +12 -0
- package/src/objects/query-compiler.ts +44 -28
- package/src/ontology-storage/commits.ts +9 -0
- package/src/ontology-storage/materializations.ts +18 -1
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
import {
|
|
10
10
|
hasVectorProfile,
|
|
11
11
|
isVectorProfileQuery,
|
|
12
|
+
linkEndpointObjectTypeIds,
|
|
12
13
|
normalizeVector,
|
|
13
14
|
vectorSearchCandidateLimit,
|
|
14
15
|
} from "@sixb/core/internal/query"
|
|
@@ -190,14 +191,7 @@ function compileObjectQueryInternal(
|
|
|
190
191
|
case "page":
|
|
191
192
|
return compilePage(projectId, query.input, query.pageSize, query.pageToken, ctx)
|
|
192
193
|
case "traverse":
|
|
193
|
-
return compileTraversal(
|
|
194
|
-
projectId,
|
|
195
|
-
query.input,
|
|
196
|
-
query.linkId,
|
|
197
|
-
query.direction,
|
|
198
|
-
query.sourceObjectTypeId,
|
|
199
|
-
ctx
|
|
200
|
-
)
|
|
194
|
+
return compileTraversal(projectId, query, ctx)
|
|
201
195
|
case "set":
|
|
202
196
|
return compileSet(projectId, query.op, query.inputs, ctx)
|
|
203
197
|
case "project":
|
|
@@ -571,14 +565,13 @@ function compilePage(
|
|
|
571
565
|
|
|
572
566
|
function compileTraversal(
|
|
573
567
|
projectId: string,
|
|
574
|
-
|
|
575
|
-
linkId: string,
|
|
576
|
-
direction: "outgoing" | "incoming",
|
|
577
|
-
sourceObjectTypeId: string | undefined,
|
|
568
|
+
traversal: Extract<ObjectQuery, { kind: "traverse" }>,
|
|
578
569
|
ctx: CompileContext
|
|
579
570
|
): CompiledObjectQuery {
|
|
580
|
-
const
|
|
571
|
+
const { linkId, direction, sourceObjectTypeId } = traversal
|
|
572
|
+
const input = compileObjectQueryInternal(projectId, traversal.input, exactContext(ctx))
|
|
581
573
|
const outputAlias = direction === "outgoing" ? "target_object" : "source_object"
|
|
574
|
+
const endpointType = compileEndpointTypes(outputAlias, linkEndpointObjectTypeIds(traversal))
|
|
582
575
|
const joinSql =
|
|
583
576
|
direction === "outgoing"
|
|
584
577
|
? `
|
|
@@ -591,6 +584,7 @@ function compileTraversal(
|
|
|
591
584
|
ON target_object.project_id = edge.project_id
|
|
592
585
|
AND target_object.object_type_id = edge.target_type_id
|
|
593
586
|
AND target_object.primary_id = edge.target_id
|
|
587
|
+
${endpointType.sql}
|
|
594
588
|
`
|
|
595
589
|
: `
|
|
596
590
|
JOIN ${ctx.source.linksTable} AS edge
|
|
@@ -602,6 +596,7 @@ function compileTraversal(
|
|
|
602
596
|
ON source_object.project_id = edge.project_id
|
|
603
597
|
AND source_object.object_type_id = edge.source_type_id
|
|
604
598
|
AND source_object.primary_id = edge.source_id
|
|
599
|
+
${endpointType.sql}
|
|
605
600
|
`
|
|
606
601
|
const order = compileOrder(identityOrderFields())
|
|
607
602
|
const qualifiedOrder = compileOrder(identityOrderFields(), outputAlias)
|
|
@@ -614,7 +609,8 @@ function compileTraversal(
|
|
|
614
609
|
const args = [
|
|
615
610
|
...input.args,
|
|
616
611
|
linkId,
|
|
617
|
-
...(
|
|
612
|
+
...(direction === "incoming" && sourceObjectTypeId !== undefined ? [sourceObjectTypeId] : []),
|
|
613
|
+
...endpointType.args,
|
|
618
614
|
...qualifiedOrder.args,
|
|
619
615
|
]
|
|
620
616
|
|
|
@@ -630,6 +626,19 @@ function compileTraversal(
|
|
|
630
626
|
}
|
|
631
627
|
}
|
|
632
628
|
|
|
629
|
+
/** Only the types the ontology says this link can reach. */
|
|
630
|
+
function compileEndpointTypes(
|
|
631
|
+
alias: string,
|
|
632
|
+
objectTypeIds: readonly string[] | undefined
|
|
633
|
+
): CompiledPredicate {
|
|
634
|
+
if (!objectTypeIds?.length) return { sql: "", args: [] }
|
|
635
|
+
|
|
636
|
+
return {
|
|
637
|
+
sql: `AND ${alias}.object_type_id IN (${objectTypeIds.map(() => "?").join(", ")})`,
|
|
638
|
+
args: [...objectTypeIds],
|
|
639
|
+
}
|
|
640
|
+
}
|
|
641
|
+
|
|
633
642
|
/** Correlation handle for an expansion: the parent row's identity columns. */
|
|
634
643
|
interface ExpansionParent {
|
|
635
644
|
project: string
|
|
@@ -698,12 +707,12 @@ function compileExpansionsObject(
|
|
|
698
707
|
return { sql: `json_object(${parts.join(", ")})`, args }
|
|
699
708
|
}
|
|
700
709
|
|
|
701
|
-
// One expansion's hydrated value.
|
|
702
|
-
//
|
|
703
|
-
//
|
|
704
|
-
//
|
|
705
|
-
//
|
|
706
|
-
// cardinality is core-resolved before pushdown.
|
|
710
|
+
// One expansion's hydrated value. A parent's links are read in the order from
|
|
711
|
+
// `compileExpansionOrder` (the expansion's `orderBy` against the target object's
|
|
712
|
+
// properties, then an identity tiebreak) and `LIMIT N` keeps the top-N per parent
|
|
713
|
+
// in-DB; each retained neighbour becomes a JSON object; and the value is an
|
|
714
|
+
// ordered array ("many", numbered by `row_number()` for `json_group_array`) or the
|
|
715
|
+
// first neighbour or null ("one"). The cardinality is core-resolved before pushdown.
|
|
707
716
|
function compileExpansionValue(
|
|
708
717
|
expansion: ObjectExpansion,
|
|
709
718
|
parent: ExpansionParent,
|
|
@@ -730,27 +739,29 @@ function compileExpansionValue(
|
|
|
730
739
|
`${parentId} = ${parent.id}`,
|
|
731
740
|
`${edge}.link_id = ?`,
|
|
732
741
|
]
|
|
733
|
-
const
|
|
742
|
+
const endpointType = compileEndpointTypes(target, expansion.endpointObjectTypeIds)
|
|
743
|
+
const whereArgs: SqliteValue[] = [...endpointType.args, expansion.linkId]
|
|
734
744
|
if (incoming && expansion.sourceObjectTypeId !== undefined) {
|
|
735
745
|
whereParts.push(`${edge}.source_type_id = ?`)
|
|
736
746
|
whereArgs.push(expansion.sourceObjectTypeId)
|
|
737
747
|
}
|
|
738
748
|
|
|
739
|
-
const
|
|
740
|
-
SELECT ${child.sql} AS elem, row_number() OVER (ORDER BY ${order.sql}) AS _ord
|
|
749
|
+
const from = `
|
|
741
750
|
FROM ${ctx.source.linksTable} AS ${edge}
|
|
742
751
|
JOIN ${ctx.source.objectsTable} AS ${target}
|
|
743
752
|
ON ${target}.project_id = ${edge}.project_id
|
|
744
753
|
AND ${target}.object_type_id = ${neighborType}
|
|
745
754
|
AND ${target}.primary_id = ${neighborId}
|
|
755
|
+
${endpointType.sql}
|
|
746
756
|
WHERE ${whereParts.join(" AND ")}
|
|
747
757
|
`
|
|
748
|
-
const innerArgs = [...child.args, ...order.args, ...whereArgs]
|
|
749
758
|
|
|
759
|
+
// ORDER BY ... LIMIT stops at the kept neighbours, so only they are built as JSON. Filtering
|
|
760
|
+
// on row_number() would build every neighbour first, in a co-routine per parent.
|
|
750
761
|
if (expansion.cardinality === "one") {
|
|
751
762
|
return {
|
|
752
|
-
sql: `(SELECT ${
|
|
753
|
-
args:
|
|
763
|
+
sql: `(SELECT ${child.sql} ${from} ORDER BY ${order.sql} LIMIT 1)`,
|
|
764
|
+
args: [...child.args, ...whereArgs, ...order.args],
|
|
754
765
|
}
|
|
755
766
|
}
|
|
756
767
|
|
|
@@ -759,8 +770,13 @@ function compileExpansionValue(
|
|
|
759
770
|
// rather than the quoted JSON text the subquery column hands back.
|
|
760
771
|
const limit = expansion.limit ?? DEFAULT_EXPANSION_FANOUT
|
|
761
772
|
return {
|
|
762
|
-
sql: `COALESCE((SELECT json_group_array(json(${ranked}.elem) ORDER BY ${ranked}._ord) FROM (
|
|
763
|
-
|
|
773
|
+
sql: `COALESCE((SELECT json_group_array(json(${ranked}.elem) ORDER BY ${ranked}._ord) FROM (
|
|
774
|
+
SELECT ${child.sql} AS elem, row_number() OVER (ORDER BY ${order.sql}) AS _ord
|
|
775
|
+
${from}
|
|
776
|
+
ORDER BY ${order.sql}
|
|
777
|
+
LIMIT ?
|
|
778
|
+
) AS ${ranked}), '[]')`,
|
|
779
|
+
args: [...child.args, ...order.args, ...whereArgs, ...order.args, limit],
|
|
764
780
|
}
|
|
765
781
|
}
|
|
766
782
|
|
|
@@ -11,6 +11,7 @@ import type {
|
|
|
11
11
|
import {
|
|
12
12
|
assertNonblank,
|
|
13
13
|
assertNonnegativeInteger,
|
|
14
|
+
assertTimestamp,
|
|
14
15
|
commitRecord,
|
|
15
16
|
originWhere,
|
|
16
17
|
type SqliteOntologyCommitRow,
|
|
@@ -78,6 +79,9 @@ export class SqliteOntologyCommitStorage implements OntologyCommitStorage {
|
|
|
78
79
|
const limit = input.limit ?? -1
|
|
79
80
|
assertNonnegativeInteger(offset, "Ontology commit list offset")
|
|
80
81
|
if (limit !== -1) assertNonnegativeInteger(limit, "Ontology commit list limit")
|
|
82
|
+
if (input.committedAt !== undefined) {
|
|
83
|
+
assertTimestamp(input.committedAt, "Ontology commit list committedAt")
|
|
84
|
+
}
|
|
81
85
|
const filters = ["project_id = ?"]
|
|
82
86
|
const values: (string | number)[] = [input.projectId]
|
|
83
87
|
if (input.run?.kind === "action") {
|
|
@@ -87,6 +91,11 @@ export class SqliteOntologyCommitStorage implements OntologyCommitStorage {
|
|
|
87
91
|
filters.push("origin_run_id = ? AND origin_kind IN ('projection', 'telemetry')")
|
|
88
92
|
values.push(input.run.id)
|
|
89
93
|
}
|
|
94
|
+
if (input.committedAt !== undefined) {
|
|
95
|
+
// Commit times are stored canonical, so text equality is exact and the index serves it.
|
|
96
|
+
filters.push("committed_at = ?")
|
|
97
|
+
values.push(input.committedAt)
|
|
98
|
+
}
|
|
90
99
|
const where = filters.join(" AND ")
|
|
91
100
|
const totalRow = this.db
|
|
92
101
|
.query(`SELECT COUNT(*) AS total FROM ontology_commits WHERE ${where}`)
|
|
@@ -25,6 +25,7 @@ import {
|
|
|
25
25
|
invalidCorrelation,
|
|
26
26
|
materializationOutboxWrite,
|
|
27
27
|
materializationPlanChunk,
|
|
28
|
+
prepareMaterializationStateRead,
|
|
28
29
|
sameNonnegativeCounts as sameCounts,
|
|
29
30
|
uniqueSorted,
|
|
30
31
|
} from "@sixb/core/internal/ontology-storage-provider"
|
|
@@ -36,16 +37,18 @@ import type {
|
|
|
36
37
|
MaterializationPlanHeader,
|
|
37
38
|
MaterializationPlanWorkRecord,
|
|
38
39
|
MaterializationSession,
|
|
40
|
+
MaterializationState,
|
|
39
41
|
MaterializationStatePage,
|
|
40
42
|
MaterializationVectorChangePage,
|
|
41
43
|
OntologyCommitRecord,
|
|
42
44
|
OntologyMaterializationStorage,
|
|
45
|
+
ReadMaterializationStateInput,
|
|
43
46
|
SourceActivationWrite,
|
|
44
47
|
StageMaterializationWorkInput,
|
|
45
48
|
StreamMaterializationStateInput,
|
|
46
49
|
StreamMaterializationVectorChangesInput,
|
|
47
50
|
} from "@sixb/core/storage"
|
|
48
|
-
import { yieldSqliteEventLoop } from "../transactions"
|
|
51
|
+
import { runDeferredReadTransaction, yieldSqliteEventLoop } from "../transactions"
|
|
49
52
|
import {
|
|
50
53
|
type SqliteMaterializationSessionState,
|
|
51
54
|
SqliteMaterializationSessions,
|
|
@@ -243,6 +246,20 @@ export class SqliteOntologyMaterializationStorage implements OntologyMaterializa
|
|
|
243
246
|
}
|
|
244
247
|
}
|
|
245
248
|
|
|
249
|
+
async readState(input: ReadMaterializationStateInput): Promise<MaterializationState> {
|
|
250
|
+
const request = prepareMaterializationStateRead(input)
|
|
251
|
+
|
|
252
|
+
// One snapshot for every statement, so the read never straddles a commit.
|
|
253
|
+
return runDeferredReadTransaction(this.db, () => {
|
|
254
|
+
const reader = new SqliteMaterializationStateReader(this.db, request.projectId)
|
|
255
|
+
return {
|
|
256
|
+
objects: reader.objectStates(request.objects),
|
|
257
|
+
links: reader.linkStates(request.links),
|
|
258
|
+
linkScopes: reader.linkSlotStates(request.linkScopes),
|
|
259
|
+
}
|
|
260
|
+
})
|
|
261
|
+
}
|
|
262
|
+
|
|
246
263
|
async stageWork(input: StageMaterializationWorkInput): Promise<void> {
|
|
247
264
|
this.sessions.stage(input)
|
|
248
265
|
await yieldSqliteEventLoop()
|