@sixb/pg 0.1.2 → 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/agents/agent-storage.d.ts +5 -3
- package/dist/agents/agent-storage.d.ts.map +1 -1
- package/dist/agents/checkpoints.d.ts +16 -0
- package/dist/agents/checkpoints.d.ts.map +1 -0
- package/dist/agents/index.d.ts +1 -0
- package/dist/agents/index.d.ts.map +1 -1
- package/dist/agents/messages.d.ts +2 -1
- package/dist/agents/messages.d.ts.map +1 -1
- package/dist/agents/rows.d.ts +18 -1
- package/dist/agents/rows.d.ts.map +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1028 -35
- package/dist/index.js.map +15 -13
- package/dist/migrations.d.ts.map +1 -1
- package/dist/ontology-storage/materialization-state.d.ts.map +1 -1
- package/dist/ontology-storage/materialization-writer.d.ts.map +1 -1
- package/dist/pg-ai-cost-storage.d.ts +12 -0
- package/dist/pg-ai-cost-storage.d.ts.map +1 -0
- package/dist/pg-ai-usage-storage.d.ts +2 -1
- package/dist/pg-ai-usage-storage.d.ts.map +1 -1
- package/dist/pg-object-storage.d.ts +4 -3
- package/dist/pg-object-storage.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/agents/agent-storage.ts +6 -3
- package/src/agents/checkpoints.ts +204 -0
- package/src/agents/index.ts +1 -0
- package/src/agents/messages.ts +71 -13
- package/src/agents/rows.ts +45 -0
- package/src/index.ts +7 -1
- package/src/migrations/026-ai-cost-accounting.sql +53 -0
- package/src/migrations/027-agent-context-checkpoints.sql +34 -0
- package/src/migrations/028-object-override-edit-times.sql +3 -0
- package/src/migrations.ts +10 -0
- package/src/ontology-storage/materialization-state.ts +2 -0
- package/src/ontology-storage/materialization-writer.ts +5 -3
- package/src/pg-ai-cost-storage.ts +707 -0
- package/src/pg-ai-usage-storage.ts +15 -0
- package/src/pg-object-query-compiler.ts +81 -1
- package/src/pg-object-storage.ts +109 -13
package/dist/migrations.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"migrations.d.ts","sourceRoot":"","sources":["../src/migrations.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AACjD,OAAO,KAAK,EAGV,YAAY,EACZ,aAAa,EACb,oBAAoB,EACrB,MAAM,oBAAoB,CAAA;
|
|
1
|
+
{"version":3,"file":"migrations.d.ts","sourceRoot":"","sources":["../src/migrations.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AACjD,OAAO,KAAK,EAGV,YAAY,EACZ,aAAa,EACb,oBAAoB,EACrB,MAAM,oBAAoB,CAAA;AAmE3B,OAAO,KAAK,EAAE,GAAG,EAAa,MAAM,aAAa,CAAA;AAEjD,MAAM,WAAW,wBAAwB;IACvC,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CACrC;AAED,eAAO,MAAM,2BAA2B,wBAAwB,CAAA;AAEhE,wBAAgB,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,aAAa,CAAC,wBAAwB,CAAC,CAE1F;AAED,wBAAgB,MAAM,CACpB,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,CAAC,OAAO,EAAE,wBAAwB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,EAC/D,OAAO,GAAE,oBAAyB,GACjC,aAAa,CAAC,wBAAwB,CAAC,CAEzC;AAED,wBAAgB,8BAA8B,CAC5C,GAAG,EAAE,GAAG,EACR,UAAU,EAAE,MAAM,GACjB,SAAS,eAAe,EAAE,CAQ5B;AAED,wBAAgB,sBAAsB,CAAC,MAAM,EAAE;IAC7C,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAA;IACjB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,QAAQ,CAAC,UAAU,EAAE,YAAY,CAAC,wBAAwB,CAAC,CAAA;CAC5D,GAAG,eAAe,CAqBlB;AAED,wBAAsB,sBAAsB,CAAC,GAAG,EAAE,GAAG,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAMxF;AAED,wBAAsB,UAAU,CAAC,GAAG,EAAE,GAAG,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE5E;AAED,wBAAgB,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAKrD;AA6KD,eAAO,MAAM,yBAAyB,wCAgCpC,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"materialization-state.d.ts","sourceRoot":"","sources":["../../src/ontology-storage/materialization-state.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAGV,eAAe,EACf,iBAAiB,EAEjB,kBAAkB,EACnB,MAAM,qCAAqC,CAAA;AAgB5C,OAAO,KAAK,EACV,6BAA6B,EAC7B,wBAAwB,EACxB,0BAA0B,EAC1B,0BAA0B,EAC1B,4BAA4B,EAO5B,oBAAoB,EACrB,MAAM,oBAAoB,CAAA;AAC3B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA;AAW7C,eAAO,MAAM,6BAA6B,kCAAkC,CAAA;AAC5E,eAAO,MAAM,yBAAyB,8BAA8B,CAAA;
|
|
1
|
+
{"version":3,"file":"materialization-state.d.ts","sourceRoot":"","sources":["../../src/ontology-storage/materialization-state.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"materialization-writer.d.ts","sourceRoot":"","sources":["../../src/ontology-storage/materialization-writer.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,oBAAoB,CAAA;AAClE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA;AAG7C,oFAAoF;AACpF,qBAAa,uBAAuB;IACtB,OAAO,CAAC,QAAQ,CAAC,GAAG;gBAAH,GAAG,EAAE,SAAS;IAErC,KAAK,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,wBAAwB,GAAG,OAAO,CAAC,IAAI,CAAC;YAOlF,cAAc;
|
|
1
|
+
{"version":3,"file":"materialization-writer.d.ts","sourceRoot":"","sources":["../../src/ontology-storage/materialization-writer.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,oBAAoB,CAAA;AAClE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA;AAG7C,oFAAoF;AACpF,qBAAa,uBAAuB;IACtB,OAAO,CAAC,QAAQ,CAAC,GAAG;gBAAH,GAAG,EAAE,SAAS;IAErC,KAAK,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,wBAAwB,GAAG,OAAO,CAAC,IAAI,CAAC;YAOlF,cAAc;YA2Kd,cAAc;YAqDd,YAAY;YA+DZ,UAAU;YAqEV,eAAe;YA+Ff,WAAW;CAwC1B"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type AiAccountingOverview, type AiCostStorage, type AiCostSummary, type AiModelCallCostRecord, type ListAiModelCallAccountingInput, type ListAiModelCallAccountingResult, type QueryAiAccountingOverviewInput, type SummarizeAiCostExecutionsInput } from "@sixb/core/storage";
|
|
2
|
+
import type { PgStoreClient } from "./transactions";
|
|
3
|
+
/** PostgreSQL-backed immutable valuations stored in one append-only table. */
|
|
4
|
+
export declare class PgAiCostStorage implements AiCostStorage {
|
|
5
|
+
private readonly sql;
|
|
6
|
+
constructor(sql: PgStoreClient);
|
|
7
|
+
recordModelCallCost(input: AiModelCallCostRecord): Promise<void>;
|
|
8
|
+
summarizeExecutions(input: SummarizeAiCostExecutionsInput): Promise<readonly AiCostSummary[]>;
|
|
9
|
+
queryProjectOverview(input: QueryAiAccountingOverviewInput): Promise<AiAccountingOverview>;
|
|
10
|
+
listModelCalls(input: ListAiModelCallAccountingInput): Promise<ListAiModelCallAccountingResult>;
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=pg-ai-cost-storage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pg-ai-cost-storage.d.ts","sourceRoot":"","sources":["../src/pg-ai-cost-storage.ts"],"names":[],"mappings":"AAaA,OAAO,EACL,KAAK,oBAAoB,EACzB,KAAK,aAAa,EAElB,KAAK,aAAa,EAClB,KAAK,qBAAqB,EAE1B,KAAK,8BAA8B,EACnC,KAAK,+BAA+B,EACpC,KAAK,8BAA8B,EACnC,KAAK,8BAA8B,EACpC,MAAM,oBAAoB,CAAA;AAC3B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAA;AAGnD,8EAA8E;AAC9E,qBAAa,eAAgB,YAAW,aAAa;IACvC,OAAO,CAAC,QAAQ,CAAC,GAAG;gBAAH,GAAG,EAAE,aAAa;IAEzC,mBAAmB,CAAC,KAAK,EAAE,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC;IA6BhE,mBAAmB,CACvB,KAAK,EAAE,8BAA8B,GACpC,OAAO,CAAC,SAAS,aAAa,EAAE,CAAC;IAsB9B,oBAAoB,CAAC,KAAK,EAAE,8BAA8B,GAAG,OAAO,CAAC,oBAAoB,CAAC;IA6G1F,cAAc,CAClB,KAAK,EAAE,8BAA8B,GACpC,OAAO,CAAC,+BAA+B,CAAC;CAsF5C"}
|
|
@@ -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 PgStoreClient } from "./transactions";
|
|
3
3
|
/** PostgreSQL-backed append-only model-call usage ledger. */
|
|
4
4
|
export declare class PgAiUsageStorage implements AiUsageStorage {
|
|
@@ -6,6 +6,7 @@ export declare class PgAiUsageStorage implements AiUsageStorage {
|
|
|
6
6
|
constructor(sql: PgStoreClient);
|
|
7
7
|
recordModelCall(input: RecordAiModelCallInput): Promise<RecordAiModelCallResult>;
|
|
8
8
|
summarizeExecution(input: SummarizeAiUsageExecutionInput): Promise<AiUsageExecutionSummary>;
|
|
9
|
+
getLatestForExecution(input: GetLatestAiModelCallForExecutionInput): Promise<AiModelCallUsageRecord | null>;
|
|
9
10
|
summarizeExecutions(input: SummarizeAiUsageExecutionsInput): Promise<readonly AiUsageExecutionSummary[]>;
|
|
10
11
|
private findByIdempotencyKey;
|
|
11
12
|
private requireById;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pg-ai-usage-storage.d.ts","sourceRoot":"","sources":["../src/pg-ai-usage-storage.ts"],"names":[],"mappings":"AACA,OAAO,
|
|
1
|
+
{"version":3,"file":"pg-ai-usage-storage.d.ts","sourceRoot":"","sources":["../src/pg-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;AAE3B,OAAO,EAAE,KAAK,aAAa,EAAoB,MAAM,gBAAgB,CAAA;AAErE,6DAA6D;AAC7D,qBAAa,gBAAiB,YAAW,cAAc;IACzC,OAAO,CAAC,QAAQ,CAAC,GAAG;gBAAH,GAAG,EAAE,aAAa;IAEzC,eAAe,CAAC,KAAK,EAAE,sBAAsB,GAAG,OAAO,CAAC,uBAAuB,CAAC;IAgFhF,kBAAkB,CACtB,KAAK,EAAE,8BAA8B,GACpC,OAAO,CAAC,uBAAuB,CAAC;IAQ7B,qBAAqB,CACzB,KAAK,EAAE,qCAAqC,GAC3C,OAAO,CAAC,sBAAsB,GAAG,IAAI,CAAC;IAYnC,mBAAmB,CACvB,KAAK,EAAE,+BAA+B,GACrC,OAAO,CAAC,SAAS,uBAAuB,EAAE,CAAC;YAShC,oBAAoB;YAkBpB,WAAW;YAYX,WAAW;IA6BzB,OAAO,CAAC,aAAa;YAiBP,qBAAqB;CAgBpC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { CountObjectsInput, CountObjectsResult, ExistsObjectsInput, ExistsObjectsResult, FacetObjectsInput, FacetObjectsResult, LinkDirection, ObjectLinkRow, ObjectQueryCapabilities, ObjectRow, ObjectStorage, QueryObjectsInput, QueryObjectsResult } from "@sixb/core/storage";
|
|
1
|
+
import type { CountObjectsInput, CountObjectsResult, ExistsObjectsInput, ExistsObjectsResult, FacetObjectsInput, FacetObjectsResult, LinkBatchKey, LinkDirection, ObjectBatchKey, ObjectLinkRow, ObjectQueryCapabilities, ObjectRow, ObjectStorage, QueryObjectLinksInput, QueryObjectLinksResult, QueryObjectsInput, QueryObjectsResult } from "@sixb/core/storage";
|
|
2
2
|
import type { PgStoreClient } from "./transactions";
|
|
3
3
|
/**
|
|
4
4
|
* PostgreSQL-based ObjectStorage implementation.
|
|
@@ -43,7 +43,7 @@ export declare class PgObjectStorage implements ObjectStorage {
|
|
|
43
43
|
objectTypeId: string;
|
|
44
44
|
primaryId: string;
|
|
45
45
|
}[];
|
|
46
|
-
}): Promise<Map<
|
|
46
|
+
}): Promise<Map<ObjectBatchKey, ObjectRow>>;
|
|
47
47
|
listLinksBatch(params: {
|
|
48
48
|
projectId: string;
|
|
49
49
|
items: readonly {
|
|
@@ -51,7 +51,8 @@ export declare class PgObjectStorage implements ObjectStorage {
|
|
|
51
51
|
objectId: string;
|
|
52
52
|
linkId: string;
|
|
53
53
|
}[];
|
|
54
|
-
}): Promise<Map<
|
|
54
|
+
}): Promise<Map<LinkBatchKey, ObjectLinkRow[]>>;
|
|
55
|
+
queryLinks(params: QueryObjectLinksInput): Promise<QueryObjectLinksResult>;
|
|
55
56
|
listIncidentLinksBatch(params: {
|
|
56
57
|
projectId: string;
|
|
57
58
|
items: readonly {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pg-object-storage.d.ts","sourceRoot":"","sources":["../src/pg-object-storage.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,iBAAiB,EACjB,kBAAkB,EAClB,kBAAkB,EAClB,mBAAmB,EAGnB,iBAAiB,EACjB,kBAAkB,EAClB,aAAa,EACb,aAAa,EACb,uBAAuB,EACvB,SAAS,EAET,aAAa,EACb,iBAAiB,EACjB,kBAAkB,EACnB,MAAM,oBAAoB,CAAA;
|
|
1
|
+
{"version":3,"file":"pg-object-storage.d.ts","sourceRoot":"","sources":["../src/pg-object-storage.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sixb/pg",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.4",
|
|
4
4
|
"description": "PostgreSQL storage provider for Sixb",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"sixb",
|
|
@@ -40,10 +40,10 @@
|
|
|
40
40
|
"postgres": "^3.4.5"
|
|
41
41
|
},
|
|
42
42
|
"peerDependencies": {
|
|
43
|
-
"@sixb/core": "0.1.
|
|
43
|
+
"@sixb/core": "0.1.4"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
|
-
"@sixb/core": "0.1.
|
|
46
|
+
"@sixb/core": "0.1.4",
|
|
47
47
|
"@types/bun": "latest",
|
|
48
48
|
"typescript": "^5.7.0"
|
|
49
49
|
},
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { AgentStorage, ExecutionStorage } from "@sixb/core/storage"
|
|
2
2
|
import type { PgStoreClient } from "../transactions"
|
|
3
|
+
import { PgAgentContextCheckpointStore } from "./checkpoints"
|
|
3
4
|
import { PgAgentMessageStore } from "./messages"
|
|
4
5
|
import { PgAgentRunStore } from "./runs"
|
|
5
6
|
import { PgAgentThreadStore } from "./threads"
|
|
@@ -10,18 +11,20 @@ export interface PgAgentStorageOptions {
|
|
|
10
11
|
}
|
|
11
12
|
|
|
12
13
|
/**
|
|
13
|
-
* PostgreSQL-backed agent persistence: thread
|
|
14
|
-
* Cross-table writes
|
|
15
|
-
*
|
|
14
|
+
* PostgreSQL-backed agent persistence: thread, run, message, and context-checkpoint sub-stores
|
|
15
|
+
* sharing one connection. Cross-table writes run inside `runPgTransaction` with `SELECT ... FOR
|
|
16
|
+
* UPDATE` row locks for single-flight and checkpoint compare-and-swap safety.
|
|
16
17
|
*/
|
|
17
18
|
export class PgAgentStorage implements AgentStorage {
|
|
18
19
|
readonly threads: PgAgentThreadStore
|
|
19
20
|
readonly runs: PgAgentRunStore
|
|
20
21
|
readonly messages: PgAgentMessageStore
|
|
22
|
+
readonly checkpoints: PgAgentContextCheckpointStore
|
|
21
23
|
|
|
22
24
|
constructor(options: PgAgentStorageOptions) {
|
|
23
25
|
this.threads = new PgAgentThreadStore(options.sql)
|
|
24
26
|
this.runs = new PgAgentRunStore(options.sql, options.executions)
|
|
25
27
|
this.messages = new PgAgentMessageStore(options.sql)
|
|
28
|
+
this.checkpoints = new PgAgentContextCheckpointStore(options.sql)
|
|
26
29
|
}
|
|
27
30
|
}
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
import {
|
|
2
|
+
agentContextCheckpointMatchesCreateInput,
|
|
3
|
+
assertAgentContextCheckpointAnchors,
|
|
4
|
+
assertAgentContextCheckpointAuthority,
|
|
5
|
+
assertAgentContextCheckpointReplayState,
|
|
6
|
+
assertCreateAgentContextCheckpointInput,
|
|
7
|
+
} from "@sixb/core/internal/agent-run-storage-provider"
|
|
8
|
+
import {
|
|
9
|
+
type AgentContextCheckpointRecord,
|
|
10
|
+
type AgentContextCheckpointStore,
|
|
11
|
+
AgentStorageError,
|
|
12
|
+
type CreateAgentContextCheckpointInput,
|
|
13
|
+
} from "@sixb/core/storage"
|
|
14
|
+
import { isUniqueViolation } from "../storage-errors"
|
|
15
|
+
import { type PgStoreClient, runPgTransaction } from "../transactions"
|
|
16
|
+
import {
|
|
17
|
+
type AgentContextCheckpointRow,
|
|
18
|
+
type AgentMessageRow,
|
|
19
|
+
type AgentRunRow,
|
|
20
|
+
type AgentThreadRow,
|
|
21
|
+
rowToContextCheckpointRecord,
|
|
22
|
+
rowToMessageRecord,
|
|
23
|
+
rowToRunRecord,
|
|
24
|
+
rowToThreadRecord,
|
|
25
|
+
} from "./rows"
|
|
26
|
+
|
|
27
|
+
const PG_CHECKPOINT_RUN_ID_BATCH_SIZE = 10_000
|
|
28
|
+
|
|
29
|
+
export class PgAgentContextCheckpointStore implements AgentContextCheckpointStore {
|
|
30
|
+
constructor(private readonly sql: PgStoreClient) {}
|
|
31
|
+
|
|
32
|
+
async create(input: CreateAgentContextCheckpointInput): Promise<AgentContextCheckpointRecord> {
|
|
33
|
+
assertCreateAgentContextCheckpointInput(input, "SixbPg")
|
|
34
|
+
|
|
35
|
+
try {
|
|
36
|
+
return await runPgTransaction(this.sql, async (tx) => {
|
|
37
|
+
// Match run finalization's lock order (run, then thread) to avoid a cross-operation deadlock.
|
|
38
|
+
const [runRow] = await tx<AgentRunRow[]>`
|
|
39
|
+
SELECT * FROM agent_runs
|
|
40
|
+
WHERE project_id = ${input.projectId} AND id = ${input.createdByRunId}
|
|
41
|
+
FOR UPDATE
|
|
42
|
+
`
|
|
43
|
+
const [threadRow] = await tx<AgentThreadRow[]>`
|
|
44
|
+
SELECT * FROM agent_threads
|
|
45
|
+
WHERE project_id = ${input.projectId} AND id = ${input.threadId}
|
|
46
|
+
FOR UPDATE
|
|
47
|
+
`
|
|
48
|
+
assertAgentContextCheckpointAuthority({
|
|
49
|
+
create: input,
|
|
50
|
+
run: runRow ? rowToRunRecord(runRow) : null,
|
|
51
|
+
thread: threadRow ? rowToThreadRecord(threadRow) : null,
|
|
52
|
+
prefix: "SixbPg",
|
|
53
|
+
})
|
|
54
|
+
|
|
55
|
+
const [latestRow] = await tx<AgentContextCheckpointRow[]>`
|
|
56
|
+
SELECT * FROM agent_context_checkpoints
|
|
57
|
+
WHERE project_id = ${input.projectId} AND thread_id = ${input.threadId}
|
|
58
|
+
ORDER BY summarized_through_seq DESC, created_at DESC, id DESC
|
|
59
|
+
LIMIT 1
|
|
60
|
+
`
|
|
61
|
+
const latest = latestRow ? rowToContextCheckpointRecord(latestRow) : null
|
|
62
|
+
const [headRow] = await tx<{ seq: number | string }[]>`
|
|
63
|
+
SELECT COALESCE(MAX(seq), 0) AS seq FROM agent_messages
|
|
64
|
+
WHERE project_id = ${input.projectId} AND thread_id = ${input.threadId}
|
|
65
|
+
`
|
|
66
|
+
const headSeq = Number(headRow?.seq ?? 0)
|
|
67
|
+
|
|
68
|
+
const [existingForRunRow] = await tx<AgentContextCheckpointRow[]>`
|
|
69
|
+
SELECT * FROM agent_context_checkpoints
|
|
70
|
+
WHERE project_id = ${input.projectId} AND created_by_run_id = ${input.createdByRunId}
|
|
71
|
+
`
|
|
72
|
+
if (existingForRunRow) {
|
|
73
|
+
const record = rowToContextCheckpointRecord(existingForRunRow)
|
|
74
|
+
if (agentContextCheckpointMatchesCreateInput(record, input)) {
|
|
75
|
+
assertAgentContextCheckpointReplayState({
|
|
76
|
+
create: input,
|
|
77
|
+
existing: record,
|
|
78
|
+
latest,
|
|
79
|
+
headSeq,
|
|
80
|
+
prefix: "SixbPg",
|
|
81
|
+
})
|
|
82
|
+
return record
|
|
83
|
+
}
|
|
84
|
+
throw new AgentStorageError(
|
|
85
|
+
"invalid_state",
|
|
86
|
+
`[SixbPg] Agent run '${input.createdByRunId}' already created a different context checkpoint.`
|
|
87
|
+
)
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
const [duplicateId] = await tx<{ present: number }[]>`
|
|
91
|
+
SELECT 1 AS present FROM agent_context_checkpoints
|
|
92
|
+
WHERE project_id = ${input.projectId} AND id = ${input.id}
|
|
93
|
+
`
|
|
94
|
+
if (duplicateId) {
|
|
95
|
+
throw new AgentStorageError(
|
|
96
|
+
"duplicate_id",
|
|
97
|
+
`[SixbPg] Agent context checkpoint '${input.id}' already exists for project '${input.projectId}'.`
|
|
98
|
+
)
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const [firstRetainedRow] = await tx<AgentMessageRow[]>`
|
|
102
|
+
SELECT * FROM agent_messages
|
|
103
|
+
WHERE
|
|
104
|
+
project_id = ${input.projectId}
|
|
105
|
+
AND thread_id = ${input.threadId}
|
|
106
|
+
AND seq > ${input.summarizedThroughSeq}
|
|
107
|
+
ORDER BY seq ASC
|
|
108
|
+
LIMIT 1
|
|
109
|
+
`
|
|
110
|
+
assertAgentContextCheckpointAnchors({
|
|
111
|
+
create: input,
|
|
112
|
+
latest,
|
|
113
|
+
headSeq,
|
|
114
|
+
firstRetained: firstRetainedRow ? rowToMessageRecord(firstRetainedRow) : null,
|
|
115
|
+
prefix: "SixbPg",
|
|
116
|
+
})
|
|
117
|
+
|
|
118
|
+
const [row] = await tx<AgentContextCheckpointRow[]>`
|
|
119
|
+
INSERT INTO agent_context_checkpoints (
|
|
120
|
+
project_id,
|
|
121
|
+
id,
|
|
122
|
+
thread_id,
|
|
123
|
+
created_by_run_id,
|
|
124
|
+
previous_checkpoint_id,
|
|
125
|
+
reason,
|
|
126
|
+
summary,
|
|
127
|
+
summary_format_version,
|
|
128
|
+
summarized_through_seq,
|
|
129
|
+
observed_head_seq,
|
|
130
|
+
estimated_input_tokens_before,
|
|
131
|
+
estimated_input_tokens_after,
|
|
132
|
+
summary_model_id,
|
|
133
|
+
created_at
|
|
134
|
+
) VALUES (
|
|
135
|
+
${input.projectId},
|
|
136
|
+
${input.id},
|
|
137
|
+
${input.threadId},
|
|
138
|
+
${input.createdByRunId},
|
|
139
|
+
${input.expectedPreviousCheckpointId},
|
|
140
|
+
${input.reason},
|
|
141
|
+
${input.summary},
|
|
142
|
+
${input.summaryFormatVersion},
|
|
143
|
+
${input.summarizedThroughSeq},
|
|
144
|
+
${input.observedHeadSeq},
|
|
145
|
+
${input.estimatedInputTokensBefore},
|
|
146
|
+
${input.estimatedInputTokensAfter},
|
|
147
|
+
${input.summaryModelId},
|
|
148
|
+
${input.createdAt ?? new Date()}
|
|
149
|
+
)
|
|
150
|
+
RETURNING *
|
|
151
|
+
`
|
|
152
|
+
return rowToContextCheckpointRecord(row)
|
|
153
|
+
})
|
|
154
|
+
} catch (error) {
|
|
155
|
+
if (isUniqueViolation(error)) {
|
|
156
|
+
throw new AgentStorageError(
|
|
157
|
+
"duplicate_id",
|
|
158
|
+
`[SixbPg] Agent context checkpoint '${input.id}' already exists for project '${input.projectId}'.`
|
|
159
|
+
)
|
|
160
|
+
}
|
|
161
|
+
throw error
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
async getLatest(input: {
|
|
166
|
+
readonly projectId: string
|
|
167
|
+
readonly threadId: string
|
|
168
|
+
}): Promise<AgentContextCheckpointRecord | null> {
|
|
169
|
+
const [row] = await this.sql<AgentContextCheckpointRow[]>`
|
|
170
|
+
SELECT * FROM agent_context_checkpoints
|
|
171
|
+
WHERE project_id = ${input.projectId} AND thread_id = ${input.threadId}
|
|
172
|
+
ORDER BY summarized_through_seq DESC, created_at DESC, id DESC
|
|
173
|
+
LIMIT 1
|
|
174
|
+
`
|
|
175
|
+
return row ? rowToContextCheckpointRecord(row) : null
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
async getByRunIds(input: {
|
|
179
|
+
readonly projectId: string
|
|
180
|
+
readonly runIds: readonly string[]
|
|
181
|
+
}): Promise<readonly AgentContextCheckpointRecord[]> {
|
|
182
|
+
const runIds = [...new Set(input.runIds)]
|
|
183
|
+
if (runIds.length === 0) return []
|
|
184
|
+
|
|
185
|
+
const rows: AgentContextCheckpointRow[] = []
|
|
186
|
+
for (let offset = 0; offset < runIds.length; offset += PG_CHECKPOINT_RUN_ID_BATCH_SIZE) {
|
|
187
|
+
const batch = runIds.slice(offset, offset + PG_CHECKPOINT_RUN_ID_BATCH_SIZE)
|
|
188
|
+
const placeholders = batch.map((_, index) => `$${index + 2}`).join(", ")
|
|
189
|
+
rows.push(
|
|
190
|
+
...(await this.sql.unsafe<AgentContextCheckpointRow[]>(
|
|
191
|
+
`SELECT * FROM agent_context_checkpoints WHERE project_id = $1 AND created_by_run_id IN (${placeholders})`,
|
|
192
|
+
[input.projectId, ...batch]
|
|
193
|
+
))
|
|
194
|
+
)
|
|
195
|
+
}
|
|
196
|
+
const byRunId = new Map(
|
|
197
|
+
rows.map((row) => [row.created_by_run_id, rowToContextCheckpointRecord(row)] as const)
|
|
198
|
+
)
|
|
199
|
+
return runIds.flatMap((runId) => {
|
|
200
|
+
const checkpoint = byRunId.get(runId)
|
|
201
|
+
return checkpoint ? [checkpoint] : []
|
|
202
|
+
})
|
|
203
|
+
}
|
|
204
|
+
}
|
package/src/agents/index.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export type { PgAgentStorageOptions } from "./agent-storage"
|
|
2
2
|
export { PgAgentStorage } from "./agent-storage"
|
|
3
|
+
export { PgAgentContextCheckpointStore } from "./checkpoints"
|
|
3
4
|
export { PgAgentMessageStore } from "./messages"
|
|
4
5
|
export { PgAgentRunStore } from "./runs"
|
|
5
6
|
export { PgAgentThreadStore } from "./threads"
|
package/src/agents/messages.ts
CHANGED
|
@@ -4,6 +4,7 @@ import {
|
|
|
4
4
|
type AgentMessageStore,
|
|
5
5
|
AgentStorageError,
|
|
6
6
|
type AppendAgentMessageInput,
|
|
7
|
+
type DeleteAgentMessagesByRunInput,
|
|
7
8
|
type ListAgentMessagesInput,
|
|
8
9
|
type ListAgentMessagesResult,
|
|
9
10
|
} from "@sixb/core/storage"
|
|
@@ -20,6 +21,23 @@ export class PgAgentMessageStore implements AgentMessageStore {
|
|
|
20
21
|
|
|
21
22
|
try {
|
|
22
23
|
return await runPgTransaction(this.sql, async (tx) => {
|
|
24
|
+
// Assistant finalization appends and finishes in one outer transaction. Lock its run first
|
|
25
|
+
// so every operation that needs both rows follows the same run -> thread order.
|
|
26
|
+
if (input.runId !== null) {
|
|
27
|
+
const [run] = await tx<{ id: string }[]>`
|
|
28
|
+
SELECT id FROM agent_runs
|
|
29
|
+
WHERE project_id = ${input.projectId} AND id = ${input.runId}
|
|
30
|
+
FOR UPDATE
|
|
31
|
+
`
|
|
32
|
+
|
|
33
|
+
if (!run) {
|
|
34
|
+
throw new AgentStorageError(
|
|
35
|
+
"run_not_found",
|
|
36
|
+
`[SixbPg] Agent run '${input.runId}' not found for project '${input.projectId}'.`
|
|
37
|
+
)
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
23
41
|
const [thread] = await tx<{ id: string }[]>`
|
|
24
42
|
SELECT id FROM agent_threads
|
|
25
43
|
WHERE project_id = ${input.projectId} AND id = ${input.threadId}
|
|
@@ -33,19 +51,6 @@ export class PgAgentMessageStore implements AgentMessageStore {
|
|
|
33
51
|
)
|
|
34
52
|
}
|
|
35
53
|
|
|
36
|
-
if (input.runId !== null) {
|
|
37
|
-
const [run] = await tx<{ id: string }[]>`
|
|
38
|
-
SELECT id FROM agent_runs WHERE project_id = ${input.projectId} AND id = ${input.runId}
|
|
39
|
-
`
|
|
40
|
-
|
|
41
|
-
if (!run) {
|
|
42
|
-
throw new AgentStorageError(
|
|
43
|
-
"run_not_found",
|
|
44
|
-
`[SixbPg] Agent run '${input.runId}' not found for project '${input.projectId}'.`
|
|
45
|
-
)
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
54
|
const [seqRow] = await tx<{ next: number | string }[]>`
|
|
50
55
|
SELECT COALESCE(MAX(seq), 0) + 1 AS next FROM agent_messages
|
|
51
56
|
WHERE project_id = ${input.projectId} AND thread_id = ${input.threadId}
|
|
@@ -104,6 +109,54 @@ export class PgAgentMessageStore implements AgentMessageStore {
|
|
|
104
109
|
}
|
|
105
110
|
}
|
|
106
111
|
|
|
112
|
+
async deleteByRunId(input: DeleteAgentMessagesByRunInput): Promise<number> {
|
|
113
|
+
return runPgTransaction(this.sql, async (tx) => {
|
|
114
|
+
const [thread] = await tx<{ id: string }[]>`
|
|
115
|
+
SELECT id FROM agent_threads
|
|
116
|
+
WHERE project_id = ${input.projectId} AND id = ${input.threadId}
|
|
117
|
+
FOR UPDATE
|
|
118
|
+
`
|
|
119
|
+
|
|
120
|
+
if (!thread) {
|
|
121
|
+
throw new AgentStorageError(
|
|
122
|
+
"thread_not_found",
|
|
123
|
+
`[SixbPg] Agent thread '${input.threadId}' not found for project '${input.projectId}'.`
|
|
124
|
+
)
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const deleted = await tx<{ id: string }[]>`
|
|
128
|
+
DELETE FROM agent_messages
|
|
129
|
+
WHERE project_id = ${input.projectId}
|
|
130
|
+
AND thread_id = ${input.threadId}
|
|
131
|
+
AND run_id = ${input.runId}
|
|
132
|
+
RETURNING id
|
|
133
|
+
`
|
|
134
|
+
if (deleted.length === 0) {
|
|
135
|
+
return 0
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
const updatedAt = new Date()
|
|
139
|
+
await tx`
|
|
140
|
+
UPDATE agent_threads
|
|
141
|
+
SET
|
|
142
|
+
message_count = (
|
|
143
|
+
SELECT COUNT(*) FROM agent_messages
|
|
144
|
+
WHERE project_id = ${input.projectId} AND thread_id = ${input.threadId}
|
|
145
|
+
),
|
|
146
|
+
last_message_at = (
|
|
147
|
+
SELECT created_at FROM agent_messages
|
|
148
|
+
WHERE project_id = ${input.projectId} AND thread_id = ${input.threadId}
|
|
149
|
+
ORDER BY seq DESC
|
|
150
|
+
LIMIT 1
|
|
151
|
+
),
|
|
152
|
+
updated_at = ${updatedAt}
|
|
153
|
+
WHERE project_id = ${input.projectId} AND id = ${input.threadId}
|
|
154
|
+
`
|
|
155
|
+
|
|
156
|
+
return deleted.length
|
|
157
|
+
})
|
|
158
|
+
}
|
|
159
|
+
|
|
107
160
|
async getById(params: { projectId: string; id: string }): Promise<AgentMessageRecord | null> {
|
|
108
161
|
const [row] = await this.sql<AgentMessageRow[]>`
|
|
109
162
|
SELECT * FROM agent_messages WHERE project_id = ${params.projectId} AND id = ${params.id}
|
|
@@ -121,6 +174,11 @@ export class PgAgentMessageStore implements AgentMessageStore {
|
|
|
121
174
|
const params: SqlParameter[] = [input.projectId, input.threadId]
|
|
122
175
|
let index = 3
|
|
123
176
|
|
|
177
|
+
if (input.afterSeq !== undefined) {
|
|
178
|
+
whereClauses.push(`seq > $${index++}`)
|
|
179
|
+
params.push(input.afterSeq)
|
|
180
|
+
}
|
|
181
|
+
|
|
124
182
|
if (input.roles) {
|
|
125
183
|
const placeholders = input.roles.map(() => `$${index++}`)
|
|
126
184
|
whereClauses.push(`role IN (${placeholders.join(", ")})`)
|
package/src/agents/rows.ts
CHANGED
|
@@ -2,6 +2,7 @@ import type { AgentMessagePart, JsonValue, Principal } from "@sixb/core"
|
|
|
2
2
|
import { parseSixbFailure } from "@sixb/core/internal/errors"
|
|
3
3
|
import {
|
|
4
4
|
AGENT_RUN_FAILURE_CODES,
|
|
5
|
+
type AgentContextCheckpointRecord,
|
|
5
6
|
type AgentMessageRecord,
|
|
6
7
|
type AgentRunDiagnostic,
|
|
7
8
|
type AgentRunRecord,
|
|
@@ -65,6 +66,23 @@ export interface AgentMessageRow {
|
|
|
65
66
|
completed_at: Date | string | null
|
|
66
67
|
}
|
|
67
68
|
|
|
69
|
+
export interface AgentContextCheckpointRow {
|
|
70
|
+
project_id: string
|
|
71
|
+
id: string
|
|
72
|
+
thread_id: string
|
|
73
|
+
created_by_run_id: string
|
|
74
|
+
previous_checkpoint_id: string | null
|
|
75
|
+
reason: AgentContextCheckpointRecord["reason"]
|
|
76
|
+
summary: string
|
|
77
|
+
summary_format_version: number | string
|
|
78
|
+
summarized_through_seq: number | string
|
|
79
|
+
observed_head_seq: number | string
|
|
80
|
+
estimated_input_tokens_before: number | string
|
|
81
|
+
estimated_input_tokens_after: number | string
|
|
82
|
+
summary_model_id: string
|
|
83
|
+
created_at: Date | string
|
|
84
|
+
}
|
|
85
|
+
|
|
68
86
|
// ── row → record mappers ────────────────────────────────────────────────────────────────────────
|
|
69
87
|
|
|
70
88
|
export function rowToThreadRecord(row: AgentThreadRow): AgentThreadRecord {
|
|
@@ -134,6 +152,33 @@ export function rowToMessageRecord(row: AgentMessageRow): AgentMessageRecord {
|
|
|
134
152
|
}
|
|
135
153
|
}
|
|
136
154
|
|
|
155
|
+
export function rowToContextCheckpointRecord(
|
|
156
|
+
row: AgentContextCheckpointRow
|
|
157
|
+
): AgentContextCheckpointRecord {
|
|
158
|
+
const summaryFormatVersion = Number(row.summary_format_version)
|
|
159
|
+
if (summaryFormatVersion !== 1) {
|
|
160
|
+
throw new Error(
|
|
161
|
+
`[SixbPg] Unsupported agent context checkpoint summary format version '${summaryFormatVersion}'.`
|
|
162
|
+
)
|
|
163
|
+
}
|
|
164
|
+
return {
|
|
165
|
+
id: row.id,
|
|
166
|
+
projectId: row.project_id,
|
|
167
|
+
threadId: row.thread_id,
|
|
168
|
+
createdByRunId: row.created_by_run_id,
|
|
169
|
+
previousCheckpointId: row.previous_checkpoint_id ?? undefined,
|
|
170
|
+
reason: row.reason,
|
|
171
|
+
summary: row.summary,
|
|
172
|
+
summaryFormatVersion: 1,
|
|
173
|
+
summarizedThroughSeq: Number(row.summarized_through_seq),
|
|
174
|
+
observedHeadSeq: Number(row.observed_head_seq),
|
|
175
|
+
estimatedInputTokensBefore: Number(row.estimated_input_tokens_before),
|
|
176
|
+
estimatedInputTokensAfter: Number(row.estimated_input_tokens_after),
|
|
177
|
+
summaryModelId: row.summary_model_id,
|
|
178
|
+
createdAt: new Date(row.created_at),
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
137
182
|
function principalFromColumns(
|
|
138
183
|
type: Principal["type"] | null | undefined,
|
|
139
184
|
id: string | null | undefined
|
package/src/index.ts
CHANGED
|
@@ -19,6 +19,7 @@ import {
|
|
|
19
19
|
createWorkflowRunOperationScope,
|
|
20
20
|
} from "@sixb/core/internal/storage-operation-scope"
|
|
21
21
|
import {
|
|
22
|
+
type AiCostStorage,
|
|
22
23
|
type AiUsageStorage,
|
|
23
24
|
createTransactionStorageProxy,
|
|
24
25
|
type ObjectStorage,
|
|
@@ -31,6 +32,7 @@ import { PgConnectorConnectionStorage } from "./connector-connection-storage"
|
|
|
31
32
|
import { createPostgresStorageMigrators, dropSchema } from "./migrations"
|
|
32
33
|
import { PgOntologyStorage, type PgOntologyTransactionContext } from "./ontology-storage"
|
|
33
34
|
import { PgActionRunStorage } from "./pg-action-run-storage"
|
|
35
|
+
import { PgAiCostStorage } from "./pg-ai-cost-storage"
|
|
34
36
|
import { PgAiUsageStorage } from "./pg-ai-usage-storage"
|
|
35
37
|
import { createPgClient, type SQL, type SQLClient } from "./pg-client"
|
|
36
38
|
import { PgExecutionStorage } from "./pg-execution-storage"
|
|
@@ -110,7 +112,7 @@ export interface PostgresStorageOptions {
|
|
|
110
112
|
/**
|
|
111
113
|
* PostgreSQL storage provider for Sixb.
|
|
112
114
|
*
|
|
113
|
-
* Bundles Sixb storage adapters, including the AI
|
|
115
|
+
* Bundles Sixb storage adapters, including the AI accounting ledger, behind a shared PostgreSQL
|
|
114
116
|
* connection pool (porsager `postgres`), which reliably reclaims connections under load.
|
|
115
117
|
*
|
|
116
118
|
* The storage exposes a core `StorageMigrator`. Sixb CLI startup and
|
|
@@ -135,6 +137,7 @@ export class PostgresStorage implements MigrationCapableStorage {
|
|
|
135
137
|
readonly executions: PgExecutionStorage
|
|
136
138
|
readonly agents: PgAgentStorage
|
|
137
139
|
readonly aiUsage: AiUsageStorage
|
|
140
|
+
readonly aiCosts: AiCostStorage
|
|
138
141
|
readonly actionRuns: PgActionRunStorage
|
|
139
142
|
readonly pipelineRuns: PgPipelineRunStorage
|
|
140
143
|
readonly workflowRuns: PgWorkflowRunStorage
|
|
@@ -208,6 +211,7 @@ export class PostgresStorage implements MigrationCapableStorage {
|
|
|
208
211
|
this.executions = createOperationScopedFacade(stores.executions, scope)
|
|
209
212
|
this.agents = createAgentOperationScope(stores.agents, scope)
|
|
210
213
|
this.aiUsage = createOperationScopedFacade(stores.aiUsage, scope)
|
|
214
|
+
this.aiCosts = createOperationScopedFacade(stores.aiCosts, scope)
|
|
211
215
|
this.actionRuns = createOperationScopedFacade(stores.actionRuns, scope)
|
|
212
216
|
this.pipelineRuns = createOperationScopedFacade(stores.pipelineRuns, scope)
|
|
213
217
|
this.workflowRuns = createWorkflowRunOperationScope(stores.workflowRuns, scope)
|
|
@@ -337,6 +341,7 @@ function createPostgresStores(
|
|
|
337
341
|
executions,
|
|
338
342
|
agents: new PgAgentStorage({ sql, executions }),
|
|
339
343
|
aiUsage: new PgAiUsageStorage(sql),
|
|
344
|
+
aiCosts: new PgAiCostStorage(sql),
|
|
340
345
|
actionRuns: new PgActionRunStorage(sql, executions),
|
|
341
346
|
pipelineRuns: new PgPipelineRunStorage(sql, executions),
|
|
342
347
|
workflowRuns: new PgWorkflowRunStorage(sql, executions),
|
|
@@ -357,6 +362,7 @@ interface PostgresStoreSet {
|
|
|
357
362
|
readonly executions: PgExecutionStorage
|
|
358
363
|
readonly agents: PgAgentStorage
|
|
359
364
|
readonly aiUsage: PgAiUsageStorage
|
|
365
|
+
readonly aiCosts: PgAiCostStorage
|
|
360
366
|
readonly actionRuns: PgActionRunStorage
|
|
361
367
|
readonly pipelineRuns: PgPipelineRunStorage
|
|
362
368
|
readonly workflowRuns: PgWorkflowRunStorage
|