@sixb/core 0.1.3 → 0.1.4
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/actions/index.js +17 -18
- package/dist/actions/index.js.map +1 -1
- package/dist/actions/worker.js +4 -4
- package/dist/actions/worker.js.map +1 -1
- package/dist/agents/context-compaction.d.ts +40 -0
- package/dist/agents/context-compaction.d.ts.map +1 -0
- package/dist/agents/ids.d.ts +2 -0
- package/dist/agents/ids.d.ts.map +1 -1
- package/dist/agents/index.d.ts +6 -5
- package/dist/agents/index.d.ts.map +1 -1
- package/dist/agents/index.js +42 -37
- package/dist/agents/index.js.map +1 -1
- package/dist/agents/streams.d.ts +17 -1
- package/dist/agents/streams.d.ts.map +1 -1
- package/dist/agents/streams.js +4 -2
- package/dist/agents/streams.js.map +1 -1
- package/dist/agents/types.d.ts +9 -0
- package/dist/agents/types.d.ts.map +1 -1
- package/dist/agents/validation.d.ts +1 -1
- package/dist/agents/validation.d.ts.map +1 -1
- package/dist/auth/index.js +7 -3
- package/dist/auth/index.js.map +1 -1
- package/dist/authorization/index.js +6 -2
- package/dist/authorization/index.js.map +1 -1
- package/dist/bootstrap/index.js +30 -31
- package/dist/bootstrap/index.js.map +1 -1
- package/dist/{chunk-xmggaxg4.js → chunk-1wk20wn3.js} +188 -21
- package/dist/{chunk-xmggaxg4.js.map → chunk-1wk20wn3.js.map} +7 -5
- package/dist/{chunk-1ywq4hzk.js → chunk-1yz3x65y.js} +7 -7
- package/dist/{chunk-gqdd7508.js → chunk-4rh2m6zg.js} +1 -1
- package/dist/{chunk-fmx1sz2h.js → chunk-72q2y8hn.js} +3 -3
- package/dist/{chunk-fmx1sz2h.js.map → chunk-72q2y8hn.js.map} +3 -3
- package/dist/{chunk-f1cyvnrk.js → chunk-7gw7mepb.js} +259 -9
- package/dist/chunk-7gw7mepb.js.map +14 -0
- package/dist/{chunk-wb4051cx.js → chunk-819wnjz8.js} +11 -5
- package/dist/chunk-819wnjz8.js.map +12 -0
- package/dist/{chunk-pxtrxm3p.js → chunk-a09jx26t.js} +1 -1
- package/dist/{chunk-ettb0cy4.js → chunk-afjpa2hs.js} +59 -29
- package/dist/{chunk-ettb0cy4.js.map → chunk-afjpa2hs.js.map} +5 -5
- package/dist/{chunk-177ed2mp.js → chunk-c43qr6s0.js} +229 -97
- package/dist/{chunk-177ed2mp.js.map → chunk-c43qr6s0.js.map} +9 -9
- package/dist/{chunk-261ag4t4.js → chunk-cbkm2vam.js} +3 -3
- package/dist/{chunk-zpw39qhj.js → chunk-dm72y8wt.js} +25 -2
- package/dist/chunk-dm72y8wt.js.map +10 -0
- package/dist/{chunk-kqxgf6kv.js → chunk-drjqm1aa.js} +16 -1
- package/dist/{chunk-kqxgf6kv.js.map → chunk-drjqm1aa.js.map} +3 -3
- package/dist/chunk-dysw7nsm.js.map +1 -1
- package/dist/{chunk-4aw0jwk0.js → chunk-f6erf2vv.js} +1 -1
- package/dist/{chunk-4z3n1dzt.js → chunk-f83ka50g.js} +131 -25
- package/dist/chunk-f83ka50g.js.map +23 -0
- package/dist/{chunk-km4rkj4t.js → chunk-g13869yf.js} +3 -3
- package/dist/{chunk-c8bw2b6c.js → chunk-hbeh8j9w.js} +2 -2
- package/dist/{chunk-n5x5y80a.js → chunk-nzw7sm3b.js} +2 -2
- package/dist/{chunk-3rsf30p4.js → chunk-pn8n8sba.js} +16 -15
- package/dist/{chunk-3rsf30p4.js.map → chunk-pn8n8sba.js.map} +3 -3
- package/dist/{chunk-63te770v.js → chunk-qewtks41.js} +8 -8
- package/dist/{chunk-63te770v.js.map → chunk-qewtks41.js.map} +2 -2
- package/dist/{chunk-4p9rh7jj.js → chunk-rs1wbvy6.js} +1 -1
- package/dist/{chunk-88ppkr54.js → chunk-rte5sm3z.js} +26 -2
- package/dist/chunk-rte5sm3z.js.map +12 -0
- package/dist/{chunk-bv41fmjn.js → chunk-s31d0qmq.js} +57 -20
- package/dist/{chunk-bv41fmjn.js.map → chunk-s31d0qmq.js.map} +8 -7
- package/dist/{chunk-c6cfqydk.js → chunk-sxwk41qa.js} +1 -1
- package/dist/chunk-t0jjkep3.js.map +1 -1
- package/dist/{chunk-d6y2wsfg.js → chunk-tek1qwgm.js} +6 -6
- package/dist/{chunk-d6y2wsfg.js.map → chunk-tek1qwgm.js.map} +1 -1
- package/dist/{chunk-d2adj15j.js → chunk-tkdscva6.js} +1 -1
- package/dist/{chunk-ttba8x6z.js → chunk-tycbzedm.js} +2 -2
- package/dist/{chunk-z8j83gzd.js → chunk-x2yw73hy.js} +1 -1
- package/dist/{chunk-qer6am8w.js → chunk-xdf9yswn.js} +1 -1
- package/dist/execution/agent.js +26 -27
- package/dist/execution/agent.js.map +1 -1
- package/dist/execution/primitive.js +26 -27
- package/dist/execution/primitive.js.map +2 -2
- package/dist/execution/request.js +27 -28
- package/dist/execution/request.js.map +2 -2
- package/dist/http/index.js +1 -1
- package/dist/index.d.ts +5 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +52 -53
- package/dist/index.js.map +1 -1
- package/dist/lake-storage/types.d.ts +2 -1
- package/dist/lake-storage/types.d.ts.map +1 -1
- package/dist/materializer/index.js +15 -16
- package/dist/materializer/index.js.map +1 -1
- package/dist/models/index.d.ts +40 -0
- package/dist/models/index.d.ts.map +1 -0
- package/dist/objects/execution.d.ts +6 -1
- package/dist/objects/execution.d.ts.map +1 -1
- package/dist/objects/index.js +19 -20
- package/dist/objects/index.js.map +1 -1
- package/dist/objects/link/endpoints.d.ts.map +1 -1
- package/dist/objects/query/executor.d.ts +1 -0
- package/dist/objects/query/executor.d.ts.map +1 -1
- package/dist/objects/query/explain.d.ts +1 -0
- package/dist/objects/query/explain.d.ts.map +1 -1
- package/dist/objects/query/index.d.ts +3 -1
- package/dist/objects/query/index.d.ts.map +1 -1
- package/dist/objects/query/index.js +30 -5
- package/dist/objects/query/index.js.map +1 -1
- package/dist/objects/query/ir.d.ts +14 -1
- package/dist/objects/query/ir.d.ts.map +1 -1
- package/dist/objects/query/links.d.ts +25 -0
- package/dist/objects/query/links.d.ts.map +1 -0
- package/dist/objects/query/normalize.d.ts.map +1 -1
- package/dist/objects/query/planner.d.ts.map +1 -1
- package/dist/objects/query/validate.d.ts +1 -0
- package/dist/objects/query/validate.d.ts.map +1 -1
- package/dist/pipelines/index.js +15 -16
- package/dist/pipelines/index.js.map +1 -1
- package/dist/projections/builders.d.ts +33 -4
- package/dist/projections/builders.d.ts.map +1 -1
- package/dist/projections/index.d.ts +1 -1
- package/dist/projections/index.d.ts.map +1 -1
- package/dist/projections/internal.js +15 -16
- package/dist/projections/internal.js.map +1 -1
- package/dist/projections/run-dispatch.d.ts +1 -0
- package/dist/projections/run-dispatch.d.ts.map +1 -1
- package/dist/projections/types.d.ts +12 -9
- package/dist/projections/types.d.ts.map +1 -1
- package/dist/projections/validation.d.ts +6 -5
- package/dist/projections/validation.d.ts.map +1 -1
- package/dist/query.d.ts +2 -1
- package/dist/query.d.ts.map +1 -1
- package/dist/query.js +2 -2
- package/dist/runtime/create.d.ts +3 -0
- package/dist/runtime/create.d.ts.map +1 -1
- package/dist/runtime/definitions.d.ts +3 -0
- package/dist/runtime/definitions.d.ts.map +1 -1
- package/dist/runtime/host.d.ts +2 -0
- package/dist/runtime/host.d.ts.map +1 -1
- package/dist/runtime/resolve-definitions.d.ts +2 -0
- package/dist/runtime/resolve-definitions.d.ts.map +1 -1
- package/dist/storage/agents/in-memory.d.ts +4 -0
- package/dist/storage/agents/in-memory.d.ts.map +1 -1
- package/dist/storage/agents/provider.js +9 -5
- package/dist/storage/agents/provider.js.map +1 -1
- package/dist/storage/agents/types.d.ts +5 -0
- package/dist/storage/agents/types.d.ts.map +1 -1
- package/dist/storage/ai-cost/provider.js +1 -1
- package/dist/storage/ai-usage/in-memory.d.ts +2 -1
- package/dist/storage/ai-usage/in-memory.d.ts.map +1 -1
- package/dist/storage/ai-usage/index.d.ts +1 -1
- package/dist/storage/ai-usage/index.d.ts.map +1 -1
- package/dist/storage/ai-usage/types.d.ts +6 -0
- package/dist/storage/ai-usage/types.d.ts.map +1 -1
- package/dist/storage/index.d.ts +3 -2
- package/dist/storage/index.d.ts.map +1 -1
- package/dist/storage/index.js +19 -14
- package/dist/storage/index.js.map +1 -1
- package/dist/storage/objects/in-memory.d.ts +6 -3
- package/dist/storage/objects/in-memory.d.ts.map +1 -1
- package/dist/storage/objects/index.d.ts +3 -1
- package/dist/storage/objects/index.d.ts.map +1 -1
- package/dist/storage/objects/keys.d.ts +16 -0
- package/dist/storage/objects/keys.d.ts.map +1 -0
- package/dist/storage/objects/types.d.ts +33 -6
- package/dist/storage/objects/types.d.ts.map +1 -1
- package/dist/storage/ontology/provider.js +1 -1
- package/dist/storage/workflow-runs/provider.js +9 -5
- package/dist/storage/workflow-runs/provider.js.map +1 -1
- package/dist/syncs/index.js +15 -16
- package/dist/syncs/index.js.map +1 -1
- package/dist/testing/agent-storage-contract.d.ts.map +1 -1
- package/dist/testing/ai-usage-storage-contract.d.ts.map +1 -1
- package/dist/testing/effective-storage-contract.d.ts +1 -1
- package/dist/testing/effective-storage-contract.d.ts.map +1 -1
- package/dist/testing/index.js +455 -40
- package/dist/testing/index.js.map +7 -7
- package/dist/testing/lake-storage-contract.d.ts.map +1 -1
- package/dist/testing/object-query-contract.d.ts +1 -1
- package/dist/testing/object-query-contract.d.ts.map +1 -1
- package/dist/webhooks/internal.js +13 -14
- package/dist/webhooks/internal.js.map +2 -2
- package/dist/workflows/index.js +27 -28
- package/dist/workflows/index.js.map +1 -1
- package/package.json +1 -1
- package/src/agents/builders.ts +3 -3
- package/src/agents/context-compaction.ts +261 -0
- package/src/agents/ids.ts +5 -0
- package/src/agents/index.ts +18 -9
- package/src/agents/streams.ts +56 -0
- package/src/agents/types.ts +10 -0
- package/src/agents/validation.ts +35 -5
- package/src/http/api-routes.ts +7 -7
- package/src/index.ts +14 -0
- package/src/lake-storage/types.ts +2 -1
- package/src/materializer/telemetry/append.ts +33 -16
- package/src/models/index.ts +71 -0
- package/src/objects/execution.ts +20 -0
- package/src/objects/link/endpoints.ts +2 -1
- package/src/objects/query/executor.ts +42 -11
- package/src/objects/query/explain.ts +11 -0
- package/src/objects/query/index.ts +6 -0
- package/src/objects/query/ir.ts +16 -0
- package/src/objects/query/links.ts +308 -0
- package/src/objects/query/normalize.ts +40 -1
- package/src/objects/query/planner.ts +5 -0
- package/src/objects/query/validate.ts +58 -2
- package/src/projections/builders.ts +220 -15
- package/src/projections/index.ts +1 -0
- package/src/projections/ownership.ts +5 -5
- package/src/projections/registry.ts +9 -3
- package/src/projections/revision.ts +31 -5
- package/src/projections/run-dispatch.ts +10 -1
- package/src/projections/types.ts +13 -9
- package/src/projections/validation.ts +61 -19
- package/src/query.ts +2 -0
- package/src/runtime/create.ts +4 -0
- package/src/runtime/definitions.ts +3 -0
- package/src/runtime/host.ts +2 -0
- package/src/runtime/resolve-definitions.ts +28 -0
- package/src/storage/agents/in-memory.ts +15 -0
- package/src/storage/agents/types.ts +5 -0
- package/src/storage/ai-usage/in-memory.ts +23 -0
- package/src/storage/ai-usage/index.ts +1 -0
- package/src/storage/ai-usage/types.ts +10 -0
- package/src/storage/index.ts +11 -0
- package/src/storage/objects/in-memory.ts +103 -16
- package/src/storage/objects/index.ts +9 -0
- package/src/storage/objects/keys.ts +36 -0
- package/src/storage/objects/types.ts +34 -6
- package/src/storage/ontology/provider-header-validation.ts +2 -2
- package/src/testing/agent-storage-contract.ts +12 -0
- package/src/testing/ai-usage-storage-contract.ts +35 -0
- package/src/testing/effective-storage-contract.ts +194 -4
- package/src/testing/lake-storage-contract.ts +56 -0
- package/src/testing/object-query-contract.ts +208 -1
- package/dist/agents/prompt.d.ts +0 -21
- package/dist/agents/prompt.d.ts.map +0 -1
- package/dist/chunk-4z3n1dzt.js.map +0 -23
- package/dist/chunk-6wetht33.js +0 -89
- package/dist/chunk-6wetht33.js.map +0 -10
- package/dist/chunk-88ppkr54.js.map +0 -12
- package/dist/chunk-f1cyvnrk.js.map +0 -13
- package/dist/chunk-wb4051cx.js.map +0 -12
- package/dist/chunk-zpw39qhj.js.map +0 -10
- package/src/agents/prompt.ts +0 -85
- /package/dist/{chunk-1ywq4hzk.js.map → chunk-1yz3x65y.js.map} +0 -0
- /package/dist/{chunk-gqdd7508.js.map → chunk-4rh2m6zg.js.map} +0 -0
- /package/dist/{chunk-pxtrxm3p.js.map → chunk-a09jx26t.js.map} +0 -0
- /package/dist/{chunk-261ag4t4.js.map → chunk-cbkm2vam.js.map} +0 -0
- /package/dist/{chunk-4aw0jwk0.js.map → chunk-f6erf2vv.js.map} +0 -0
- /package/dist/{chunk-km4rkj4t.js.map → chunk-g13869yf.js.map} +0 -0
- /package/dist/{chunk-c8bw2b6c.js.map → chunk-hbeh8j9w.js.map} +0 -0
- /package/dist/{chunk-n5x5y80a.js.map → chunk-nzw7sm3b.js.map} +0 -0
- /package/dist/{chunk-4p9rh7jj.js.map → chunk-rs1wbvy6.js.map} +0 -0
- /package/dist/{chunk-c6cfqydk.js.map → chunk-sxwk41qa.js.map} +0 -0
- /package/dist/{chunk-d2adj15j.js.map → chunk-tkdscva6.js.map} +0 -0
- /package/dist/{chunk-ttba8x6z.js.map → chunk-tycbzedm.js.map} +0 -0
- /package/dist/{chunk-z8j83gzd.js.map → chunk-x2yw73hy.js.map} +0 -0
- /package/dist/{chunk-qer6am8w.js.map → chunk-xdf9yswn.js.map} +0 -0
|
@@ -2,6 +2,7 @@ import type { ActionDefinitionCatalog } from "../actions"
|
|
|
2
2
|
import type { AgentDefinition } from "../agents"
|
|
3
3
|
import type { ConnectorDefinition } from "../connectors"
|
|
4
4
|
import type { DatasetDefinition } from "../datasets"
|
|
5
|
+
import type { ModelCatalog } from "../models"
|
|
5
6
|
import type { OntologyDefinitionCatalog } from "../ontology"
|
|
6
7
|
import type { PipelineDefinition } from "../pipelines"
|
|
7
8
|
import type { ProjectionDefinitionCatalog } from "../projections"
|
|
@@ -24,6 +25,8 @@ export interface SixbDefinitions {
|
|
|
24
25
|
readonly agents: DefinitionCatalog<AgentDefinition>
|
|
25
26
|
readonly connectors: DefinitionCatalog<ConnectorDefinition>
|
|
26
27
|
readonly datasets: DefinitionCatalog<DatasetDefinition>
|
|
28
|
+
/** Absent until a project configures `models` in createSixb(). */
|
|
29
|
+
readonly models?: ModelCatalog
|
|
27
30
|
readonly pipelines: DefinitionCatalog<PipelineDefinition>
|
|
28
31
|
readonly projections: ProjectionDefinitionCatalog
|
|
29
32
|
readonly rules: DefinitionCatalog<RuleDefinition>
|
package/src/runtime/host.ts
CHANGED
|
@@ -48,6 +48,7 @@ import {
|
|
|
48
48
|
type SixbReadiness,
|
|
49
49
|
} from "../maintenance"
|
|
50
50
|
import { createOntologyMaterializer, type OntologyMaterializerContract } from "../materializer"
|
|
51
|
+
import type { ModelCatalogInput } from "../models"
|
|
51
52
|
import type { PipelineDefinition } from "../pipelines/types"
|
|
52
53
|
import { registerProjectionRegistry } from "../projections/internal"
|
|
53
54
|
import type { ProjectionDefinition } from "../projections/types"
|
|
@@ -108,6 +109,7 @@ export interface SixbHostOptions<TOntologySources extends readonly OntologySourc
|
|
|
108
109
|
rules?: readonly RuleDefinition[]
|
|
109
110
|
workflows?: readonly WorkflowDefinition[]
|
|
110
111
|
agents?: readonly AgentDefinition[]
|
|
112
|
+
models?: ModelCatalogInput
|
|
111
113
|
groups?: readonly GroupDefinition[]
|
|
112
114
|
roles?: readonly RoleDefinition[]
|
|
113
115
|
membershipPolicies?: readonly MembershipPolicyDefinition[]
|
|
@@ -5,6 +5,7 @@ import { validateAgentGroupReferences, validateAgentToolsAtStartup } from "../ag
|
|
|
5
5
|
import type { ConnectorDefinition } from "../connectors"
|
|
6
6
|
import type { DatasetDefinition } from "../datasets/types"
|
|
7
7
|
import { assertDatasetDefinition } from "../datasets/validation"
|
|
8
|
+
import { createModelCatalog, type ModelCatalog, type ModelCatalogInput, modelRef } from "../models"
|
|
8
9
|
import { OntologyRegistry } from "../ontology"
|
|
9
10
|
import type { PipelineDefinition } from "../pipelines/types"
|
|
10
11
|
import { ProjectionRegistry } from "../projections"
|
|
@@ -40,6 +41,7 @@ interface DefinitionOptions {
|
|
|
40
41
|
readonly rules?: readonly RuleDefinition[]
|
|
41
42
|
readonly workflows?: readonly WorkflowDefinition[]
|
|
42
43
|
readonly agents?: readonly AgentDefinition[]
|
|
44
|
+
readonly models?: ModelCatalogInput
|
|
43
45
|
readonly groups?: readonly GroupDefinition[]
|
|
44
46
|
readonly roles?: readonly RoleDefinition[]
|
|
45
47
|
readonly membershipPolicies?: readonly MembershipPolicyDefinition[]
|
|
@@ -60,6 +62,8 @@ export function resolveDefinitions(options: DefinitionOptions): ResolvedDefiniti
|
|
|
60
62
|
|
|
61
63
|
const agents = options.agents ?? []
|
|
62
64
|
validateAgentToolsAtStartup(agents)
|
|
65
|
+
const models = options.models === undefined ? undefined : createModelCatalog(options.models)
|
|
66
|
+
validateAgentModelReferences(agents, models)
|
|
63
67
|
const agentsById = indexUniqueDefinitions("agent", agents)
|
|
64
68
|
const connectorsById = indexUniqueDefinitions("connector", options.connectors ?? [])
|
|
65
69
|
|
|
@@ -158,6 +162,7 @@ export function resolveDefinitions(options: DefinitionOptions): ResolvedDefiniti
|
|
|
158
162
|
agents: createDefinitionCatalog(agentsById),
|
|
159
163
|
connectors: createDefinitionCatalog(connectorsById),
|
|
160
164
|
datasets: createDefinitionCatalog(datasetsById),
|
|
165
|
+
...(models === undefined ? {} : { models }),
|
|
161
166
|
pipelines: createDefinitionCatalog(pipelinesById),
|
|
162
167
|
projections: projectionRegistry,
|
|
163
168
|
rules: createDefinitionCatalog(rulesById),
|
|
@@ -236,3 +241,26 @@ function validateScheduleReferences(
|
|
|
236
241
|
}
|
|
237
242
|
}
|
|
238
243
|
}
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
* Keep every agent on a model the project actually allows.
|
|
247
|
+
*
|
|
248
|
+
* Only enforced once a project configures `models`; without a catalog an agent's model is its own
|
|
249
|
+
* declaration, which is the pre-catalog behavior.
|
|
250
|
+
*/
|
|
251
|
+
function validateAgentModelReferences(
|
|
252
|
+
agents: readonly AgentDefinition[],
|
|
253
|
+
models: ModelCatalog | undefined
|
|
254
|
+
): void {
|
|
255
|
+
if (models === undefined) {
|
|
256
|
+
return
|
|
257
|
+
}
|
|
258
|
+
for (const agent of agents) {
|
|
259
|
+
const ref = modelRef(agent.model)
|
|
260
|
+
if (models.language.getById(ref) === null) {
|
|
261
|
+
throw new RuntimeError(
|
|
262
|
+
`[Sixb] Agent '${agent.id}' uses unknown language model '${ref}'. Add it to 'models.language' in createSixb().`
|
|
263
|
+
)
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
}
|
|
@@ -642,6 +642,21 @@ class InMemoryAgentContextCheckpointStore implements AgentContextCheckpointStore
|
|
|
642
642
|
return record ? clone(record) : null
|
|
643
643
|
}
|
|
644
644
|
|
|
645
|
+
async getByRunIds(input: {
|
|
646
|
+
readonly projectId: string
|
|
647
|
+
readonly runIds: readonly string[]
|
|
648
|
+
}): Promise<readonly AgentContextCheckpointRecord[]> {
|
|
649
|
+
const byRunId = new Map(
|
|
650
|
+
[...this.state.checkpoints.values()]
|
|
651
|
+
.filter((checkpoint) => checkpoint.projectId === input.projectId)
|
|
652
|
+
.map((checkpoint) => [checkpoint.createdByRunId, checkpoint] as const)
|
|
653
|
+
)
|
|
654
|
+
return [...new Set(input.runIds)].flatMap((runId) => {
|
|
655
|
+
const checkpoint = byRunId.get(runId)
|
|
656
|
+
return checkpoint ? [clone(checkpoint)] : []
|
|
657
|
+
})
|
|
658
|
+
}
|
|
659
|
+
|
|
645
660
|
private findLatest(projectId: string, threadId: string): AgentContextCheckpointRecord | null {
|
|
646
661
|
return (
|
|
647
662
|
[...this.state.checkpoints.values()]
|
|
@@ -408,6 +408,11 @@ export interface AgentContextCheckpointStore {
|
|
|
408
408
|
* Repeating the same payload for the same creating run is idempotent.
|
|
409
409
|
*/
|
|
410
410
|
create(input: CreateAgentContextCheckpointInput): Promise<AgentContextCheckpointRecord>
|
|
411
|
+
/** Return checkpoints created by the requested runs, in first-occurrence input order. */
|
|
412
|
+
getByRunIds(input: {
|
|
413
|
+
readonly projectId: string
|
|
414
|
+
readonly runIds: readonly string[]
|
|
415
|
+
}): Promise<readonly AgentContextCheckpointRecord[]>
|
|
411
416
|
getLatest(input: {
|
|
412
417
|
readonly projectId: string
|
|
413
418
|
readonly threadId: string
|
|
@@ -5,6 +5,7 @@ import type {
|
|
|
5
5
|
AiModelCallUsageRecord,
|
|
6
6
|
AiUsageExecutionSummary,
|
|
7
7
|
AiUsageStorage,
|
|
8
|
+
GetLatestAiModelCallForExecutionInput,
|
|
8
9
|
RecordAiModelCallInput,
|
|
9
10
|
RecordAiModelCallResult,
|
|
10
11
|
SummarizeAiUsageExecutionInput,
|
|
@@ -69,6 +70,28 @@ export class InMemoryAiUsageStorage implements AiUsageStorage {
|
|
|
69
70
|
return { record: structuredClone(record), created: true }
|
|
70
71
|
}
|
|
71
72
|
|
|
73
|
+
async getLatestForExecution(
|
|
74
|
+
input: GetLatestAiModelCallForExecutionInput
|
|
75
|
+
): Promise<AiModelCallUsageRecord | null> {
|
|
76
|
+
assertAiUsageExecutionId(input.executionId)
|
|
77
|
+
if (typeof input.projectId !== "string" || input.projectId.trim().length === 0) {
|
|
78
|
+
throw new TypeError("[Sixb] AI usage projectId must be nonblank.")
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
let latest: AiModelCallUsageRecord | null = null
|
|
82
|
+
for (const record of this.records.values()) {
|
|
83
|
+
if (record.projectId !== input.projectId || record.executionId !== input.executionId) continue
|
|
84
|
+
if (
|
|
85
|
+
!latest ||
|
|
86
|
+
record.occurredAt.getTime() > latest.occurredAt.getTime() ||
|
|
87
|
+
(record.occurredAt.getTime() === latest.occurredAt.getTime() && record.id > latest.id)
|
|
88
|
+
) {
|
|
89
|
+
latest = record
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return latest ? structuredClone(latest) : null
|
|
93
|
+
}
|
|
94
|
+
|
|
72
95
|
async summarizeExecution(
|
|
73
96
|
input: SummarizeAiUsageExecutionInput
|
|
74
97
|
): Promise<AiUsageExecutionSummary> {
|
|
@@ -80,6 +80,11 @@ export interface SummarizeAiUsageExecutionsInput {
|
|
|
80
80
|
readonly executionIds: readonly string[]
|
|
81
81
|
}
|
|
82
82
|
|
|
83
|
+
export interface GetLatestAiModelCallForExecutionInput {
|
|
84
|
+
readonly projectId: string
|
|
85
|
+
readonly executionId: string
|
|
86
|
+
}
|
|
87
|
+
|
|
83
88
|
/** Durable, provider-neutral accounting for completed language-model calls. */
|
|
84
89
|
export interface AiUsageStorage {
|
|
85
90
|
/**
|
|
@@ -88,6 +93,11 @@ export interface AiUsageStorage {
|
|
|
88
93
|
*/
|
|
89
94
|
recordModelCall(input: RecordAiModelCallInput): Promise<RecordAiModelCallResult>
|
|
90
95
|
|
|
96
|
+
/** Latest completed provider call for one execution, ordered by occurrence and stable id. */
|
|
97
|
+
getLatestForExecution(
|
|
98
|
+
input: GetLatestAiModelCallForExecutionInput
|
|
99
|
+
): Promise<AiModelCallUsageRecord | null>
|
|
100
|
+
|
|
91
101
|
/** Aggregate normalized usage and call presence across every attempt of one execution. */
|
|
92
102
|
summarizeExecution(input: SummarizeAiUsageExecutionInput): Promise<AiUsageExecutionSummary>
|
|
93
103
|
|
package/src/storage/index.ts
CHANGED
|
@@ -138,6 +138,7 @@ export type {
|
|
|
138
138
|
AiUsageReportingStatus,
|
|
139
139
|
AiUsageStorage,
|
|
140
140
|
AiUsageStorageErrorCode,
|
|
141
|
+
GetLatestAiModelCallForExecutionInput,
|
|
141
142
|
InMemoryAiUsageGroupRow,
|
|
142
143
|
InMemoryAiUsageStorageSnapshot,
|
|
143
144
|
RecordAiModelCallInput,
|
|
@@ -352,10 +353,13 @@ export type {
|
|
|
352
353
|
ExpandedObjectRow,
|
|
353
354
|
FacetObjectsInput,
|
|
354
355
|
FacetObjectsResult,
|
|
356
|
+
LinkBatchKey,
|
|
355
357
|
LinkDirection,
|
|
358
|
+
ObjectBatchKey,
|
|
356
359
|
ObjectFacetBucket,
|
|
357
360
|
ObjectFacetRequest,
|
|
358
361
|
ObjectFacetResult,
|
|
362
|
+
ObjectLinkCursor,
|
|
359
363
|
ObjectLinkRow,
|
|
360
364
|
ObjectQueryCapabilities,
|
|
361
365
|
ObjectQueryCapabilityMap,
|
|
@@ -364,9 +368,16 @@ export type {
|
|
|
364
368
|
ObjectRow,
|
|
365
369
|
ObjectRowLinks,
|
|
366
370
|
ObjectStorage,
|
|
371
|
+
QueryObjectLinksInput,
|
|
372
|
+
QueryObjectLinksResult,
|
|
367
373
|
QueryObjectsInput,
|
|
368
374
|
QueryObjectsResult,
|
|
369
375
|
} from "./objects"
|
|
376
|
+
export {
|
|
377
|
+
linkBatchKey,
|
|
378
|
+
objectBatchKey,
|
|
379
|
+
objectLinkCursor,
|
|
380
|
+
} from "./objects"
|
|
370
381
|
export type {
|
|
371
382
|
AbandonSourceMaterializationCandidateInput,
|
|
372
383
|
AbandonSourceMaterializationInput,
|
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
import type { EffectiveLinkSnapshot, EffectiveObjectSnapshot } from "../../materialization/model"
|
|
2
2
|
import type { ObjectQuery, ObjectQueryPredicate, ObjectQuerySortField } from "../../objects/query"
|
|
3
3
|
import { compareQueryScalarValues, queryScalarValuesEqual } from "../../objects/query/scalar-values"
|
|
4
|
+
import type { LinkBatchKey, ObjectBatchKey } from "./keys"
|
|
5
|
+
import {
|
|
6
|
+
compareObjectLinkCursors,
|
|
7
|
+
compareObjectLinks,
|
|
8
|
+
linkBatchKey,
|
|
9
|
+
objectBatchKey,
|
|
10
|
+
objectLinkCursor,
|
|
11
|
+
} from "./keys"
|
|
4
12
|
import type {
|
|
5
13
|
CountObjectsInput,
|
|
6
14
|
CountObjectsResult,
|
|
@@ -15,6 +23,8 @@ import type {
|
|
|
15
23
|
ObjectQueryCapabilities,
|
|
16
24
|
ObjectRow,
|
|
17
25
|
ObjectStorage,
|
|
26
|
+
QueryObjectLinksInput,
|
|
27
|
+
QueryObjectLinksResult,
|
|
18
28
|
QueryObjectsInput,
|
|
19
29
|
QueryObjectsResult,
|
|
20
30
|
} from "./types"
|
|
@@ -26,6 +36,7 @@ const IN_MEMORY_OBJECT_QUERY_CAPABILITIES: ObjectQueryCapabilities = {
|
|
|
26
36
|
facetObjects: true,
|
|
27
37
|
nodes: {
|
|
28
38
|
start: true,
|
|
39
|
+
refs: true,
|
|
29
40
|
filter: true,
|
|
30
41
|
text: true,
|
|
31
42
|
vector: true,
|
|
@@ -80,25 +91,41 @@ const IN_MEMORY_OBJECT_QUERY_CAPABILITIES: ObjectQueryCapabilities = {
|
|
|
80
91
|
}
|
|
81
92
|
|
|
82
93
|
function objectRowKey(projectId: string, objectTypeId: string): string {
|
|
83
|
-
return
|
|
94
|
+
return JSON.stringify([projectId, objectTypeId])
|
|
84
95
|
}
|
|
85
96
|
|
|
86
|
-
function
|
|
97
|
+
function objectRowProjectPrefix(projectId: string): string {
|
|
98
|
+
return `[${JSON.stringify(projectId)},`
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function compareStrings(left: string, right: string): number {
|
|
87
102
|
if (left < right) return -1
|
|
88
103
|
if (left > right) return 1
|
|
89
104
|
return 0
|
|
90
105
|
}
|
|
91
106
|
|
|
107
|
+
function assertLinkQueryLimit(limit: number): void {
|
|
108
|
+
if (!Number.isSafeInteger(limit) || limit <= 0) {
|
|
109
|
+
throw new Error("Object link query limit must be a positive safe integer.")
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
92
113
|
function sourceLinkBucketKey(projectId: string, sourceTypeId: string, sourceId: string): string {
|
|
93
|
-
return
|
|
114
|
+
return JSON.stringify([projectId, sourceTypeId, sourceId])
|
|
94
115
|
}
|
|
95
116
|
|
|
96
117
|
function linkRowKey(linkId: string, targetTypeId: string, targetId: string): string {
|
|
97
|
-
return
|
|
118
|
+
return JSON.stringify([linkId, targetTypeId, targetId])
|
|
98
119
|
}
|
|
99
120
|
|
|
100
121
|
function fullLinkRowKey(row: ObjectLinkRow): string {
|
|
101
|
-
return
|
|
122
|
+
return JSON.stringify([
|
|
123
|
+
row.sourceTypeId,
|
|
124
|
+
row.sourceId,
|
|
125
|
+
row.linkId,
|
|
126
|
+
row.targetTypeId,
|
|
127
|
+
row.targetId,
|
|
128
|
+
])
|
|
102
129
|
}
|
|
103
130
|
|
|
104
131
|
type QueryEntry = {
|
|
@@ -343,6 +370,8 @@ export class InMemoryObjectStorage implements ObjectStorage {
|
|
|
343
370
|
switch (query.kind) {
|
|
344
371
|
case "start":
|
|
345
372
|
return this.evaluateStart(projectId, query.objectTypeId)
|
|
373
|
+
case "refs":
|
|
374
|
+
return this.evaluateRefs(projectId, query.refs)
|
|
346
375
|
case "filter": {
|
|
347
376
|
const input = this.evaluateObjectQuery(projectId, query.input)
|
|
348
377
|
const entries = input.entries.filter((entry) =>
|
|
@@ -446,6 +475,29 @@ export class InMemoryObjectStorage implements ObjectStorage {
|
|
|
446
475
|
return completeEvaluation(entries)
|
|
447
476
|
}
|
|
448
477
|
|
|
478
|
+
private evaluateRefs(
|
|
479
|
+
projectId: string,
|
|
480
|
+
refs: readonly { objectTypeId: string; primaryId: string }[]
|
|
481
|
+
): QueryEvaluation {
|
|
482
|
+
const seen = new Set<string>()
|
|
483
|
+
const entries = refs
|
|
484
|
+
.flatMap((ref) => {
|
|
485
|
+
const key = JSON.stringify([ref.objectTypeId, ref.primaryId])
|
|
486
|
+
if (seen.has(key)) return []
|
|
487
|
+
seen.add(key)
|
|
488
|
+
const row = this.rows.get(objectRowKey(projectId, ref.objectTypeId))?.get(ref.primaryId)
|
|
489
|
+
return row ? [row] : []
|
|
490
|
+
})
|
|
491
|
+
.sort(
|
|
492
|
+
(left, right) =>
|
|
493
|
+
compareStrings(left.objectTypeId, right.objectTypeId) ||
|
|
494
|
+
compareStrings(left.primaryId, right.primaryId)
|
|
495
|
+
)
|
|
496
|
+
.map((row, order) => ({ row, score: 0, order }))
|
|
497
|
+
|
|
498
|
+
return completeEvaluation(entries)
|
|
499
|
+
}
|
|
500
|
+
|
|
449
501
|
private evaluateSet(
|
|
450
502
|
projectId: string,
|
|
451
503
|
op: "union" | "intersect" | "subtract",
|
|
@@ -602,8 +654,8 @@ export class InMemoryObjectStorage implements ObjectStorage {
|
|
|
602
654
|
async getByPrimaryIdBatch(params: {
|
|
603
655
|
projectId: string
|
|
604
656
|
items: readonly { objectTypeId: string; primaryId: string }[]
|
|
605
|
-
}): Promise<Map<
|
|
606
|
-
const result = new Map<
|
|
657
|
+
}): Promise<Map<ObjectBatchKey, ObjectRow>> {
|
|
658
|
+
const result = new Map<ObjectBatchKey, ObjectRow>()
|
|
607
659
|
for (const item of params.items) {
|
|
608
660
|
const row = await this.getByPrimaryId({
|
|
609
661
|
projectId: params.projectId,
|
|
@@ -611,7 +663,7 @@ export class InMemoryObjectStorage implements ObjectStorage {
|
|
|
611
663
|
primaryId: item.primaryId,
|
|
612
664
|
})
|
|
613
665
|
if (row) {
|
|
614
|
-
result.set(
|
|
666
|
+
result.set(objectBatchKey(item.objectTypeId, item.primaryId), row)
|
|
615
667
|
}
|
|
616
668
|
}
|
|
617
669
|
return result
|
|
@@ -620,8 +672,8 @@ export class InMemoryObjectStorage implements ObjectStorage {
|
|
|
620
672
|
async listLinksBatch(params: {
|
|
621
673
|
projectId: string
|
|
622
674
|
items: readonly { objectTypeId: string; objectId: string; linkId: string }[]
|
|
623
|
-
}): Promise<Map<
|
|
624
|
-
const result = new Map<
|
|
675
|
+
}): Promise<Map<LinkBatchKey, ObjectLinkRow[]>> {
|
|
676
|
+
const result = new Map<LinkBatchKey, ObjectLinkRow[]>()
|
|
625
677
|
for (const item of params.items) {
|
|
626
678
|
const rows = await this.listLinks({
|
|
627
679
|
projectId: params.projectId,
|
|
@@ -630,12 +682,48 @@ export class InMemoryObjectStorage implements ObjectStorage {
|
|
|
630
682
|
linkId: item.linkId,
|
|
631
683
|
})
|
|
632
684
|
if (rows.length > 0) {
|
|
633
|
-
result.set(
|
|
685
|
+
result.set(linkBatchKey(item.objectTypeId, item.objectId, item.linkId), [...rows])
|
|
634
686
|
}
|
|
635
687
|
}
|
|
636
688
|
return result
|
|
637
689
|
}
|
|
638
690
|
|
|
691
|
+
async queryLinks(params: QueryObjectLinksInput): Promise<QueryObjectLinksResult> {
|
|
692
|
+
assertLinkQueryLimit(params.limit)
|
|
693
|
+
if (params.objectRefs.length === 0 || params.endpointObjectTypeIds?.length === 0) {
|
|
694
|
+
return { links: [], hasMore: false }
|
|
695
|
+
}
|
|
696
|
+
|
|
697
|
+
const allowedTypes = params.endpointObjectTypeIds
|
|
698
|
+
? new Set(params.endpointObjectTypeIds)
|
|
699
|
+
: undefined
|
|
700
|
+
const deduped = new Map<string, ObjectLinkRow>()
|
|
701
|
+
for (const object of params.objectRefs) {
|
|
702
|
+
const rows = await this.listLinks({
|
|
703
|
+
projectId: params.projectId,
|
|
704
|
+
objectTypeId: object.objectTypeId,
|
|
705
|
+
objectId: object.primaryId,
|
|
706
|
+
direction: params.direction,
|
|
707
|
+
...(params.linkId === undefined ? {} : { linkId: params.linkId }),
|
|
708
|
+
})
|
|
709
|
+
for (const row of rows) {
|
|
710
|
+
if (
|
|
711
|
+
allowedTypes &&
|
|
712
|
+
(!allowedTypes.has(row.sourceTypeId) || !allowedTypes.has(row.targetTypeId))
|
|
713
|
+
) {
|
|
714
|
+
continue
|
|
715
|
+
}
|
|
716
|
+
if (params.after && compareObjectLinkCursors(objectLinkCursor(row), params.after) <= 0) {
|
|
717
|
+
continue
|
|
718
|
+
}
|
|
719
|
+
deduped.set(fullLinkRowKey(row), row)
|
|
720
|
+
}
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
const rows = [...deduped.values()].sort(compareObjectLinks).slice(0, params.limit + 1)
|
|
724
|
+
return { links: rows.slice(0, params.limit), hasMore: rows.length > params.limit }
|
|
725
|
+
}
|
|
726
|
+
|
|
639
727
|
async listIncidentLinksBatch(params: {
|
|
640
728
|
projectId: string
|
|
641
729
|
items: readonly { objectTypeId: string; objectId: string }[]
|
|
@@ -665,10 +753,9 @@ export class InMemoryObjectStorage implements ObjectStorage {
|
|
|
665
753
|
const bucket = this.rows.get(objectRowKey(params.projectId, params.objectTypeId))
|
|
666
754
|
const rows = [...(bucket?.values() ?? [])]
|
|
667
755
|
.filter(
|
|
668
|
-
(row) =>
|
|
669
|
-
!params.afterPrimaryId || comparePrimaryIds(row.primaryId, params.afterPrimaryId) > 0
|
|
756
|
+
(row) => !params.afterPrimaryId || compareStrings(row.primaryId, params.afterPrimaryId) > 0
|
|
670
757
|
)
|
|
671
|
-
.sort((left, right) =>
|
|
758
|
+
.sort((left, right) => compareStrings(left.primaryId, right.primaryId))
|
|
672
759
|
.slice(0, params.limit + 1)
|
|
673
760
|
const hasMore = rows.length > params.limit
|
|
674
761
|
const objects = rows.slice(0, params.limit).map((row) => structuredClone(row))
|
|
@@ -707,7 +794,7 @@ export class InMemoryObjectStorage implements ObjectStorage {
|
|
|
707
794
|
}
|
|
708
795
|
} else {
|
|
709
796
|
for (const [key, bucket] of this.rows) {
|
|
710
|
-
if (key.startsWith(
|
|
797
|
+
if (key.startsWith(objectRowProjectPrefix(params.projectId))) {
|
|
711
798
|
allRows.push(...bucket.values())
|
|
712
799
|
}
|
|
713
800
|
}
|
|
@@ -1113,7 +1200,7 @@ function rowIdentityKey(row: ObjectRow): string {
|
|
|
1113
1200
|
}
|
|
1114
1201
|
|
|
1115
1202
|
function rowIdentityKeyParts(objectTypeId: string, primaryId: string): string {
|
|
1116
|
-
return
|
|
1203
|
+
return objectBatchKey(objectTypeId, primaryId)
|
|
1117
1204
|
}
|
|
1118
1205
|
|
|
1119
1206
|
function upsertEntry(entriesByKey: Map<string, QueryEntry>, entry: QueryEntry): void {
|
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
export type { LinkBatchKey, ObjectBatchKey } from "./keys"
|
|
2
|
+
export {
|
|
3
|
+
linkBatchKey,
|
|
4
|
+
objectBatchKey,
|
|
5
|
+
objectLinkCursor,
|
|
6
|
+
} from "./keys"
|
|
1
7
|
export type {
|
|
2
8
|
CountObjectsInput,
|
|
3
9
|
CountObjectsResult,
|
|
@@ -11,6 +17,7 @@ export type {
|
|
|
11
17
|
ObjectFacetBucket,
|
|
12
18
|
ObjectFacetRequest,
|
|
13
19
|
ObjectFacetResult,
|
|
20
|
+
ObjectLinkCursor,
|
|
14
21
|
ObjectLinkRow,
|
|
15
22
|
ObjectQueryCapabilities,
|
|
16
23
|
ObjectQueryCapabilityMap,
|
|
@@ -19,6 +26,8 @@ export type {
|
|
|
19
26
|
ObjectRow,
|
|
20
27
|
ObjectRowLinks,
|
|
21
28
|
ObjectStorage,
|
|
29
|
+
QueryObjectLinksInput,
|
|
30
|
+
QueryObjectLinksResult,
|
|
22
31
|
QueryObjectsInput,
|
|
23
32
|
QueryObjectsResult,
|
|
24
33
|
} from "./types"
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { ObjectLinkCursor, ObjectLinkRow } from "./types"
|
|
2
|
+
|
|
3
|
+
export type ObjectBatchKey = string & {
|
|
4
|
+
readonly __sixbObjectBatchKey: true
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export type LinkBatchKey = string & {
|
|
8
|
+
readonly __sixbLinkBatchKey: true
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/** Collision-safe key for object batch-read results. */
|
|
12
|
+
export function objectBatchKey(objectTypeId: string, primaryId: string): ObjectBatchKey {
|
|
13
|
+
return JSON.stringify([objectTypeId, primaryId]) as ObjectBatchKey
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/** Collision-safe key for outgoing-link batch-read results. */
|
|
17
|
+
export function linkBatchKey(objectTypeId: string, objectId: string, linkId: string): LinkBatchKey {
|
|
18
|
+
return JSON.stringify([objectTypeId, objectId, linkId]) as LinkBatchKey
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/** Canonical storage ordering and cursor for physical links. */
|
|
22
|
+
export function objectLinkCursor(link: ObjectLinkRow): ObjectLinkCursor {
|
|
23
|
+
return [link.sourceTypeId, link.sourceId, link.linkId, link.targetTypeId, link.targetId]
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export function compareObjectLinkCursors(left: ObjectLinkCursor, right: ObjectLinkCursor): number {
|
|
27
|
+
for (let index = 0; index < left.length; index += 1) {
|
|
28
|
+
if (left[index] < right[index]) return -1
|
|
29
|
+
if (left[index] > right[index]) return 1
|
|
30
|
+
}
|
|
31
|
+
return 0
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export function compareObjectLinks(left: ObjectLinkRow, right: ObjectLinkRow): number {
|
|
35
|
+
return compareObjectLinkCursors(objectLinkCursor(left), objectLinkCursor(right))
|
|
36
|
+
}
|
|
@@ -6,6 +6,7 @@ import type {
|
|
|
6
6
|
ObjectQuerySortField,
|
|
7
7
|
QueryScalarKind,
|
|
8
8
|
} from "../../objects/query"
|
|
9
|
+
import type { LinkBatchKey, ObjectBatchKey } from "./keys"
|
|
9
10
|
|
|
10
11
|
/**
|
|
11
12
|
* Latest-state projection storage for objects and links.
|
|
@@ -64,6 +65,26 @@ export interface ObjectLinkRow {
|
|
|
64
65
|
|
|
65
66
|
export type LinkDirection = "outgoing" | "incoming" | "both"
|
|
66
67
|
|
|
68
|
+
/** Stable physical-link order: source type/id, link id, then target type/id. */
|
|
69
|
+
export type ObjectLinkCursor = readonly [string, string, string, string, string]
|
|
70
|
+
|
|
71
|
+
export interface QueryObjectLinksInput {
|
|
72
|
+
projectId: string
|
|
73
|
+
/** Object identities are treated as a set; duplicate refs do not duplicate links. */
|
|
74
|
+
objectRefs: readonly { objectTypeId: string; primaryId: string }[]
|
|
75
|
+
direction: LinkDirection
|
|
76
|
+
linkId?: string
|
|
77
|
+
/** When present, both endpoints must belong to this set. An empty set matches no links. */
|
|
78
|
+
endpointObjectTypeIds?: readonly string[]
|
|
79
|
+
after?: ObjectLinkCursor
|
|
80
|
+
limit: number
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export interface QueryObjectLinksResult {
|
|
84
|
+
links: readonly ObjectLinkRow[]
|
|
85
|
+
hasMore: boolean
|
|
86
|
+
}
|
|
87
|
+
|
|
67
88
|
export type ObjectQueryCapabilityMap<T extends string> = Readonly<Partial<Record<T, boolean>>>
|
|
68
89
|
|
|
69
90
|
export type ObjectQueryScalarOperation = "equality" | "ordering"
|
|
@@ -192,27 +213,34 @@ export interface ObjectStorage {
|
|
|
192
213
|
|
|
193
214
|
/**
|
|
194
215
|
* Batch fetch objects by (objectTypeId, primaryId) pairs.
|
|
195
|
-
* Returns a Map keyed by
|
|
216
|
+
* Returns a Map keyed by {@link objectBatchKey}. Missing items are absent.
|
|
196
217
|
*/
|
|
197
218
|
getByPrimaryIdBatch(params: {
|
|
198
219
|
projectId: string
|
|
199
220
|
items: readonly { objectTypeId: string; primaryId: string }[]
|
|
200
|
-
}): Promise<
|
|
221
|
+
}): Promise<ReadonlyMap<ObjectBatchKey, ObjectRow>>
|
|
201
222
|
|
|
202
223
|
/**
|
|
203
224
|
* Batch fetch outgoing links by (objectTypeId, objectId, linkId) tuples.
|
|
204
|
-
* Returns a Map keyed by
|
|
225
|
+
* Returns a Map keyed by {@link linkBatchKey}. Missing entries are absent.
|
|
205
226
|
*/
|
|
206
227
|
listLinksBatch(params: {
|
|
207
228
|
projectId: string
|
|
208
229
|
items: readonly { objectTypeId: string; objectId: string; linkId: string }[]
|
|
209
|
-
}): Promise<
|
|
230
|
+
}): Promise<ReadonlyMap<LinkBatchKey, ObjectLinkRow[]>>
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* Read one canonical page of physical links incident to an object set.
|
|
234
|
+
* Filtering, endpoint-type scope, cursoring, ordering, and the limit are provider-owned so a
|
|
235
|
+
* bounded response never requires loading every incident link into the runtime.
|
|
236
|
+
*/
|
|
237
|
+
queryLinks(params: QueryObjectLinksInput): Promise<QueryObjectLinksResult>
|
|
210
238
|
|
|
211
239
|
/**
|
|
212
240
|
* Batch fetch every link incident to any of the given objects, in BOTH directions (the object as
|
|
213
241
|
* link source or target). Returns a flat, de-duplicated list: a physical link incident to two
|
|
214
|
-
* listed objects appears once.
|
|
215
|
-
*
|
|
242
|
+
* listed objects appears once. This unpaged primitive exists for internal materialization and
|
|
243
|
+
* per-parent expansion work; interactive reads use {@link queryLinks}.
|
|
216
244
|
*/
|
|
217
245
|
listIncidentLinksBatch(params: {
|
|
218
246
|
projectId: string
|
|
@@ -155,9 +155,9 @@ function assertProjectionTelemetryBatch(
|
|
|
155
155
|
if (source.sourceRowsSkipped > source.sourceRowCount) {
|
|
156
156
|
invalidCorrelation("Projection telemetry skipped rows exceed its source row count.")
|
|
157
157
|
}
|
|
158
|
-
if (source.sourceRowCount
|
|
158
|
+
if (inputPointCount < source.sourceRowCount - source.sourceRowsSkipped) {
|
|
159
159
|
invalidCorrelation(
|
|
160
|
-
"Projection telemetry
|
|
160
|
+
"Projection telemetry input points do not account for every non-skipped source row."
|
|
161
161
|
)
|
|
162
162
|
}
|
|
163
163
|
if (typeof source.inputExhausted !== "boolean") {
|
|
@@ -1077,6 +1077,18 @@ export function runAgentStorageContractSuite<TStorage extends AgentStorageContra
|
|
|
1077
1077
|
await storage.checkpoints.getLatest({ projectId: otherProjectId, threadId: "thr_1" })
|
|
1078
1078
|
).toBeNull()
|
|
1079
1079
|
expect(await storage.checkpoints.getLatest({ projectId, threadId: "thr_2" })).toBeNull()
|
|
1080
|
+
await expect(
|
|
1081
|
+
storage.checkpoints.getByRunIds({
|
|
1082
|
+
projectId,
|
|
1083
|
+
runIds: ["run_2", "missing", "run_2"],
|
|
1084
|
+
})
|
|
1085
|
+
).resolves.toEqual([created])
|
|
1086
|
+
await expect(
|
|
1087
|
+
storage.checkpoints.getByRunIds({
|
|
1088
|
+
projectId: otherProjectId,
|
|
1089
|
+
runIds: ["run_2"],
|
|
1090
|
+
})
|
|
1091
|
+
).resolves.toEqual([])
|
|
1080
1092
|
|
|
1081
1093
|
const retained = await storage.messages.list({
|
|
1082
1094
|
projectId,
|