@sixb/sqlite 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.
@@ -8,6 +8,10 @@ export declare class SqliteAgentContextCheckpointStore implements AgentContextCh
8
8
  readonly projectId: string;
9
9
  readonly threadId: string;
10
10
  }): Promise<AgentContextCheckpointRecord | null>;
11
+ getByRunIds(input: {
12
+ readonly projectId: string;
13
+ readonly runIds: readonly string[];
14
+ }): Promise<readonly AgentContextCheckpointRecord[]>;
11
15
  private findLatest;
12
16
  private requireById;
13
17
  }
@@ -1 +1 @@
1
- {"version":3,"file":"checkpoints.d.ts","sourceRoot":"","sources":["../../src/agents/checkpoints.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAQ1C,OAAO,EACL,KAAK,4BAA4B,EACjC,KAAK,2BAA2B,EAEhC,KAAK,iCAAiC,EACvC,MAAM,oBAAoB,CAAA;AAY3B,qBAAa,iCAAkC,YAAW,2BAA2B;IACvE,OAAO,CAAC,QAAQ,CAAC,EAAE;gBAAF,EAAE,EAAE,QAAQ;IAEnC,MAAM,CAAC,KAAK,EAAE,iCAAiC,GAAG,OAAO,CAAC,4BAA4B,CAAC;IAiHvF,SAAS,CAAC,KAAK,EAAE;QACrB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;QAC1B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;KAC1B,GAAG,OAAO,CAAC,4BAA4B,GAAG,IAAI,CAAC;IAIhD,OAAO,CAAC,UAAU;IAclB,OAAO,CAAC,WAAW;CAYpB"}
1
+ {"version":3,"file":"checkpoints.d.ts","sourceRoot":"","sources":["../../src/agents/checkpoints.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAQ1C,OAAO,EACL,KAAK,4BAA4B,EACjC,KAAK,2BAA2B,EAEhC,KAAK,iCAAiC,EACvC,MAAM,oBAAoB,CAAA;AAc3B,qBAAa,iCAAkC,YAAW,2BAA2B;IACvE,OAAO,CAAC,QAAQ,CAAC,EAAE;gBAAF,EAAE,EAAE,QAAQ;IAEnC,MAAM,CAAC,KAAK,EAAE,iCAAiC,GAAG,OAAO,CAAC,4BAA4B,CAAC;IAiHvF,SAAS,CAAC,KAAK,EAAE;QACrB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;QAC1B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;KAC1B,GAAG,OAAO,CAAC,4BAA4B,GAAG,IAAI,CAAC;IAI1C,WAAW,CAAC,KAAK,EAAE;QACvB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;QAC1B,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAA;KACnC,GAAG,OAAO,CAAC,SAAS,4BAA4B,EAAE,CAAC;IAyBpD,OAAO,CAAC,UAAU;IAclB,OAAO,CAAC,WAAW;CAYpB"}
@@ -1,4 +1,4 @@
1
- import { type AiUsageExecutionSummary, type AiUsageStorage, type RecordAiModelCallInput, type RecordAiModelCallResult, type SummarizeAiUsageExecutionInput, type SummarizeAiUsageExecutionsInput } from "@sixb/core/storage";
1
+ import { type AiModelCallUsageRecord, type AiUsageExecutionSummary, type AiUsageStorage, type GetLatestAiModelCallForExecutionInput, type RecordAiModelCallInput, type RecordAiModelCallResult, type SummarizeAiUsageExecutionInput, type SummarizeAiUsageExecutionsInput } from "@sixb/core/storage";
2
2
  import { type SqliteStoreConnection } from "./transactions";
3
3
  export interface SqliteAiUsageStorageOptions {
4
4
  readonly path?: string;
@@ -10,6 +10,7 @@ export declare class SqliteAiUsageStorage implements AiUsageStorage {
10
10
  constructor(options?: SqliteAiUsageStorageOptions);
11
11
  recordModelCall(input: RecordAiModelCallInput): Promise<RecordAiModelCallResult>;
12
12
  summarizeExecution(input: SummarizeAiUsageExecutionInput): Promise<AiUsageExecutionSummary>;
13
+ getLatestForExecution(input: GetLatestAiModelCallForExecutionInput): Promise<AiModelCallUsageRecord | null>;
13
14
  summarizeExecutions(input: SummarizeAiUsageExecutionsInput): Promise<readonly AiUsageExecutionSummary[]>;
14
15
  close(): void;
15
16
  private insertRecord;
@@ -1 +1 @@
1
- {"version":3,"file":"ai-usage-storage.d.ts","sourceRoot":"","sources":["../src/ai-usage-storage.ts"],"names":[],"mappings":"AACA,OAAO,EAGL,KAAK,uBAAuB,EAC5B,KAAK,cAAc,EAKnB,KAAK,sBAAsB,EAC3B,KAAK,uBAAuB,EAC5B,KAAK,8BAA8B,EACnC,KAAK,+BAA+B,EACrC,MAAM,oBAAoB,CAAA;AAG3B,OAAO,EAIL,KAAK,qBAAqB,EAC3B,MAAM,gBAAgB,CAAA;AAEvB,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,UAAU,CAAC,EAAE,qBAAqB,CAAA;CAC5C;AAED,yDAAyD;AACzD,qBAAa,oBAAqB,YAAW,cAAc;IACzD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAuB;gBAEtC,OAAO,GAAE,2BAAgC;IAO/C,eAAe,CAAC,KAAK,EAAE,sBAAsB,GAAG,OAAO,CAAC,uBAAuB,CAAC;IAoChF,kBAAkB,CACtB,KAAK,EAAE,8BAA8B,GACpC,OAAO,CAAC,uBAAuB,CAAC;IAQ7B,mBAAmB,CACvB,KAAK,EAAE,+BAA+B,GACrC,OAAO,CAAC,SAAS,uBAAuB,EAAE,CAAC;IAS9C,KAAK,IAAI,IAAI;IAIb,OAAO,CAAC,YAAY;IAwDpB,OAAO,CAAC,oBAAoB;IA2B5B,OAAO,CAAC,WAAW;IAQnB,OAAO,CAAC,WAAW;IAmCnB,OAAO,CAAC,aAAa;IAkBrB,OAAO,CAAC,qBAAqB;CAU9B"}
1
+ {"version":3,"file":"ai-usage-storage.d.ts","sourceRoot":"","sources":["../src/ai-usage-storage.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,KAAK,sBAAsB,EAC3B,KAAK,uBAAuB,EAC5B,KAAK,cAAc,EAInB,KAAK,qCAAqC,EAE1C,KAAK,sBAAsB,EAC3B,KAAK,uBAAuB,EAC5B,KAAK,8BAA8B,EACnC,KAAK,+BAA+B,EACrC,MAAM,oBAAoB,CAAA;AAG3B,OAAO,EAIL,KAAK,qBAAqB,EAC3B,MAAM,gBAAgB,CAAA;AAEvB,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,UAAU,CAAC,EAAE,qBAAqB,CAAA;CAC5C;AAED,yDAAyD;AACzD,qBAAa,oBAAqB,YAAW,cAAc;IACzD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAuB;gBAEtC,OAAO,GAAE,2BAAgC;IAO/C,eAAe,CAAC,KAAK,EAAE,sBAAsB,GAAG,OAAO,CAAC,uBAAuB,CAAC;IAoChF,kBAAkB,CACtB,KAAK,EAAE,8BAA8B,GACpC,OAAO,CAAC,uBAAuB,CAAC;IAQ7B,qBAAqB,CACzB,KAAK,EAAE,qCAAqC,GAC3C,OAAO,CAAC,sBAAsB,GAAG,IAAI,CAAC;IAgBnC,mBAAmB,CACvB,KAAK,EAAE,+BAA+B,GACrC,OAAO,CAAC,SAAS,uBAAuB,EAAE,CAAC;IAS9C,KAAK,IAAI,IAAI;IAIb,OAAO,CAAC,YAAY;IAwDpB,OAAO,CAAC,oBAAoB;IA2B5B,OAAO,CAAC,WAAW;IAQnB,OAAO,CAAC,WAAW;IAmCnB,OAAO,CAAC,aAAa;IAkBrB,OAAO,CAAC,qBAAqB;CAU9B"}
package/dist/index.js CHANGED
@@ -3844,6 +3844,8 @@ function queryAgentList(input) {
3844
3844
  }
3845
3845
 
3846
3846
  // src/agents/checkpoints.ts
3847
+ var SQLITE_CHECKPOINT_RUN_ID_BATCH_SIZE = 500;
3848
+
3847
3849
  class SqliteAgentContextCheckpointStore {
3848
3850
  db;
3849
3851
  constructor(db) {
@@ -3914,6 +3916,22 @@ class SqliteAgentContextCheckpointStore {
3914
3916
  async getLatest(input) {
3915
3917
  return this.findLatest(input.projectId, input.threadId);
3916
3918
  }
3919
+ async getByRunIds(input) {
3920
+ const runIds = [...new Set(input.runIds)];
3921
+ if (runIds.length === 0)
3922
+ return [];
3923
+ const rows = [];
3924
+ for (let offset = 0;offset < runIds.length; offset += SQLITE_CHECKPOINT_RUN_ID_BATCH_SIZE) {
3925
+ const batch = runIds.slice(offset, offset + SQLITE_CHECKPOINT_RUN_ID_BATCH_SIZE);
3926
+ const placeholders = batch.map(() => "?").join(", ");
3927
+ rows.push(...this.db.query(`SELECT * FROM agent_context_checkpoints WHERE project_id = ? AND created_by_run_id IN (${placeholders})`).all(input.projectId, ...batch));
3928
+ }
3929
+ const byRunId = new Map(rows.map((row) => [row.created_by_run_id, rowToContextCheckpointRecord(row)]));
3930
+ return runIds.flatMap((runId) => {
3931
+ const checkpoint = byRunId.get(runId);
3932
+ return checkpoint ? [checkpoint] : [];
3933
+ });
3934
+ }
3917
3935
  findLatest(projectId, threadId) {
3918
3936
  const row = this.db.query(`
3919
3937
  SELECT * FROM agent_context_checkpoints
@@ -4974,6 +4992,17 @@ class SqliteAiUsageStorage {
4974
4992
  });
4975
4993
  return summary;
4976
4994
  }
4995
+ async getLatestForExecution(input) {
4996
+ assertNonBlankProjectId(input.projectId);
4997
+ assertAiUsageExecutionId(input.executionId);
4998
+ const row = this.connection.db.query(`
4999
+ SELECT * FROM ai_model_call_usage
5000
+ WHERE project_id = ? AND execution_id = ?
5001
+ ORDER BY occurred_at DESC, id DESC
5002
+ LIMIT 1
5003
+ `).get(input.projectId, input.executionId);
5004
+ return row ? this.rowToRecord(row) : null;
5005
+ }
4977
5006
  async summarizeExecutions(input) {
4978
5007
  assertNonBlankProjectId(input.projectId);
4979
5008
  for (const executionId of input.executionIds)
@@ -7592,6 +7621,9 @@ function isDuplicateExecutionError(error) {
7592
7621
  return error instanceof Error && error.message.includes("UNIQUE constraint failed: executions.project_id, executions.id");
7593
7622
  }
7594
7623
 
7624
+ // src/object-storage.ts
7625
+ import { linkBatchKey, objectBatchKey } from "@sixb/core/storage";
7626
+
7595
7627
  // src/object-query-compiler.ts
7596
7628
  import {
7597
7629
  ObjectQueryExecutionError
@@ -7607,6 +7639,8 @@ function compileObjectQueryInternal(projectId, query, ctx) {
7607
7639
  switch (query.kind) {
7608
7640
  case "start":
7609
7641
  return compileStart(projectId, query);
7642
+ case "refs":
7643
+ return compileRefs(projectId, query);
7610
7644
  case "filter":
7611
7645
  return compileFilter(projectId, query.input, query.predicate);
7612
7646
  case "sort":
@@ -7654,6 +7688,50 @@ function compileStart(projectId, query) {
7654
7688
  }
7655
7689
  };
7656
7690
  }
7691
+ function compileRefs(projectId, query) {
7692
+ if (query.refs.length === 0) {
7693
+ throw new Error("[Sixb] SQLite object storage requires at least one ref");
7694
+ }
7695
+ const order = compileOrder(identityOrderFields());
7696
+ const selectedOrder = compileOrder(identityOrderFields(), "selected");
7697
+ const refsJson = JSON.stringify(query.refs);
7698
+ const requested = `
7699
+ SELECT DISTINCT
7700
+ json_extract(ref.value, '$.objectTypeId') AS object_type_id,
7701
+ json_extract(ref.value, '$.primaryId') AS primary_id
7702
+ FROM json_each(?) AS ref
7703
+ `;
7704
+ const sql = `
7705
+ WITH requested AS (${requested})
7706
+ SELECT selected.*, selected.properties AS _cursor_properties
7707
+ FROM requested
7708
+ JOIN objects AS selected
7709
+ ON selected.project_id = ?
7710
+ AND selected.object_type_id = requested.object_type_id
7711
+ AND selected.primary_id = requested.primary_id
7712
+ ORDER BY ${selectedOrder.sql}
7713
+ `;
7714
+ return {
7715
+ sql,
7716
+ args: [refsJson, projectId, ...selectedOrder.args],
7717
+ totalSql: `
7718
+ WITH requested AS (${requested})
7719
+ SELECT COUNT(*) AS total
7720
+ FROM requested
7721
+ JOIN objects AS selected
7722
+ ON selected.project_id = ?
7723
+ AND selected.object_type_id = requested.object_type_id
7724
+ AND selected.primary_id = requested.primary_id
7725
+ `,
7726
+ totalArgs: [refsJson, projectId],
7727
+ order,
7728
+ hasMore: () => false,
7729
+ trimRows: identityRows,
7730
+ nextPageToken: () => {
7731
+ return;
7732
+ }
7733
+ };
7734
+ }
7657
7735
  function compileFilter(projectId, inputQuery, predicateNode) {
7658
7736
  const predicate = compilePredicate(predicateNode);
7659
7737
  return compileWhere(projectId, inputQuery, predicate);
@@ -8397,6 +8475,7 @@ var SQLITE_OBJECT_QUERY_CAPABILITIES = {
8397
8475
  facetObjects: true,
8398
8476
  nodes: {
8399
8477
  start: true,
8478
+ refs: true,
8400
8479
  filter: true,
8401
8480
  text: true,
8402
8481
  sort: true,
@@ -8448,7 +8527,7 @@ var SQLITE_OBJECT_QUERY_CAPABILITIES = {
8448
8527
  stablePageTokens: true
8449
8528
  },
8450
8529
  notes: [
8451
- "SQLite object query pushdown supports start/filter/text/sort/limit/page/traverse/set/project/expand over JSON properties and object links.",
8530
+ "SQLite object query pushdown supports start/refs/filter/text/sort/limit/page/traverse/set/project/expand over JSON properties and object links.",
8452
8531
  "expand hydrates linked objects in-database (top-N per parent via row_number() + json_group_array); core resolves each expansion's cardinality before pushdown, and a mixed/unresolved one stays on the fallback.",
8453
8532
  "Ordered decimal predicates and sorting use the bounded core fallback because SQLite has no native exact decimal type; canonical decimal equality remains pushdown-safe.",
8454
8533
  "Relevance sorting, vector search, and unresolved start.includeSubtypes remain planner fallback or rejection cases."
@@ -8527,12 +8606,16 @@ class SqliteObjectStorage {
8527
8606
  const result = new Map;
8528
8607
  if (params.items.length === 0)
8529
8608
  return result;
8530
- const stmt = this.db.query("SELECT * FROM objects WHERE project_id = ? AND object_type_id = ? AND primary_id = ?");
8531
- for (const item of params.items) {
8532
- const row = stmt.get(params.projectId, item.objectTypeId, item.primaryId);
8533
- if (row) {
8534
- result.set(`${item.objectTypeId}:${item.primaryId}`, this.rowToObject(row));
8535
- }
8609
+ const rows = this.db.query(`
8610
+ SELECT object.*
8611
+ FROM json_each(?) AS requested
8612
+ JOIN objects AS object
8613
+ ON object.project_id = ?
8614
+ AND object.object_type_id = json_extract(requested.value, '$.objectTypeId')
8615
+ AND object.primary_id = json_extract(requested.value, '$.primaryId')
8616
+ `).all(JSON.stringify(params.items), params.projectId);
8617
+ for (const row of rows) {
8618
+ result.set(objectBatchKey(row.object_type_id, row.primary_id), this.rowToObject(row));
8536
8619
  }
8537
8620
  return result;
8538
8621
  }
@@ -8544,25 +8627,95 @@ class SqliteObjectStorage {
8544
8627
  for (const item of params.items) {
8545
8628
  const rows = stmt.all(params.projectId, item.objectTypeId, item.objectId, item.linkId);
8546
8629
  if (rows.length > 0) {
8547
- result.set(`${item.objectTypeId}:${item.objectId}:${item.linkId}`, rows.map((r) => this.rowToLink(r)));
8630
+ result.set(linkBatchKey(item.objectTypeId, item.objectId, item.linkId), rows.map((r) => this.rowToLink(r)));
8548
8631
  }
8549
8632
  }
8550
8633
  return result;
8551
8634
  }
8552
- async listIncidentLinksBatch(params) {
8553
- const deduped = new Map;
8554
- for (const item of params.items) {
8555
- const rows = await this.listLinks({
8556
- projectId: params.projectId,
8557
- objectTypeId: item.objectTypeId,
8558
- objectId: item.objectId,
8559
- direction: "both"
8560
- });
8561
- for (const row of rows) {
8562
- deduped.set(`${row.sourceTypeId}:${row.sourceId}:${row.linkId}:${row.targetTypeId}:${row.targetId}`, row);
8563
- }
8635
+ async queryLinks(params) {
8636
+ assertLinkQueryLimit(params.limit);
8637
+ if (params.objectRefs.length === 0 || params.endpointObjectTypeIds?.length === 0) {
8638
+ return { links: [], hasMore: false };
8639
+ }
8640
+ const sourceJoin = `
8641
+ SELECT link.*
8642
+ FROM links AS link
8643
+ JOIN requested
8644
+ ON requested.object_type_id = link.source_type_id
8645
+ AND requested.object_id = link.source_id
8646
+ WHERE link.project_id = ?
8647
+ `;
8648
+ const targetJoin = `
8649
+ SELECT link.*
8650
+ FROM links AS link
8651
+ JOIN requested
8652
+ ON requested.object_type_id = link.target_type_id
8653
+ AND requested.object_id = link.target_id
8654
+ WHERE link.project_id = ?
8655
+ `;
8656
+ const incidentSql = params.direction === "outgoing" ? sourceJoin : params.direction === "incoming" ? targetJoin : `${sourceJoin} UNION ${targetJoin}`;
8657
+ const args = [JSON.stringify(params.objectRefs), params.projectId];
8658
+ if (params.direction === "both")
8659
+ args.push(params.projectId);
8660
+ const predicates = [];
8661
+ if (params.linkId !== undefined) {
8662
+ predicates.push("link_id = ?");
8663
+ args.push(params.linkId);
8564
8664
  }
8565
- return [...deduped.values()];
8665
+ if (params.endpointObjectTypeIds !== undefined) {
8666
+ const allowedTypes = JSON.stringify([...new Set(params.endpointObjectTypeIds)]);
8667
+ predicates.push("source_type_id IN (SELECT value FROM json_each(?))", "target_type_id IN (SELECT value FROM json_each(?))");
8668
+ args.push(allowedTypes, allowedTypes);
8669
+ }
8670
+ if (params.after) {
8671
+ predicates.push("(source_type_id, source_id, link_id, target_type_id, target_id) > (?, ?, ?, ?, ?)");
8672
+ args.push(...params.after);
8673
+ }
8674
+ args.push(params.limit + 1);
8675
+ const whereSql = predicates.length > 0 ? `WHERE ${predicates.join(" AND ")}` : "";
8676
+ const rows = this.db.query(`
8677
+ WITH requested AS (
8678
+ SELECT DISTINCT
8679
+ json_extract(value, '$.objectTypeId') AS object_type_id,
8680
+ json_extract(value, '$.primaryId') AS object_id
8681
+ FROM json_each(?)
8682
+ ), incident AS (${incidentSql})
8683
+ SELECT *
8684
+ FROM incident
8685
+ ${whereSql}
8686
+ ORDER BY source_type_id, source_id, link_id, target_type_id, target_id
8687
+ LIMIT ?
8688
+ `).all(...args);
8689
+ return {
8690
+ links: rows.slice(0, params.limit).map((row) => this.rowToLink(row)),
8691
+ hasMore: rows.length > params.limit
8692
+ };
8693
+ }
8694
+ async listIncidentLinksBatch(params) {
8695
+ if (params.items.length === 0)
8696
+ return [];
8697
+ const rows = this.db.query(`
8698
+ WITH requested AS (
8699
+ SELECT
8700
+ json_extract(value, '$.objectTypeId') AS object_type_id,
8701
+ json_extract(value, '$.objectId') AS object_id
8702
+ FROM json_each(?)
8703
+ )
8704
+ SELECT link.*
8705
+ FROM links AS link
8706
+ JOIN requested
8707
+ ON requested.object_type_id = link.source_type_id
8708
+ AND requested.object_id = link.source_id
8709
+ WHERE link.project_id = ?
8710
+ UNION
8711
+ SELECT link.*
8712
+ FROM links AS link
8713
+ JOIN requested
8714
+ ON requested.object_type_id = link.target_type_id
8715
+ AND requested.object_id = link.target_id
8716
+ WHERE link.project_id = ?
8717
+ `).all(JSON.stringify(params.items), params.projectId, params.projectId);
8718
+ return rows.map((row) => this.rowToLink(row));
8566
8719
  }
8567
8720
  async listByPrimaryIdPage(params) {
8568
8721
  assertReconciliationPageLimit(params.limit);
@@ -8674,6 +8827,11 @@ function assertReconciliationPageLimit(limit) {
8674
8827
  throw new Error("Object reconciliation page limit must be a positive safe integer.");
8675
8828
  }
8676
8829
  }
8830
+ function assertLinkQueryLimit(limit) {
8831
+ if (!Number.isSafeInteger(limit) || limit <= 0) {
8832
+ throw new Error("Object link query limit must be a positive safe integer.");
8833
+ }
8834
+ }
8677
8835
  function readTotal(db, compiled) {
8678
8836
  const row = db.query(compiled.totalSql).get(...compiled.totalArgs);
8679
8837
  return row.total;
@@ -13913,4 +14071,4 @@ export {
13913
14071
  SqliteStorage
13914
14072
  };
13915
14073
 
13916
- //# debugId=3913310C430C57B764756E2164756E21
14074
+ //# debugId=2D24EFD822513C9E64756E2164756E21