@sixb/pg 0.1.20 → 0.1.22
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/README.md +1 -0
- package/dist/agents/agent-storage.d.ts +8 -2
- package/dist/agents/agent-storage.d.ts.map +1 -1
- package/dist/agents/approvals.d.ts +48 -0
- package/dist/agents/approvals.d.ts.map +1 -0
- package/dist/agents/checkpoints.d.ts +1 -0
- package/dist/agents/checkpoints.d.ts.map +1 -1
- package/dist/agents/index.d.ts +1 -0
- package/dist/agents/index.d.ts.map +1 -1
- package/dist/agents/memory.d.ts +19 -0
- package/dist/agents/memory.d.ts.map +1 -0
- package/dist/agents/messages.d.ts.map +1 -1
- package/dist/agents/rows.d.ts +15 -1
- package/dist/agents/rows.d.ts.map +1 -1
- package/dist/agents/runs.d.ts +3 -1
- package/dist/agents/runs.d.ts.map +1 -1
- package/dist/agents/settings.d.ts +29 -0
- package/dist/agents/settings.d.ts.map +1 -0
- package/dist/agents/threads.d.ts +10 -1
- package/dist/agents/threads.d.ts.map +1 -1
- package/dist/ai-cost-groups.d.ts.map +1 -1
- package/dist/auth-storage/auth-storage.d.ts +3 -2
- package/dist/auth-storage/auth-storage.d.ts.map +1 -1
- package/dist/auth-storage/sessions.d.ts +2 -1
- package/dist/auth-storage/sessions.d.ts.map +1 -1
- package/dist/auth-storage/users.d.ts +8 -4
- package/dist/auth-storage/users.d.ts.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6001 -2923
- package/dist/index.js.map +45 -37
- package/dist/migrations.d.ts.map +1 -1
- package/dist/objects/conditional-reader.d.ts +17 -0
- package/dist/objects/conditional-reader.d.ts.map +1 -0
- package/dist/objects/query-compiler.d.ts +27 -1
- package/dist/objects/query-compiler.d.ts.map +1 -1
- package/dist/objects/query-indexes.d.ts.map +1 -1
- package/dist/objects/read-scope.d.ts +10 -1
- package/dist/objects/read-scope.d.ts.map +1 -1
- package/dist/objects/reader.d.ts +2 -0
- package/dist/objects/reader.d.ts.map +1 -1
- package/dist/objects/scoped-reader.d.ts +12 -0
- package/dist/objects/scoped-reader.d.ts.map +1 -0
- package/dist/objects/selected-reader.d.ts +1 -0
- package/dist/objects/selected-reader.d.ts.map +1 -1
- package/dist/objects/storage.d.ts +7 -1
- package/dist/objects/storage.d.ts.map +1 -1
- package/dist/ontology-storage/index.d.ts +2 -0
- package/dist/ontology-storage/index.d.ts.map +1 -1
- package/dist/ontology-storage/materialization-session.d.ts +6 -0
- package/dist/ontology-storage/materialization-session.d.ts.map +1 -1
- package/dist/ontology-storage/materialization-writer.d.ts +15 -0
- package/dist/ontology-storage/materialization-writer.d.ts.map +1 -1
- package/dist/ontology-storage/materializations.d.ts.map +1 -1
- package/dist/ontology-storage/replacement-plans.d.ts.map +1 -1
- package/dist/ontology-storage/sources.d.ts +2 -1
- package/dist/ontology-storage/sources.d.ts.map +1 -1
- package/dist/ontology-storage/unique-values.d.ts +60 -0
- package/dist/ontology-storage/unique-values.d.ts.map +1 -0
- package/dist/pg-action-run-storage.d.ts +4 -0
- package/dist/pg-action-run-storage.d.ts.map +1 -1
- package/dist/pg-activity-storage.d.ts +22 -0
- package/dist/pg-activity-storage.d.ts.map +1 -0
- package/dist/pg-ai-cost-storage.d.ts.map +1 -1
- package/dist/pg-ai-usage-storage.d.ts +8 -1
- package/dist/pg-ai-usage-storage.d.ts.map +1 -1
- package/dist/pg-artifact-storage.d.ts +26 -0
- package/dist/pg-artifact-storage.d.ts.map +1 -0
- package/dist/pg-execution-storage.d.ts +3 -1
- package/dist/pg-execution-storage.d.ts.map +1 -1
- package/dist/pg-workflow-run-storage.d.ts +4 -0
- package/dist/pg-workflow-run-storage.d.ts.map +1 -1
- package/dist/share-grant-storage.d.ts +2 -1
- package/dist/share-grant-storage.d.ts.map +1 -1
- package/dist/storage-errors.d.ts +2 -0
- package/dist/storage-errors.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/agents/agent-storage.ts +11 -2
- package/src/agents/approvals.ts +400 -0
- package/src/agents/checkpoints.ts +8 -4
- package/src/agents/index.ts +1 -0
- package/src/agents/memory.ts +175 -0
- package/src/agents/messages.ts +14 -7
- package/src/agents/rows.ts +46 -1
- package/src/agents/runs.ts +154 -22
- package/src/agents/settings.ts +105 -0
- package/src/agents/threads.ts +379 -3
- package/src/ai-cost-groups.ts +11 -1
- package/src/auth-storage/auth-storage.ts +45 -13
- package/src/auth-storage/sessions.ts +20 -0
- package/src/auth-storage/users.ts +105 -43
- package/src/index.ts +10 -0
- package/src/migrations/063-artifacts.sql +67 -0
- package/src/migrations/064-drop-output-diagnostics.sql +14 -0
- package/src/migrations/065-plan-work-payload-statistics.sql +5 -0
- package/src/migrations/066-activity.sql +61 -0
- package/src/migrations/067-activity-timeline.sql +15 -0
- package/src/migrations/068-activity-interactions.sql +20 -0
- package/src/migrations/069-artifact-kinds.sql +4 -0
- package/src/migrations/070-artifact-state.sql +16 -0
- package/src/migrations/071-agent-thread-participants.sql +16 -0
- package/src/migrations/072-forked-context-checkpoints.sql +23 -0
- package/src/migrations/073-unique-values.sql +25 -0
- package/src/migrations/074-generated-media-usage.sql +21 -0
- package/src/migrations/075-model-call-files.sql +11 -0
- package/src/migrations/076-agent-memory.sql +33 -0
- package/src/migrations/077-artifact-threads.sql +21 -0
- package/src/migrations/078-agent-approvals.sql +58 -0
- package/src/migrations/079-agent-approval-resume.sql +20 -0
- package/src/migrations/080-subagent-threads.sql +145 -0
- package/src/migrations/081-subagent-questions.sql +6 -0
- package/src/migrations.ts +52 -0
- package/src/objects/conditional-reader.ts +44 -0
- package/src/objects/prepare-queries.ts +1 -1
- package/src/objects/query-compiler.ts +96 -33
- package/src/objects/query-indexes.ts +29 -10
- package/src/objects/read-scope.ts +140 -25
- package/src/objects/reader.ts +50 -6
- package/src/objects/scoped-reader.ts +101 -0
- package/src/objects/selected-reader.ts +16 -76
- package/src/objects/storage.ts +24 -5
- package/src/objects/text-count-index.ts +1 -0
- package/src/ontology-storage/index.ts +3 -0
- package/src/ontology-storage/materialization-session.ts +8 -0
- package/src/ontology-storage/materialization-writer.ts +76 -1
- package/src/ontology-storage/materializations.ts +20 -1
- package/src/ontology-storage/replacement-plans.ts +25 -7
- package/src/ontology-storage/sources.ts +37 -0
- package/src/ontology-storage/unique-values.ts +274 -0
- package/src/pg-action-run-storage.ts +23 -0
- package/src/pg-activity-storage.ts +486 -0
- package/src/pg-ai-cost-storage.ts +62 -12
- package/src/pg-ai-usage-storage.ts +90 -1
- package/src/pg-artifact-storage.ts +521 -0
- package/src/pg-execution-storage.ts +83 -0
- package/src/pg-workflow-run-storage.ts +23 -0
- package/src/share-grant-storage.ts +21 -0
- package/src/storage-errors.ts +7 -0
- package/src/transactions.ts +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pg-artifact-storage.d.ts","sourceRoot":"","sources":["../src/pg-artifact-storage.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EACV,wBAAwB,EACxB,cAAc,EACd,kBAAkB,EAClB,qBAAqB,EACrB,kBAAkB,EAClB,eAAe,EAEf,qBAAqB,EACrB,iBAAiB,EACjB,mBAAmB,EACnB,mBAAmB,EACnB,mCAAmC,EACnC,qCAAqC,EACrC,2BAA2B,EAC3B,gBAAgB,EAChB,uBAAuB,EACvB,kBAAkB,EAClB,mBAAmB,EACnB,yBAAyB,EACzB,0BAA0B,EAC1B,4BAA4B,EAC5B,2BAA2B,EAC3B,wBAAwB,EACxB,qBAAqB,EACtB,MAAM,oBAAoB,CAAA;AAE3B,OAAO,EAAE,KAAK,aAAa,EAAoB,MAAM,gBAAgB,CAAA;AA2BrE,qBAAa,iBAAkB,YAAW,eAAe;IAC3C,OAAO,CAAC,QAAQ,CAAC,GAAG;gBAAH,GAAG,EAAE,aAAa;IAEzC,MAAM,CAAC,KAAK,EAAE,mBAAmB,GAAG,OAAO,CAAC,wBAAwB,CAAC;IAsBrE,OAAO,CAAC,KAAK,EAAE,2BAA2B,GAAG,OAAO,CAAC,wBAAwB,CAAC;IA6C9E,GAAG,CAAC,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;IAQ5D,IAAI,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAuC7D,UAAU,CAAC,KAAK,EAAE,uBAAuB,GAAG,OAAO,CAAC,qBAAqB,GAAG,IAAI,CAAC;IASjF,aAAa,CAAC,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IASzD,IAAI,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,cAAc,CAAC;IA2CvD,YAAY,CAAC,KAAK,EAAE,yBAAyB,GAAG,OAAO,CAAC,0BAA0B,CAAC;IAoBnF,uBAAuB,CAC3B,KAAK,EAAE,4BAA4B,GAClC,OAAO,CAAC,qBAAqB,EAAE,CAAC;IAkB7B,gBAAgB,CAAC,MAAM,EAAE,wBAAwB,GAAG,OAAO,CAAC,IAAI,CAAC;IAejE,cAAc,CAClB,KAAK,EAAE,2BAA2B,GACjC,OAAO,CAAC,wBAAwB,GAAG,IAAI,CAAC;IAQrC,wBAAwB,CAAC,KAAK,EAAE,qCAAqC,GAAG,OAAO,CAAC,MAAM,CAAC;IAavF,QAAQ,CAAC,KAAK,EAAE,qBAAqB,GAAG,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC;IAU1E,QAAQ,CAAC,KAAK,EAAE,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC;IA+CrD,WAAW,CAAC,KAAK,EAAE,qBAAqB,GAAG,OAAO,CAAC,OAAO,CAAC;IAW3D,SAAS,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAAC,kBAAkB,EAAE,CAAC;IAWnE,UAAU,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAAC,MAAM,CAAC;IAUtD,MAAM,CAAC,KAAK,EAAE,mBAAmB,GAAG,OAAO,CAAC,OAAO,CAAC;IASpD,sBAAsB,CAAC,KAAK,EAAE,mCAAmC,GAAG,OAAO,CAAC,MAAM,CAAC;CA6D1F"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type ExecutionStorageRow } from "@sixb/core/internal/execution-storage";
|
|
2
|
-
import type { CreateExecutionInput, ExecutionRecord, ExecutionStorage, ShareSessionStorage } from "@sixb/core/storage";
|
|
2
|
+
import type { CreateExecutionInput, ExecutionDescendant, ExecutionRecord, ExecutionStorage, ListExecutionDescendantsInput, ListSessionExecutionsInput, SessionExecutions, ShareSessionStorage } from "@sixb/core/storage";
|
|
3
3
|
import type { PgAuthStorage } from "./auth-storage";
|
|
4
4
|
import type { PgStoreClient } from "./transactions";
|
|
5
5
|
export declare class PgExecutionStorage implements ExecutionStorage {
|
|
@@ -12,6 +12,8 @@ export declare class PgExecutionStorage implements ExecutionStorage {
|
|
|
12
12
|
readonly projectId: string;
|
|
13
13
|
readonly id: string;
|
|
14
14
|
}): Promise<ExecutionRecord | null>;
|
|
15
|
+
listBySession(input: ListSessionExecutionsInput): Promise<SessionExecutions>;
|
|
16
|
+
listDescendants(input: ListExecutionDescendantsInput): Promise<readonly ExecutionDescendant[]>;
|
|
15
17
|
}
|
|
16
18
|
/** An `executions` row as its record, for any store that reads executions alongside its own rows. */
|
|
17
19
|
export declare function pgExecutionRecord(row: PgExecutionRow): ExecutionRecord;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pg-execution-storage.d.ts","sourceRoot":"","sources":["../src/pg-execution-storage.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"pg-execution-storage.d.ts","sourceRoot":"","sources":["../src/pg-execution-storage.ts"],"names":[],"mappings":"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"}
|
|
@@ -17,6 +17,10 @@ export declare class PgWorkflowRunStorage implements WorkflowRunStorage {
|
|
|
17
17
|
projectId: string;
|
|
18
18
|
id: string;
|
|
19
19
|
}): Promise<WorkflowRunRecord | null>;
|
|
20
|
+
getByExecutionIds(params: {
|
|
21
|
+
readonly projectId: string;
|
|
22
|
+
readonly executionIds: readonly string[];
|
|
23
|
+
}): Promise<readonly WorkflowRunRecord[]>;
|
|
20
24
|
list(input: ListWorkflowRunsInput): Promise<ListWorkflowRunsResult>;
|
|
21
25
|
listLatestByWorkflowIds(input: ListLatestWorkflowRunsInput): Promise<ListLatestWorkflowRunsResult>;
|
|
22
26
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pg-workflow-run-storage.d.ts","sourceRoot":"","sources":["../src/pg-workflow-run-storage.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"pg-workflow-run-storage.d.ts","sourceRoot":"","sources":["../src/pg-workflow-run-storage.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import type { CreateShareGrantInput, GetShareGrantByIdInput, ListShareGrantsInput, ListShareGrantsResult, RevokeShareGrantInput, ShareGrantRecord, ShareGrantStorage } from "@sixb/core/storage";
|
|
1
|
+
import type { CreateShareGrantInput, GetShareGrantByIdInput, GetShareGrantsByIdsInput, ListShareGrantsInput, ListShareGrantsResult, RevokeShareGrantInput, ShareGrantRecord, ShareGrantStorage } from "@sixb/core/storage";
|
|
2
2
|
import type { PgStoreClient } from "./transactions";
|
|
3
3
|
export declare class PgShareGrantStorage implements ShareGrantStorage {
|
|
4
4
|
private readonly sql;
|
|
5
5
|
constructor(sql: PgStoreClient);
|
|
6
6
|
create(input: CreateShareGrantInput): Promise<ShareGrantRecord>;
|
|
7
7
|
getById(input: GetShareGrantByIdInput): Promise<ShareGrantRecord | null>;
|
|
8
|
+
getByIds(input: GetShareGrantsByIdsInput): Promise<readonly ShareGrantRecord[]>;
|
|
8
9
|
list(input: ListShareGrantsInput): Promise<ListShareGrantsResult>;
|
|
9
10
|
revoke(input: RevokeShareGrantInput): Promise<ShareGrantRecord | null>;
|
|
10
11
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"share-grant-storage.d.ts","sourceRoot":"","sources":["../src/share-grant-storage.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EACV,qBAAqB,EACrB,sBAAsB,EACtB,oBAAoB,EACpB,qBAAqB,EACrB,qBAAqB,EACrB,gBAAgB,EAChB,iBAAiB,EAClB,MAAM,oBAAoB,CAAA;AAI3B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAA;AAEnD,qBAAa,mBAAoB,YAAW,iBAAiB;IAC/C,OAAO,CAAC,QAAQ,CAAC,GAAG;gBAAH,GAAG,EAAE,aAAa;IAEzC,MAAM,CAAC,KAAK,EAAE,qBAAqB,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAqD/D,OAAO,CAAC,KAAK,EAAE,sBAAsB,GAAG,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC;IAUxE,IAAI,CAAC,KAAK,EAAE,oBAAoB,GAAG,OAAO,CAAC,qBAAqB,CAAC;IA8CjE,MAAM,CAAC,KAAK,EAAE,qBAAqB,GAAG,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC;CAqB7E"}
|
|
1
|
+
{"version":3,"file":"share-grant-storage.d.ts","sourceRoot":"","sources":["../src/share-grant-storage.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EACV,qBAAqB,EACrB,sBAAsB,EACtB,wBAAwB,EACxB,oBAAoB,EACpB,qBAAqB,EACrB,qBAAqB,EACrB,gBAAgB,EAChB,iBAAiB,EAClB,MAAM,oBAAoB,CAAA;AAI3B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAA;AAEnD,qBAAa,mBAAoB,YAAW,iBAAiB;IAC/C,OAAO,CAAC,QAAQ,CAAC,GAAG;gBAAH,GAAG,EAAE,aAAa;IAEzC,MAAM,CAAC,KAAK,EAAE,qBAAqB,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAqD/D,OAAO,CAAC,KAAK,EAAE,sBAAsB,GAAG,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC;IAUxE,QAAQ,CAAC,KAAK,EAAE,wBAAwB,GAAG,OAAO,CAAC,SAAS,gBAAgB,EAAE,CAAC;IAoB/E,IAAI,CAAC,KAAK,EAAE,oBAAoB,GAAG,OAAO,CAAC,qBAAqB,CAAC;IA8CjE,MAAM,CAAC,KAAK,EAAE,qBAAqB,GAAG,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC;CAqB7E"}
|
package/dist/storage-errors.d.ts
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
export declare function pgErrorCode(error: unknown): string | undefined;
|
|
3
3
|
/** True when the error is a PostgreSQL unique-constraint violation (SQLSTATE 23505). */
|
|
4
4
|
export declare function isUniqueViolation(error: unknown): boolean;
|
|
5
|
+
/** True when the error is a unique violation of exactly the named constraint. */
|
|
6
|
+
export declare function isUniqueViolationOf(error: unknown, constraint: string): boolean;
|
|
5
7
|
/** True when the error is a PostgreSQL foreign-key violation (SQLSTATE 23503). */
|
|
6
8
|
export declare function isForeignKeyViolation(error: unknown): boolean;
|
|
7
9
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"storage-errors.d.ts","sourceRoot":"","sources":["../src/storage-errors.ts"],"names":[],"mappings":"AAmEA,yFAAyF;AACzF,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAQ9D;AAED,wFAAwF;AACxF,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAEzD;AAED,kFAAkF;AAClF,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAE7D;AAED;;;;GAIG;AACH,wBAAgB,8BAA8B,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAGtE;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAQxD;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAsBtD"}
|
|
1
|
+
{"version":3,"file":"storage-errors.d.ts","sourceRoot":"","sources":["../src/storage-errors.ts"],"names":[],"mappings":"AAmEA,yFAAyF;AACzF,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAQ9D;AAED,wFAAwF;AACxF,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAEzD;AAED,iFAAiF;AACjF,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAI/E;AAED,kFAAkF;AAClF,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAE7D;AAED;;;;GAIG;AACH,wBAAgB,8BAA8B,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAGtE;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAQxD;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAsBtD"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sixb/pg",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.22",
|
|
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.22"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
|
-
"@sixb/core": "0.1.
|
|
46
|
+
"@sixb/core": "0.1.22",
|
|
47
47
|
"@types/bun": "latest",
|
|
48
48
|
"typescript": "^5.7.0"
|
|
49
49
|
},
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import type { AgentStorage, ExecutionStorage } from "@sixb/core/storage"
|
|
2
2
|
import type { PgStoreClient } from "../transactions"
|
|
3
|
+
import { PgAgentApprovalStore } from "./approvals"
|
|
3
4
|
import { PgAgentContextCheckpointStore } from "./checkpoints"
|
|
5
|
+
import { PgAgentMemoryStore } from "./memory"
|
|
4
6
|
import { PgAgentMessageStore } from "./messages"
|
|
5
7
|
import { PgAgentRunStore } from "./runs"
|
|
8
|
+
import { PgAgentApprovalModeStore } from "./settings"
|
|
6
9
|
import { PgAgentThreadStore } from "./threads"
|
|
7
10
|
|
|
8
11
|
export interface PgAgentStorageOptions {
|
|
@@ -11,8 +14,8 @@ export interface PgAgentStorageOptions {
|
|
|
11
14
|
}
|
|
12
15
|
|
|
13
16
|
/**
|
|
14
|
-
* PostgreSQL-backed agent persistence: thread, run, message,
|
|
15
|
-
* sharing one connection. Cross-table writes run inside `runPgTransaction` with `SELECT ... FOR
|
|
17
|
+
* PostgreSQL-backed agent persistence: thread, run, message, context-checkpoint, memory, approval
|
|
18
|
+
* and approval-mode sub-stores sharing one connection. Cross-table writes run inside `runPgTransaction` with `SELECT ... FOR
|
|
16
19
|
* UPDATE` row locks for single-flight and checkpoint compare-and-swap safety.
|
|
17
20
|
*/
|
|
18
21
|
export class PgAgentStorage implements AgentStorage {
|
|
@@ -20,11 +23,17 @@ export class PgAgentStorage implements AgentStorage {
|
|
|
20
23
|
readonly runs: PgAgentRunStore
|
|
21
24
|
readonly messages: PgAgentMessageStore
|
|
22
25
|
readonly checkpoints: PgAgentContextCheckpointStore
|
|
26
|
+
readonly memory: PgAgentMemoryStore
|
|
27
|
+
readonly approvals: PgAgentApprovalStore
|
|
28
|
+
readonly approvalModes: PgAgentApprovalModeStore
|
|
23
29
|
|
|
24
30
|
constructor(options: PgAgentStorageOptions) {
|
|
25
31
|
this.threads = new PgAgentThreadStore(options.sql)
|
|
26
32
|
this.runs = new PgAgentRunStore(options.sql, options.executions)
|
|
27
33
|
this.messages = new PgAgentMessageStore(options.sql)
|
|
28
34
|
this.checkpoints = new PgAgentContextCheckpointStore(options.sql)
|
|
35
|
+
this.memory = new PgAgentMemoryStore(options.sql)
|
|
36
|
+
this.approvals = new PgAgentApprovalStore(options.sql)
|
|
37
|
+
this.approvalModes = new PgAgentApprovalModeStore(options.sql)
|
|
29
38
|
}
|
|
30
39
|
}
|
|
@@ -0,0 +1,400 @@
|
|
|
1
|
+
import type { Principal } from "@sixb/core"
|
|
2
|
+
import {
|
|
3
|
+
agentApprovalCallKey,
|
|
4
|
+
assertAgentApprovalCaller,
|
|
5
|
+
assertRequestAgentApprovalInput,
|
|
6
|
+
newAgentApprovalRecord,
|
|
7
|
+
} from "@sixb/core/internal/agent-run-storage-provider"
|
|
8
|
+
import {
|
|
9
|
+
type AgentApprovalCall,
|
|
10
|
+
type AgentApprovalCursor,
|
|
11
|
+
type AgentApprovalMode,
|
|
12
|
+
type AgentApprovalOutcome,
|
|
13
|
+
type AgentApprovalRecord,
|
|
14
|
+
type AgentApprovalStore,
|
|
15
|
+
AgentStorageError,
|
|
16
|
+
type DecideAgentApprovalInput,
|
|
17
|
+
type DecideAgentApprovalResult,
|
|
18
|
+
type ListAgentApprovalsInput,
|
|
19
|
+
type ListAgentApprovalsResult,
|
|
20
|
+
type MarkAgentApprovalsReportedInput,
|
|
21
|
+
type RequestAgentApprovalInput,
|
|
22
|
+
type RequestAgentApprovalResult,
|
|
23
|
+
type SettleAgentApprovalsInput,
|
|
24
|
+
type StopAgentApprovalsInput,
|
|
25
|
+
type StopAgentApprovalsResult,
|
|
26
|
+
} from "@sixb/core/storage"
|
|
27
|
+
import type { SQLClient } from "../pg-client"
|
|
28
|
+
import { type PgStoreClient, runPgTransaction } from "../transactions"
|
|
29
|
+
import { type AgentRunRow, rowToRunRecord } from "./rows"
|
|
30
|
+
|
|
31
|
+
interface AgentApprovalRow {
|
|
32
|
+
readonly project_id: string
|
|
33
|
+
readonly id: string
|
|
34
|
+
readonly thread_id: string
|
|
35
|
+
readonly run_id: string
|
|
36
|
+
readonly caller_run_id: string
|
|
37
|
+
readonly requested_by_type: Principal["type"]
|
|
38
|
+
readonly requested_by_id: string
|
|
39
|
+
readonly mode: AgentApprovalRecord["mode"]
|
|
40
|
+
readonly call_key: string
|
|
41
|
+
readonly call: AgentApprovalCall | string
|
|
42
|
+
readonly status: AgentApprovalRecord["status"]
|
|
43
|
+
readonly created_at: Date | string
|
|
44
|
+
readonly expires_at: Date | string
|
|
45
|
+
readonly decided_at: Date | string | null
|
|
46
|
+
readonly decided_by_type: Principal["type"] | null
|
|
47
|
+
readonly decided_by_id: string | null
|
|
48
|
+
readonly outcome: AgentApprovalOutcome | string | null
|
|
49
|
+
readonly reported_in_message_id: string | null
|
|
50
|
+
readonly raised_mode: AgentApprovalMode | null
|
|
51
|
+
readonly turn_stopped_at: Date | string | null
|
|
52
|
+
readonly execution_claimed_at: Date | string | null
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export class PgAgentApprovalStore implements AgentApprovalStore {
|
|
56
|
+
constructor(private readonly sql: PgStoreClient) {}
|
|
57
|
+
|
|
58
|
+
async request(input: RequestAgentApprovalInput): Promise<RequestAgentApprovalResult> {
|
|
59
|
+
assertRequestAgentApprovalInput(input, "SixbPg")
|
|
60
|
+
|
|
61
|
+
return runPgTransaction(this.sql, async (tx) => {
|
|
62
|
+
// The caller's row lock serializes its requests with its `finish`, which cancels them.
|
|
63
|
+
const turn = await lockRun(tx, input.projectId, input.runId)
|
|
64
|
+
const caller =
|
|
65
|
+
input.callerRunId === input.runId
|
|
66
|
+
? turn
|
|
67
|
+
: await lockRun(tx, input.projectId, input.callerRunId)
|
|
68
|
+
const threadId = assertAgentApprovalCaller({ request: input, turn, caller, prefix: "SixbPg" })
|
|
69
|
+
|
|
70
|
+
const live = await selectLive(tx, input.projectId, threadId, agentApprovalCallKey(input.call))
|
|
71
|
+
if (live) return { approval: rowToApproval(live), created: false }
|
|
72
|
+
|
|
73
|
+
const approval = newAgentApprovalRecord(input, threadId)
|
|
74
|
+
const [inserted] = await tx<AgentApprovalRow[]>`
|
|
75
|
+
INSERT INTO agent_approvals (
|
|
76
|
+
project_id, id, thread_id, run_id, caller_run_id, requested_by_type, requested_by_id,
|
|
77
|
+
mode, call_key, call, status, created_at, expires_at
|
|
78
|
+
) VALUES (
|
|
79
|
+
${approval.projectId}, ${approval.id}, ${approval.threadId}, ${approval.runId},
|
|
80
|
+
${approval.callerRunId}, ${approval.requestedBy.type}, ${approval.requestedBy.id},
|
|
81
|
+
${approval.mode}, ${approval.callKey}, ${JSON.stringify(approval.call)}::text::jsonb,
|
|
82
|
+
'pending', ${approval.createdAt}, ${approval.expiresAt}
|
|
83
|
+
)
|
|
84
|
+
ON CONFLICT DO NOTHING
|
|
85
|
+
RETURNING *
|
|
86
|
+
`
|
|
87
|
+
if (inserted) return { approval: rowToApproval(inserted), created: true }
|
|
88
|
+
|
|
89
|
+
// Another caller of the same turn held the call first.
|
|
90
|
+
const raced = await selectLive(tx, input.projectId, threadId, approval.callKey)
|
|
91
|
+
if (raced) return { approval: rowToApproval(raced), created: false }
|
|
92
|
+
throw new AgentStorageError(
|
|
93
|
+
"duplicate_id",
|
|
94
|
+
`[SixbPg] Agent approval '${input.id}' already exists for project '${input.projectId}'.`
|
|
95
|
+
)
|
|
96
|
+
})
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
async decide(input: DecideAgentApprovalInput): Promise<DecideAgentApprovalResult | null> {
|
|
100
|
+
const decidedAt = input.decidedAt ?? new Date()
|
|
101
|
+
const [row] = await this.sql<AgentApprovalRow[]>`
|
|
102
|
+
UPDATE agent_approvals
|
|
103
|
+
SET
|
|
104
|
+
status = CASE WHEN expires_at <= ${decidedAt} THEN 'expired' ELSE ${input.decision} END,
|
|
105
|
+
decided_at = CASE WHEN expires_at <= ${decidedAt} THEN NULL ELSE ${decidedAt}::timestamptz END,
|
|
106
|
+
decided_by_type = CASE WHEN expires_at <= ${decidedAt} THEN NULL ELSE ${input.decidedBy.type} END,
|
|
107
|
+
decided_by_id = CASE WHEN expires_at <= ${decidedAt} THEN NULL ELSE ${input.decidedBy.id} END,
|
|
108
|
+
raised_mode = CASE WHEN expires_at <= ${decidedAt} OR ${input.decision} <> 'approved'
|
|
109
|
+
THEN NULL ELSE ${input.raisedMode ?? null}::text END
|
|
110
|
+
WHERE project_id = ${input.projectId} AND id = ${input.id} AND status = 'pending'
|
|
111
|
+
RETURNING *
|
|
112
|
+
`
|
|
113
|
+
if (row) {
|
|
114
|
+
const approval = rowToApproval(row)
|
|
115
|
+
return { approval, decided: approval.status === input.decision }
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const current = await this.getById(input)
|
|
119
|
+
return current ? { approval: current, decided: false } : null
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
async recordOutcome(input: {
|
|
123
|
+
readonly projectId: string
|
|
124
|
+
readonly id: string
|
|
125
|
+
readonly outcome: AgentApprovalOutcome
|
|
126
|
+
}): Promise<AgentApprovalRecord> {
|
|
127
|
+
const [row] = await this.sql<AgentApprovalRow[]>`
|
|
128
|
+
UPDATE agent_approvals
|
|
129
|
+
SET outcome = ${JSON.stringify(input.outcome)}::text::jsonb
|
|
130
|
+
WHERE project_id = ${input.projectId} AND id = ${input.id}
|
|
131
|
+
AND status = 'approved' AND outcome IS NULL
|
|
132
|
+
RETURNING *
|
|
133
|
+
`
|
|
134
|
+
if (row) return rowToApproval(row)
|
|
135
|
+
|
|
136
|
+
const current = await this.getById(input)
|
|
137
|
+
if (current?.status === "approved") return current
|
|
138
|
+
throw new AgentStorageError(
|
|
139
|
+
"invalid_state",
|
|
140
|
+
current
|
|
141
|
+
? `[SixbPg] Agent approval '${input.id}' is not approved (status '${current.status}').`
|
|
142
|
+
: `[SixbPg] Agent approval '${input.id}' not found for project '${input.projectId}'.`
|
|
143
|
+
)
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
async settle(input: SettleAgentApprovalsInput): Promise<readonly AgentApprovalRecord[]> {
|
|
147
|
+
const rows = await this.sql<AgentApprovalRow[]>`
|
|
148
|
+
UPDATE agent_approvals SET status = ${input.status}
|
|
149
|
+
WHERE project_id = ${input.projectId} AND thread_id = ${input.threadId}
|
|
150
|
+
AND status = 'pending'
|
|
151
|
+
RETURNING *
|
|
152
|
+
`
|
|
153
|
+
return rows.map(rowToApproval).sort(compareApprovals)
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
async stop(input: StopAgentApprovalsInput): Promise<StopAgentApprovalsResult> {
|
|
157
|
+
const runId = input.runId ?? null
|
|
158
|
+
const requesterType = input.requestedBy?.type ?? null
|
|
159
|
+
const requesterId = input.requestedBy?.id ?? null
|
|
160
|
+
const stoppedAt = input.stoppedAt ?? new Date()
|
|
161
|
+
|
|
162
|
+
// What each row was before the update tells what this stop changed.
|
|
163
|
+
const rows = await this.sql<
|
|
164
|
+
(AgentApprovalRow & { readonly was_pending: boolean; readonly newly_stopped: boolean })[]
|
|
165
|
+
>`
|
|
166
|
+
WITH matched AS (
|
|
167
|
+
SELECT id, status = 'pending' AS was_pending, turn_stopped_at IS NULL AS newly_stopped
|
|
168
|
+
FROM agent_approvals
|
|
169
|
+
WHERE project_id = ${input.projectId} AND thread_id = ${input.threadId}
|
|
170
|
+
AND reported_in_message_id IS NULL
|
|
171
|
+
AND (status = 'pending' OR turn_stopped_at IS NULL)
|
|
172
|
+
AND (${runId}::text IS NULL OR run_id = ${runId})
|
|
173
|
+
AND (${requesterType}::text IS NULL
|
|
174
|
+
OR (requested_by_type = ${requesterType} AND requested_by_id = ${requesterId}))
|
|
175
|
+
FOR UPDATE
|
|
176
|
+
)
|
|
177
|
+
UPDATE agent_approvals AS approval
|
|
178
|
+
SET
|
|
179
|
+
status = CASE WHEN matched.was_pending THEN 'cancelled' ELSE approval.status END,
|
|
180
|
+
turn_stopped_at = COALESCE(approval.turn_stopped_at, ${stoppedAt}::timestamptz)
|
|
181
|
+
FROM matched
|
|
182
|
+
WHERE approval.project_id = ${input.projectId} AND approval.id = matched.id
|
|
183
|
+
RETURNING approval.*, matched.was_pending, matched.newly_stopped
|
|
184
|
+
`
|
|
185
|
+
const cancelled = rows.filter((row) => row.was_pending).map(rowToApproval)
|
|
186
|
+
const stopped = rows.filter((row) => row.newly_stopped).length
|
|
187
|
+
return { cancelled: cancelled.sort(compareApprovals), stopped }
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
async holdsRun(input: { readonly projectId: string; readonly runId: string }): Promise<boolean> {
|
|
191
|
+
return pgHoldsRun(this.sql, input.projectId, input.runId)
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
async claimExecution(input: {
|
|
195
|
+
readonly projectId: string
|
|
196
|
+
readonly id: string
|
|
197
|
+
readonly claimedAt: Date
|
|
198
|
+
readonly staleBefore: Date
|
|
199
|
+
}): Promise<AgentApprovalRecord | null> {
|
|
200
|
+
const [row] = await this.sql<AgentApprovalRow[]>`
|
|
201
|
+
UPDATE agent_approvals SET execution_claimed_at = ${input.claimedAt}
|
|
202
|
+
WHERE project_id = ${input.projectId} AND id = ${input.id}
|
|
203
|
+
AND status = 'approved' AND outcome IS NULL
|
|
204
|
+
AND COALESCE(execution_claimed_at, decided_at) <= ${input.staleBefore}
|
|
205
|
+
RETURNING *
|
|
206
|
+
`
|
|
207
|
+
return row ? rowToApproval(row) : null
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
async listRepairable(input: {
|
|
211
|
+
readonly projectId: string
|
|
212
|
+
readonly claimableBefore: Date
|
|
213
|
+
readonly after?: AgentApprovalCursor
|
|
214
|
+
readonly limit: number
|
|
215
|
+
}): Promise<readonly AgentApprovalRecord[]> {
|
|
216
|
+
const afterAt = input.after?.createdAt ?? null
|
|
217
|
+
const afterId = input.after?.id ?? ""
|
|
218
|
+
// Each half of the OR matches one partial index.
|
|
219
|
+
const rows = await this.sql<AgentApprovalRow[]>`
|
|
220
|
+
SELECT * FROM agent_approvals
|
|
221
|
+
WHERE project_id = ${input.projectId}
|
|
222
|
+
AND (
|
|
223
|
+
(status = 'approved' AND outcome IS NULL
|
|
224
|
+
AND COALESCE(execution_claimed_at, decided_at) <= ${input.claimableBefore})
|
|
225
|
+
OR (status IN ('approved', 'denied') AND reported_in_message_id IS NULL
|
|
226
|
+
AND turn_stopped_at IS NULL)
|
|
227
|
+
)
|
|
228
|
+
AND (${afterAt}::timestamptz IS NULL OR (created_at, id) > (${afterAt}::timestamptz, ${afterId}))
|
|
229
|
+
ORDER BY created_at, id
|
|
230
|
+
LIMIT ${input.limit}
|
|
231
|
+
`
|
|
232
|
+
return rows.map(rowToApproval)
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
async expireDue(input: {
|
|
236
|
+
readonly projectId: string
|
|
237
|
+
readonly now: Date
|
|
238
|
+
readonly limit?: number
|
|
239
|
+
}): Promise<readonly AgentApprovalRecord[]> {
|
|
240
|
+
// The CTE picks the rows once, under the limit; an `IN` subquery did not keep to it.
|
|
241
|
+
const rows = await this.sql<AgentApprovalRow[]>`
|
|
242
|
+
WITH due AS (
|
|
243
|
+
SELECT id FROM agent_approvals
|
|
244
|
+
WHERE project_id = ${input.projectId} AND status = 'pending'
|
|
245
|
+
AND expires_at <= ${input.now}
|
|
246
|
+
ORDER BY created_at, id
|
|
247
|
+
LIMIT ${input.limit ?? null}
|
|
248
|
+
FOR UPDATE SKIP LOCKED
|
|
249
|
+
)
|
|
250
|
+
UPDATE agent_approvals AS approval SET status = 'expired'
|
|
251
|
+
FROM due
|
|
252
|
+
WHERE approval.project_id = ${input.projectId} AND approval.id = due.id
|
|
253
|
+
RETURNING approval.*
|
|
254
|
+
`
|
|
255
|
+
return rows.map(rowToApproval).sort(compareApprovals)
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
async markReported(input: MarkAgentApprovalsReportedInput): Promise<readonly string[]> {
|
|
259
|
+
const ids = [...new Set(input.ids)]
|
|
260
|
+
if (ids.length === 0) return []
|
|
261
|
+
|
|
262
|
+
const rows = await this.sql<{ id: string }[]>`
|
|
263
|
+
UPDATE agent_approvals SET reported_in_message_id = ${input.messageId}
|
|
264
|
+
WHERE project_id = ${input.projectId} AND thread_id = ${input.threadId}
|
|
265
|
+
AND id = ANY(${this.sql.array(ids)}::text[]) AND reported_in_message_id IS NULL
|
|
266
|
+
AND (${input.resuming !== true} OR turn_stopped_at IS NULL)
|
|
267
|
+
RETURNING id
|
|
268
|
+
`
|
|
269
|
+
const marked = new Set(rows.map((row) => row.id))
|
|
270
|
+
return ids.filter((id) => marked.has(id))
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
async getById(params: {
|
|
274
|
+
readonly projectId: string
|
|
275
|
+
readonly id: string
|
|
276
|
+
}): Promise<AgentApprovalRecord | null> {
|
|
277
|
+
const [row] = await this.sql<AgentApprovalRow[]>`
|
|
278
|
+
SELECT * FROM agent_approvals WHERE project_id = ${params.projectId} AND id = ${params.id}
|
|
279
|
+
`
|
|
280
|
+
return row ? rowToApproval(row) : null
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
async list(input: ListAgentApprovalsInput): Promise<ListAgentApprovalsResult> {
|
|
284
|
+
if (input.statuses?.length === 0) return { approvals: [], hasMore: false, total: 0 }
|
|
285
|
+
|
|
286
|
+
const offset = input.offset ?? 0
|
|
287
|
+
return runPgTransaction(
|
|
288
|
+
this.sql,
|
|
289
|
+
async (tx) => {
|
|
290
|
+
const [counted] = await tx<{ total: number }[]>`
|
|
291
|
+
SELECT COUNT(*)::int AS total FROM agent_approvals WHERE ${listFilter(tx, input)}
|
|
292
|
+
`
|
|
293
|
+
const rows = await tx<AgentApprovalRow[]>`
|
|
294
|
+
SELECT * FROM agent_approvals WHERE ${listFilter(tx, input)}
|
|
295
|
+
ORDER BY created_at, id
|
|
296
|
+
LIMIT ${input.limit ?? null} OFFSET ${offset}
|
|
297
|
+
`
|
|
298
|
+
const total = counted?.total ?? 0
|
|
299
|
+
return { approvals: rows.map(rowToApproval), hasMore: offset + rows.length < total, total }
|
|
300
|
+
},
|
|
301
|
+
{ isolation: "repeatableRead" }
|
|
302
|
+
)
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
/** The `list` predicate, as the in-memory store's `agentApprovalMatches` reads it. */
|
|
307
|
+
function listFilter(sql: SQLClient, input: ListAgentApprovalsInput) {
|
|
308
|
+
const threadId = input.threadId ?? null
|
|
309
|
+
const runId = input.runId ?? null
|
|
310
|
+
const requesterType = input.requestedBy?.type ?? null
|
|
311
|
+
const requesterId = input.requestedBy?.id ?? null
|
|
312
|
+
const reported = input.reported ?? null
|
|
313
|
+
const statuses = input.statuses ?? null
|
|
314
|
+
|
|
315
|
+
return sql`
|
|
316
|
+
project_id = ${input.projectId}
|
|
317
|
+
AND (${threadId}::text IS NULL OR thread_id = ${threadId})
|
|
318
|
+
AND (${runId}::text IS NULL OR run_id = ${runId})
|
|
319
|
+
AND (${requesterType}::text IS NULL
|
|
320
|
+
OR (requested_by_type = ${requesterType} AND requested_by_id = ${requesterId}))
|
|
321
|
+
AND (${statuses === null}::boolean OR status = ANY(${sql.array([...(statuses ?? [])])}::text[]))
|
|
322
|
+
AND (${reported}::boolean IS NULL OR (reported_in_message_id IS NOT NULL) = ${reported})
|
|
323
|
+
`
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
async function lockRun(sql: SQLClient, projectId: string, id: string) {
|
|
327
|
+
const [row] = await sql<AgentRunRow[]>`
|
|
328
|
+
SELECT * FROM agent_runs WHERE project_id = ${projectId} AND id = ${id} FOR UPDATE
|
|
329
|
+
`
|
|
330
|
+
return row ? rowToRunRecord(row) : null
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
function selectLive(
|
|
334
|
+
sql: SQLClient,
|
|
335
|
+
projectId: string,
|
|
336
|
+
threadId: string,
|
|
337
|
+
callKey: string
|
|
338
|
+
): Promise<AgentApprovalRow | undefined> {
|
|
339
|
+
return sql<AgentApprovalRow[]>`
|
|
340
|
+
SELECT * FROM agent_approvals
|
|
341
|
+
WHERE project_id = ${projectId} AND thread_id = ${threadId} AND call_key = ${callKey}
|
|
342
|
+
AND status IN ('pending', 'approved', 'denied')
|
|
343
|
+
`.then((rows) => rows[0])
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
function rowToApproval(row: AgentApprovalRow): AgentApprovalRecord {
|
|
347
|
+
return {
|
|
348
|
+
id: row.id,
|
|
349
|
+
projectId: row.project_id,
|
|
350
|
+
threadId: row.thread_id,
|
|
351
|
+
runId: row.run_id,
|
|
352
|
+
callerRunId: row.caller_run_id,
|
|
353
|
+
requestedBy: { type: row.requested_by_type, id: row.requested_by_id },
|
|
354
|
+
mode: row.mode,
|
|
355
|
+
callKey: row.call_key,
|
|
356
|
+
call: parseJson<AgentApprovalCall>(row.call),
|
|
357
|
+
status: row.status,
|
|
358
|
+
createdAt: new Date(row.created_at),
|
|
359
|
+
expiresAt: new Date(row.expires_at),
|
|
360
|
+
...(row.decided_at === null ? {} : { decidedAt: new Date(row.decided_at) }),
|
|
361
|
+
...(row.decided_by_type === null || row.decided_by_id === null
|
|
362
|
+
? {}
|
|
363
|
+
: { decidedBy: { type: row.decided_by_type, id: row.decided_by_id } }),
|
|
364
|
+
...(row.outcome === null ? {} : { outcome: parseJson<AgentApprovalOutcome>(row.outcome) }),
|
|
365
|
+
...(row.reported_in_message_id === null
|
|
366
|
+
? {}
|
|
367
|
+
: { reportedInMessageId: row.reported_in_message_id }),
|
|
368
|
+
...(row.raised_mode === null ? {} : { raisedMode: row.raised_mode }),
|
|
369
|
+
...(row.turn_stopped_at === null ? {} : { turnStoppedAt: new Date(row.turn_stopped_at) }),
|
|
370
|
+
...(row.execution_claimed_at === null
|
|
371
|
+
? {}
|
|
372
|
+
: { executionClaimedAt: new Date(row.execution_claimed_at) }),
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
/**
|
|
377
|
+
* Whether a run holds a call: an approval of its, or one it made for its turn, pending or decided
|
|
378
|
+
* and not reported yet. `holdsRun` and the paused finish of `runs.finish` both ask this.
|
|
379
|
+
*/
|
|
380
|
+
export async function pgHoldsRun(
|
|
381
|
+
sql: PgStoreClient,
|
|
382
|
+
projectId: string,
|
|
383
|
+
runId: string
|
|
384
|
+
): Promise<boolean> {
|
|
385
|
+
const [held] = await sql<{ id: string }[]>`
|
|
386
|
+
SELECT id FROM agent_approvals
|
|
387
|
+
WHERE project_id = ${projectId} AND (run_id = ${runId} OR caller_run_id = ${runId})
|
|
388
|
+
AND status IN ('pending', 'approved', 'denied') AND reported_in_message_id IS NULL
|
|
389
|
+
LIMIT 1
|
|
390
|
+
`
|
|
391
|
+
return held !== undefined
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
function parseJson<T>(value: T | string): T {
|
|
395
|
+
return typeof value === "string" ? (JSON.parse(value) as T) : value
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
function compareApprovals(left: AgentApprovalRecord, right: AgentApprovalRecord): number {
|
|
399
|
+
return left.createdAt.getTime() - right.createdAt.getTime() || left.id.localeCompare(right.id)
|
|
400
|
+
}
|
|
@@ -67,7 +67,10 @@ export class PgAgentContextCheckpointStore implements AgentContextCheckpointStor
|
|
|
67
67
|
|
|
68
68
|
const [existingForRunRow] = await tx<AgentContextCheckpointRow[]>`
|
|
69
69
|
SELECT * FROM agent_context_checkpoints
|
|
70
|
-
WHERE
|
|
70
|
+
WHERE
|
|
71
|
+
project_id = ${input.projectId}
|
|
72
|
+
AND thread_id = ${input.threadId}
|
|
73
|
+
AND created_by_run_id = ${input.createdByRunId}
|
|
71
74
|
`
|
|
72
75
|
if (existingForRunRow) {
|
|
73
76
|
const record = rowToContextCheckpointRecord(existingForRunRow)
|
|
@@ -177,6 +180,7 @@ export class PgAgentContextCheckpointStore implements AgentContextCheckpointStor
|
|
|
177
180
|
|
|
178
181
|
async getByRunIds(input: {
|
|
179
182
|
readonly projectId: string
|
|
183
|
+
readonly threadId: string
|
|
180
184
|
readonly runIds: readonly string[]
|
|
181
185
|
}): Promise<readonly AgentContextCheckpointRecord[]> {
|
|
182
186
|
const runIds = [...new Set(input.runIds)]
|
|
@@ -185,11 +189,11 @@ export class PgAgentContextCheckpointStore implements AgentContextCheckpointStor
|
|
|
185
189
|
const rows: AgentContextCheckpointRow[] = []
|
|
186
190
|
for (let offset = 0; offset < runIds.length; offset += PG_CHECKPOINT_RUN_ID_BATCH_SIZE) {
|
|
187
191
|
const batch = runIds.slice(offset, offset + PG_CHECKPOINT_RUN_ID_BATCH_SIZE)
|
|
188
|
-
const placeholders = batch.map((_, index) => `$${index +
|
|
192
|
+
const placeholders = batch.map((_, index) => `$${index + 3}`).join(", ")
|
|
189
193
|
rows.push(
|
|
190
194
|
...(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]
|
|
195
|
+
`SELECT * FROM agent_context_checkpoints WHERE project_id = $1 AND thread_id = $2 AND created_by_run_id IN (${placeholders})`,
|
|
196
|
+
[input.projectId, input.threadId, ...batch]
|
|
193
197
|
))
|
|
194
198
|
)
|
|
195
199
|
}
|
package/src/agents/index.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export type { PgAgentStorageOptions } from "./agent-storage"
|
|
2
2
|
export { PgAgentStorage } from "./agent-storage"
|
|
3
3
|
export { PgAgentContextCheckpointStore } from "./checkpoints"
|
|
4
|
+
export { PgAgentMemoryStore } from "./memory"
|
|
4
5
|
export { PgAgentMessageStore } from "./messages"
|
|
5
6
|
export { PgAgentRunStore } from "./runs"
|
|
6
7
|
export { PgAgentThreadStore } from "./threads"
|