@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.
Files changed (139) hide show
  1. package/README.md +1 -0
  2. package/dist/agents/agent-storage.d.ts +8 -2
  3. package/dist/agents/agent-storage.d.ts.map +1 -1
  4. package/dist/agents/approvals.d.ts +48 -0
  5. package/dist/agents/approvals.d.ts.map +1 -0
  6. package/dist/agents/checkpoints.d.ts +1 -0
  7. package/dist/agents/checkpoints.d.ts.map +1 -1
  8. package/dist/agents/index.d.ts +1 -0
  9. package/dist/agents/index.d.ts.map +1 -1
  10. package/dist/agents/memory.d.ts +19 -0
  11. package/dist/agents/memory.d.ts.map +1 -0
  12. package/dist/agents/messages.d.ts.map +1 -1
  13. package/dist/agents/rows.d.ts +15 -1
  14. package/dist/agents/rows.d.ts.map +1 -1
  15. package/dist/agents/runs.d.ts +3 -1
  16. package/dist/agents/runs.d.ts.map +1 -1
  17. package/dist/agents/settings.d.ts +29 -0
  18. package/dist/agents/settings.d.ts.map +1 -0
  19. package/dist/agents/threads.d.ts +10 -1
  20. package/dist/agents/threads.d.ts.map +1 -1
  21. package/dist/ai-cost-groups.d.ts.map +1 -1
  22. package/dist/auth-storage/auth-storage.d.ts +3 -2
  23. package/dist/auth-storage/auth-storage.d.ts.map +1 -1
  24. package/dist/auth-storage/sessions.d.ts +2 -1
  25. package/dist/auth-storage/sessions.d.ts.map +1 -1
  26. package/dist/auth-storage/users.d.ts +8 -4
  27. package/dist/auth-storage/users.d.ts.map +1 -1
  28. package/dist/index.d.ts +4 -0
  29. package/dist/index.d.ts.map +1 -1
  30. package/dist/index.js +6001 -2923
  31. package/dist/index.js.map +45 -37
  32. package/dist/migrations.d.ts.map +1 -1
  33. package/dist/objects/conditional-reader.d.ts +17 -0
  34. package/dist/objects/conditional-reader.d.ts.map +1 -0
  35. package/dist/objects/query-compiler.d.ts +27 -1
  36. package/dist/objects/query-compiler.d.ts.map +1 -1
  37. package/dist/objects/query-indexes.d.ts.map +1 -1
  38. package/dist/objects/read-scope.d.ts +10 -1
  39. package/dist/objects/read-scope.d.ts.map +1 -1
  40. package/dist/objects/reader.d.ts +2 -0
  41. package/dist/objects/reader.d.ts.map +1 -1
  42. package/dist/objects/scoped-reader.d.ts +12 -0
  43. package/dist/objects/scoped-reader.d.ts.map +1 -0
  44. package/dist/objects/selected-reader.d.ts +1 -0
  45. package/dist/objects/selected-reader.d.ts.map +1 -1
  46. package/dist/objects/storage.d.ts +7 -1
  47. package/dist/objects/storage.d.ts.map +1 -1
  48. package/dist/ontology-storage/index.d.ts +2 -0
  49. package/dist/ontology-storage/index.d.ts.map +1 -1
  50. package/dist/ontology-storage/materialization-session.d.ts +6 -0
  51. package/dist/ontology-storage/materialization-session.d.ts.map +1 -1
  52. package/dist/ontology-storage/materialization-writer.d.ts +15 -0
  53. package/dist/ontology-storage/materialization-writer.d.ts.map +1 -1
  54. package/dist/ontology-storage/materializations.d.ts.map +1 -1
  55. package/dist/ontology-storage/replacement-plans.d.ts.map +1 -1
  56. package/dist/ontology-storage/sources.d.ts +2 -1
  57. package/dist/ontology-storage/sources.d.ts.map +1 -1
  58. package/dist/ontology-storage/unique-values.d.ts +60 -0
  59. package/dist/ontology-storage/unique-values.d.ts.map +1 -0
  60. package/dist/pg-action-run-storage.d.ts +4 -0
  61. package/dist/pg-action-run-storage.d.ts.map +1 -1
  62. package/dist/pg-activity-storage.d.ts +22 -0
  63. package/dist/pg-activity-storage.d.ts.map +1 -0
  64. package/dist/pg-ai-cost-storage.d.ts.map +1 -1
  65. package/dist/pg-ai-usage-storage.d.ts +8 -1
  66. package/dist/pg-ai-usage-storage.d.ts.map +1 -1
  67. package/dist/pg-artifact-storage.d.ts +26 -0
  68. package/dist/pg-artifact-storage.d.ts.map +1 -0
  69. package/dist/pg-execution-storage.d.ts +3 -1
  70. package/dist/pg-execution-storage.d.ts.map +1 -1
  71. package/dist/pg-workflow-run-storage.d.ts +4 -0
  72. package/dist/pg-workflow-run-storage.d.ts.map +1 -1
  73. package/dist/share-grant-storage.d.ts +2 -1
  74. package/dist/share-grant-storage.d.ts.map +1 -1
  75. package/dist/storage-errors.d.ts +2 -0
  76. package/dist/storage-errors.d.ts.map +1 -1
  77. package/package.json +3 -3
  78. package/src/agents/agent-storage.ts +11 -2
  79. package/src/agents/approvals.ts +400 -0
  80. package/src/agents/checkpoints.ts +8 -4
  81. package/src/agents/index.ts +1 -0
  82. package/src/agents/memory.ts +175 -0
  83. package/src/agents/messages.ts +14 -7
  84. package/src/agents/rows.ts +46 -1
  85. package/src/agents/runs.ts +154 -22
  86. package/src/agents/settings.ts +105 -0
  87. package/src/agents/threads.ts +379 -3
  88. package/src/ai-cost-groups.ts +11 -1
  89. package/src/auth-storage/auth-storage.ts +45 -13
  90. package/src/auth-storage/sessions.ts +20 -0
  91. package/src/auth-storage/users.ts +105 -43
  92. package/src/index.ts +10 -0
  93. package/src/migrations/063-artifacts.sql +67 -0
  94. package/src/migrations/064-drop-output-diagnostics.sql +14 -0
  95. package/src/migrations/065-plan-work-payload-statistics.sql +5 -0
  96. package/src/migrations/066-activity.sql +61 -0
  97. package/src/migrations/067-activity-timeline.sql +15 -0
  98. package/src/migrations/068-activity-interactions.sql +20 -0
  99. package/src/migrations/069-artifact-kinds.sql +4 -0
  100. package/src/migrations/070-artifact-state.sql +16 -0
  101. package/src/migrations/071-agent-thread-participants.sql +16 -0
  102. package/src/migrations/072-forked-context-checkpoints.sql +23 -0
  103. package/src/migrations/073-unique-values.sql +25 -0
  104. package/src/migrations/074-generated-media-usage.sql +21 -0
  105. package/src/migrations/075-model-call-files.sql +11 -0
  106. package/src/migrations/076-agent-memory.sql +33 -0
  107. package/src/migrations/077-artifact-threads.sql +21 -0
  108. package/src/migrations/078-agent-approvals.sql +58 -0
  109. package/src/migrations/079-agent-approval-resume.sql +20 -0
  110. package/src/migrations/080-subagent-threads.sql +145 -0
  111. package/src/migrations/081-subagent-questions.sql +6 -0
  112. package/src/migrations.ts +52 -0
  113. package/src/objects/conditional-reader.ts +44 -0
  114. package/src/objects/prepare-queries.ts +1 -1
  115. package/src/objects/query-compiler.ts +96 -33
  116. package/src/objects/query-indexes.ts +29 -10
  117. package/src/objects/read-scope.ts +140 -25
  118. package/src/objects/reader.ts +50 -6
  119. package/src/objects/scoped-reader.ts +101 -0
  120. package/src/objects/selected-reader.ts +16 -76
  121. package/src/objects/storage.ts +24 -5
  122. package/src/objects/text-count-index.ts +1 -0
  123. package/src/ontology-storage/index.ts +3 -0
  124. package/src/ontology-storage/materialization-session.ts +8 -0
  125. package/src/ontology-storage/materialization-writer.ts +76 -1
  126. package/src/ontology-storage/materializations.ts +20 -1
  127. package/src/ontology-storage/replacement-plans.ts +25 -7
  128. package/src/ontology-storage/sources.ts +37 -0
  129. package/src/ontology-storage/unique-values.ts +274 -0
  130. package/src/pg-action-run-storage.ts +23 -0
  131. package/src/pg-activity-storage.ts +486 -0
  132. package/src/pg-ai-cost-storage.ts +62 -12
  133. package/src/pg-ai-usage-storage.ts +90 -1
  134. package/src/pg-artifact-storage.ts +521 -0
  135. package/src/pg-execution-storage.ts +83 -0
  136. package/src/pg-workflow-run-storage.ts +23 -0
  137. package/src/share-grant-storage.ts +21 -0
  138. package/src/storage-errors.ts +7 -0
  139. 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,EACL,KAAK,mBAAmB,EAIzB,MAAM,uCAAuC,CAAA;AAC9C,OAAO,KAAK,EACV,oBAAoB,EACpB,eAAe,EACf,gBAAgB,EAChB,mBAAmB,EACpB,MAAM,oBAAoB,CAAA;AAE3B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAA;AAEnD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAA;AAEnD,qBAAa,kBAAmB,YAAW,gBAAgB;IAEvD,OAAO,CAAC,QAAQ,CAAC,GAAG;IACpB,OAAO,CAAC,QAAQ,CAAC,IAAI;IACrB,OAAO,CAAC,QAAQ,CAAC,aAAa;gBAFb,GAAG,EAAE,aAAa,EAClB,IAAI,EAAE,aAAa,EACnB,aAAa,EAAE,IAAI,CAAC,mBAAmB,EAAE,SAAS,CAAC;IAGhE,MAAM,CAAC,KAAK,EAAE,oBAAoB,GAAG,OAAO,CAAC,eAAe,CAAC;IA8E7D,OAAO,CAAC,MAAM,EAAE;QACpB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;QAC1B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;KACpB,GAAG,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC;CAQpC;AAED,qGAAqG;AACrG,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,cAAc,GAAG,eAAe,CAEtE;AA8BD,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,aAAa,EAAE,mBAAmB,CAAC,cAAc,CAAC,CAAA;IAC3D,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,WAAW,EAAE,mBAAmB,CAAC,YAAY,CAAC,CAAA;IACvD,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAA;IAC5C,QAAQ,CAAC,+BAA+B,EAAE,MAAM,GAAG,IAAI,CAAA;IACvD,QAAQ,CAAC,mBAAmB,EAAE,MAAM,EAAE,CAAA;IACtC,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAA;IAC/B,QAAQ,CAAC,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3C,QAAQ,CAAC,cAAc,EAAE,mBAAmB,CAAC,eAAe,CAAC,CAAA;IAC7D,QAAQ,CAAC,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAA;IACzC,QAAQ,CAAC,4BAA4B,EAAE,MAAM,GAAG,IAAI,CAAA;IACpD,QAAQ,CAAC,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAA;IAC5C,QAAQ,CAAC,yBAAyB,EAAE,MAAM,GAAG,IAAI,CAAA;IACjD,QAAQ,CAAC,wBAAwB,EAAE,mBAAmB,CAAC,wBAAwB,CAAC,CAAA;IAChF,QAAQ,CAAC,sBAAsB,EAAE,MAAM,GAAG,IAAI,CAAA;IAC9C,QAAQ,CAAC,0BAA0B,EAAE,mBAAmB,CAAC,0BAA0B,CAAC,CAAA;IACpF,QAAQ,CAAC,yBAAyB,EAAE,mBAAmB,CAAC,yBAAyB,CAAC,CAAA;IAClF,QAAQ,CAAC,uBAAuB,EAAE,MAAM,GAAG,IAAI,CAAA;IAC/C,QAAQ,CAAC,+BAA+B,EAAE,MAAM,GAAG,IAAI,CAAA;IACvD,QAAQ,CAAC,UAAU,EAAE,IAAI,GAAG,MAAM,CAAA;CACnC"}
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"}
@@ -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.20",
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.20"
43
+ "@sixb/core": "0.1.22"
44
44
  },
45
45
  "devDependencies": {
46
- "@sixb/core": "0.1.20",
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, and context-checkpoint sub-stores
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 project_id = ${input.projectId} AND created_by_run_id = ${input.createdByRunId}
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 + 2}`).join(", ")
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
  }
@@ -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"