@yielded/agent 0.1.0-beta.172 → 0.1.0-beta.174

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 (226) hide show
  1. package/dist/{Admin-BX9ns28E.d.mts → Admin-BHmp2V9p.d.mts} +25 -16
  2. package/dist/{Agent-9aBoIi74.d.mts → Agent-B39jRnFv.d.mts} +2 -2
  3. package/dist/{Agent-0WvBWWbM.mjs → Agent-BiRbr73L.mjs} +7 -6
  4. package/dist/Agent-BiRbr73L.mjs.map +1 -0
  5. package/dist/{AgentRuntime-CQ-qcETl.mjs → AgentRuntime-B6qZlD3f.mjs} +199 -191
  6. package/dist/AgentRuntime-B6qZlD3f.mjs.map +1 -0
  7. package/dist/{AgentRuntime-BfP14534.d.mts → AgentRuntime-BD3ZHAMq.d.mts} +10 -10
  8. package/dist/{Digest-DCuPlhNk.mjs → Digest-EpeqWEdv.mjs} +41 -14
  9. package/dist/Digest-EpeqWEdv.mjs.map +1 -0
  10. package/dist/{DurableAgentRuntime-BAmSkWYr.mjs → DurableAgentRuntime-CBBjRNJN.mjs} +1447 -1424
  11. package/dist/DurableAgentRuntime-CBBjRNJN.mjs.map +1 -0
  12. package/dist/{EventSource-BwliwQz9.d.mts → EventSource-C9aaJaXT.d.mts} +2 -2
  13. package/dist/{MessageDelivery-CeSDfHZa.d.mts → MessageDelivery-BGDm-c46.d.mts} +4 -4
  14. package/dist/{Messaging-C_6OOg_s.d.mts → Messaging-SVu6rWV8.d.mts} +12 -6
  15. package/dist/{MessagingHost-B8oKM7AC.d.mts → MessagingHost-C6SOAcoG.d.mts} +2 -2
  16. package/dist/{Output-Dsx6k52t.d.mts → Output-CRamN1Fy.d.mts} +2 -2
  17. package/dist/{PreparedInputAdmission-CxSJSiTl.d.mts → PreparedInputAdmission-BvDqlgiP.d.mts} +3 -3
  18. package/dist/{RunContinuation-DHYNAQFi.mjs → RunContinuation-4ZATcVLB.mjs} +113 -56
  19. package/dist/RunContinuation-4ZATcVLB.mjs.map +1 -0
  20. package/dist/{RunContinuation-FHM7XPjq.d.mts → RunContinuation-CTJ1jGrO.d.mts} +6 -6
  21. package/dist/{RunJournal-kfKVxJj7.mjs → RunJournal-CNZqA3Ge.mjs} +33 -5
  22. package/dist/RunJournal-CNZqA3Ge.mjs.map +1 -0
  23. package/dist/{RunOptions-D8zxFIrZ.d.mts → RunOptions-Be77lKVZ.d.mts} +2 -2
  24. package/dist/{RunStorage-uqPxps09.mjs → RunStorage-BHjuuERI.mjs} +9 -6
  25. package/dist/RunStorage-BHjuuERI.mjs.map +1 -0
  26. package/dist/{Scheduling-CVyfXlBR.mjs → Scheduling-NG8slKdI.mjs} +11 -11
  27. package/dist/Scheduling-NG8slKdI.mjs.map +1 -0
  28. package/dist/{Subagent-vpffemql.mjs → Subagent-CTIpnzlB.mjs} +53 -40
  29. package/dist/Subagent-CTIpnzlB.mjs.map +1 -0
  30. package/dist/{Subagent-E6tvd7-k.d.mts → Subagent-DKhZA72u.d.mts} +19 -8
  31. package/dist/{SubagentHost-B6w2m-SI.d.mts → SubagentHost-D1xBgn9g.d.mts} +2 -2
  32. package/dist/{Subscription-DONig54Q.d.mts → Subscription-BNg9VCRl.d.mts} +2 -2
  33. package/dist/{SubscriptionInput-mJIRxWJM.d.mts → SubscriptionInput-BUoXv-_K.d.mts} +2 -2
  34. package/dist/{ThreadImport-CoQTZywm.d.mts → ThreadImport-CMgzttvr.d.mts} +43 -43
  35. package/dist/{ThreadImport-DckUMEqJ.mjs → ThreadImport-CodYoJoa.mjs} +7 -7
  36. package/dist/ThreadImport-CodYoJoa.mjs.map +1 -0
  37. package/dist/{ThreadStore-CEekRa80.mjs → ThreadStore-59uDGXul.mjs} +163 -84
  38. package/dist/ThreadStore-59uDGXul.mjs.map +1 -0
  39. package/dist/{ThreadTransfer-B4gTQLIl.mjs → ThreadTransfer-3jigUl3g.mjs} +3 -3
  40. package/dist/{ThreadTransfer-B4gTQLIl.mjs.map → ThreadTransfer-3jigUl3g.mjs.map} +1 -1
  41. package/dist/{WorkerAdmission-DFVbbVh2.mjs → WorkerAdmission-DDYJdOsU.mjs} +4 -4
  42. package/dist/{WorkerAdmission-DFVbbVh2.mjs.map → WorkerAdmission-DDYJdOsU.mjs.map} +1 -1
  43. package/dist/{agent-registration-ByMZ_cK5.mjs → agent-registration-DRbyhAu-.mjs} +69 -56
  44. package/dist/agent-registration-DRbyhAu-.mjs.map +1 -0
  45. package/dist/capabilities/Approval.mjs +2 -2
  46. package/dist/capabilities/Approval.mjs.map +1 -1
  47. package/dist/capabilities/BrowserUse.d.mts +102 -1867
  48. package/dist/capabilities/BrowserUse.mjs +74 -798
  49. package/dist/capabilities/BrowserUse.mjs.map +1 -1
  50. package/dist/capabilities/Budget.mjs +3 -1
  51. package/dist/capabilities/Budget.mjs.map +1 -1
  52. package/dist/capabilities/CodeMode.d.mts +1 -1
  53. package/dist/capabilities/CodeMode.mjs +16 -9
  54. package/dist/capabilities/CodeMode.mjs.map +1 -1
  55. package/dist/capabilities/Commands.d.mts +1 -1
  56. package/dist/capabilities/McpClient.mjs +1 -1
  57. package/dist/capabilities/McpClient.mjs.map +1 -1
  58. package/dist/capabilities/Messaging.d.mts +1 -1
  59. package/dist/capabilities/Messaging.mjs +4 -4
  60. package/dist/capabilities/Messaging.mjs.map +1 -1
  61. package/dist/capabilities/ModelContext.mjs +7 -5
  62. package/dist/capabilities/ModelContext.mjs.map +1 -1
  63. package/dist/capabilities/Redaction.mjs +49 -19
  64. package/dist/capabilities/Redaction.mjs.map +1 -1
  65. package/dist/capabilities/RunHooks.d.mts +1 -1
  66. package/dist/capabilities/RunHooks.mjs +1 -1
  67. package/dist/capabilities/RunHooks.mjs.map +1 -1
  68. package/dist/capabilities/Subagent.d.mts +1 -1
  69. package/dist/capabilities/Subagent.mjs +1 -1
  70. package/dist/capabilities/SubagentReservations.mjs +3 -1
  71. package/dist/capabilities/SubagentReservations.mjs.map +1 -1
  72. package/dist/capabilities/WebCapture.mjs.map +1 -1
  73. package/dist/capabilities/WebSearch.mjs +7 -7
  74. package/dist/capabilities/WebSearch.mjs.map +1 -1
  75. package/dist/core/Agent.d.mts +1 -1
  76. package/dist/core/Agent.mjs +1 -1
  77. package/dist/core/AgentUpdates.mjs +8 -8
  78. package/dist/core/AgentUpdates.mjs.map +1 -1
  79. package/dist/core/Thread.mjs +1 -1
  80. package/dist/core/Thread.mjs.map +1 -1
  81. package/dist/core/Usage.mjs +2 -2
  82. package/dist/core/Usage.mjs.map +1 -1
  83. package/dist/durable/Admin.d.mts +1 -1
  84. package/dist/durable/AgentRegistration.d.mts +1 -1
  85. package/dist/durable/AgentRegistration.mjs +1 -1
  86. package/dist/durable/Certification.d.mts +1 -1
  87. package/dist/durable/CommittedActivity.d.mts +1 -1
  88. package/dist/durable/CommittedActivity.mjs +2 -2
  89. package/dist/durable/Digest.mjs +1 -1
  90. package/dist/durable/DurableAgentRuntime.d.mts +1 -1
  91. package/dist/durable/DurableAgentRuntime.mjs +2 -2
  92. package/dist/durable/EventSource.d.mts +1 -1
  93. package/dist/durable/EventSource.mjs +6 -6
  94. package/dist/durable/EventSource.mjs.map +1 -1
  95. package/dist/durable/GitHubWorkflowSource.d.mts +3 -3
  96. package/dist/durable/LifecyclePublication.d.mts +1 -1
  97. package/dist/durable/LifecyclePublication.mjs +1 -1
  98. package/dist/durable/MessageDelivery.d.mts +1 -1
  99. package/dist/durable/MessageDelivery.mjs +1 -1
  100. package/dist/durable/MessageDeliveryStoreConformance.d.mts +2 -2
  101. package/dist/durable/MessageDeliveryStoreConformance.mjs +1 -1
  102. package/dist/durable/PersistentHistory.d.mts +1 -1
  103. package/dist/durable/PersistentHistory.mjs +3 -3
  104. package/dist/durable/PreparedInputAdmission.d.mts +1 -1
  105. package/dist/durable/RecordFormat.mjs +2 -2
  106. package/dist/durable/RecordFormat.mjs.map +1 -1
  107. package/dist/durable/Recovery.d.mts +1 -1
  108. package/dist/durable/RunContinuation.d.mts +2 -2
  109. package/dist/durable/RunContinuation.mjs +2 -2
  110. package/dist/durable/RunJournal.d.mts +1 -1
  111. package/dist/durable/RunJournal.mjs +1 -1
  112. package/dist/durable/RunStorage.d.mts +1 -1
  113. package/dist/durable/RunStorage.mjs +1 -1
  114. package/dist/durable/Scheduling.d.mts +1 -1
  115. package/dist/durable/Scheduling.mjs +1 -1
  116. package/dist/durable/SettlementPublisher.d.mts +1 -1
  117. package/dist/durable/SettlementPublisher.mjs +2 -2
  118. package/dist/durable/SubmissionLedger.d.mts +1 -1
  119. package/dist/durable/SubmissionLedger.mjs +5 -1
  120. package/dist/durable/SubmissionLedger.mjs.map +1 -1
  121. package/dist/durable/SubmissionLedgerConformance.d.mts +1 -1
  122. package/dist/durable/SubmissionLedgerConformance.mjs +4 -4
  123. package/dist/durable/SubmissionStatus.d.mts +1 -1
  124. package/dist/durable/Subscription.d.mts +1 -1
  125. package/dist/durable/SubscriptionInput.d.mts +1 -1
  126. package/dist/durable/SubscriptionInput.mjs +3 -3
  127. package/dist/durable/SubscriptionInput.mjs.map +1 -1
  128. package/dist/durable/SubscriptionStoreConformance.d.mts +1 -1
  129. package/dist/durable/SubscriptionStoreConformance.mjs +2 -2
  130. package/dist/durable/SubscriptionStoreConformance.mjs.map +1 -1
  131. package/dist/durable/SubscriptionTools.d.mts +2 -2
  132. package/dist/durable/SubscriptionTransition.d.mts +1 -1
  133. package/dist/durable/Subscriptions.d.mts +5 -5
  134. package/dist/durable/Subscriptions.mjs +2 -2
  135. package/dist/durable/Subscriptions.mjs.map +1 -1
  136. package/dist/durable/ThreadArchiveRange.d.mts +1 -1
  137. package/dist/durable/ThreadContextHistory.d.mts +1 -1
  138. package/dist/durable/ThreadContextHistory.mjs +1 -1
  139. package/dist/durable/ThreadImport.d.mts +1 -1
  140. package/dist/durable/ThreadImport.mjs +1 -1
  141. package/dist/durable/ThreadInvariants.d.mts +3 -3
  142. package/dist/durable/ThreadInvariants.mjs +4 -4
  143. package/dist/durable/ThreadInvariants.mjs.map +1 -1
  144. package/dist/durable/ThreadProjectionMaintenance.d.mts +1 -1
  145. package/dist/durable/ThreadReader.d.mts +1 -1
  146. package/dist/durable/ThreadReader.mjs +1 -1
  147. package/dist/durable/ThreadStore.d.mts +1 -1
  148. package/dist/durable/ThreadStore.mjs +1 -1
  149. package/dist/durable/ThreadStoreConformance.d.mts +1 -1
  150. package/dist/durable/ThreadStoreConformance.mjs +3 -3
  151. package/dist/durable/ThreadTransfer.d.mts +1 -1
  152. package/dist/durable/ThreadTransfer.mjs +1 -1
  153. package/dist/durable/ThreadWork.d.mts +1 -1
  154. package/dist/durable/ThreadWork.mjs +4 -4
  155. package/dist/durable/ThreadWork.mjs.map +1 -1
  156. package/dist/durable/WorkerAdmission.d.mts +1 -1
  157. package/dist/durable/WorkerAdmission.mjs +1 -1
  158. package/dist/durable/WorkerHost.d.mts +2 -2
  159. package/dist/engine/AgentRuntime.d.mts +1 -1
  160. package/dist/engine/AgentRuntime.mjs +1 -1
  161. package/dist/engine/MessagingHost.d.mts +1 -1
  162. package/dist/engine/Output.d.mts +1 -1
  163. package/dist/engine/RunOptions.d.mts +1 -1
  164. package/dist/engine/SubagentHost.d.mts +1 -1
  165. package/dist/index.d.mts +19 -19
  166. package/dist/index.mjs +14 -14
  167. package/dist/{run-context-reader-OcsZr4bk.d.mts → run-context-reader-CC7ZD95F.d.mts} +2 -2
  168. package/package.json +1 -1
  169. package/src/capabilities/Approval.ts +58 -60
  170. package/src/capabilities/BrowserUse.ts +89 -944
  171. package/src/capabilities/Budget.ts +8 -1
  172. package/src/capabilities/CodeMode.ts +57 -33
  173. package/src/capabilities/McpClient.ts +2 -2
  174. package/src/capabilities/Messaging.ts +51 -55
  175. package/src/capabilities/ModelContext.ts +5 -2
  176. package/src/capabilities/Redaction.ts +64 -34
  177. package/src/capabilities/RunHooks.ts +52 -55
  178. package/src/capabilities/Subagent.ts +33 -33
  179. package/src/capabilities/SubagentReservations.ts +9 -1
  180. package/src/capabilities/WebCapture.ts +6 -0
  181. package/src/capabilities/WebSearch.ts +10 -7
  182. package/src/capabilities/internal/subagent-background.ts +202 -158
  183. package/src/core/Agent.ts +11 -6
  184. package/src/core/AgentUpdates.ts +8 -8
  185. package/src/core/Thread.ts +9 -10
  186. package/src/core/Usage.ts +7 -8
  187. package/src/core/internal/agent-updates.ts +1 -0
  188. package/src/durable/DurableAgentRuntime.ts +645 -625
  189. package/src/durable/EventSource.ts +15 -9
  190. package/src/durable/RecordFormat.ts +5 -3
  191. package/src/durable/RunContinuation.ts +233 -81
  192. package/src/durable/RunJournal.ts +10 -9
  193. package/src/durable/RunStorage.ts +122 -124
  194. package/src/durable/Scheduling.ts +639 -651
  195. package/src/durable/SubmissionLedger.ts +4 -0
  196. package/src/durable/SubscriptionInput.ts +5 -3
  197. package/src/durable/SubscriptionStoreConformance.ts +23 -23
  198. package/src/durable/Subscriptions.ts +18 -19
  199. package/src/durable/ThreadImport.ts +18 -19
  200. package/src/durable/ThreadInvariants.ts +2 -1
  201. package/src/durable/ThreadStore.ts +215 -111
  202. package/src/durable/ThreadWork.ts +1 -2
  203. package/src/durable/internal/StorageOwner.ts +10 -4
  204. package/src/durable/internal/agent-registration.ts +96 -89
  205. package/src/durable/internal/canonical-json.ts +61 -20
  206. package/src/durable/internal/prompt-history-cache.ts +13 -4
  207. package/src/durable/internal/record-encoding.ts +120 -64
  208. package/src/durable/internal/schedule-time.ts +6 -6
  209. package/src/durable/internal/usage-totals.ts +38 -0
  210. package/src/durable/internal/worker-host.ts +69 -74
  211. package/src/engine/internal/agent-runtime.ts +1067 -1018
  212. package/src/engine/internal/provisional-text.ts +12 -10
  213. package/src/engine/internal/tool-exposure.ts +22 -18
  214. package/src/engine/internal/tool-telemetry.ts +12 -7
  215. package/dist/Agent-0WvBWWbM.mjs.map +0 -1
  216. package/dist/AgentRuntime-CQ-qcETl.mjs.map +0 -1
  217. package/dist/Digest-DCuPlhNk.mjs.map +0 -1
  218. package/dist/DurableAgentRuntime-BAmSkWYr.mjs.map +0 -1
  219. package/dist/RunContinuation-DHYNAQFi.mjs.map +0 -1
  220. package/dist/RunJournal-kfKVxJj7.mjs.map +0 -1
  221. package/dist/RunStorage-uqPxps09.mjs.map +0 -1
  222. package/dist/Scheduling-CVyfXlBR.mjs.map +0 -1
  223. package/dist/Subagent-vpffemql.mjs.map +0 -1
  224. package/dist/ThreadImport-DckUMEqJ.mjs.map +0 -1
  225. package/dist/ThreadStore-CEekRa80.mjs.map +0 -1
  226. package/dist/agent-registration-ByMZ_cK5.mjs.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"ThreadTransfer-B4gTQLIl.mjs","names":[],"sources":["../src/durable/internal/thread-transfer-source.ts","../src/durable/ThreadTransfer.ts"],"sourcesContent":["import { Context } from \"effect\";\n\n/** Installed before opening the source pull, so producer fibers observe the same phase. */\nexport const ImportSourcePhase = Context.Reference<{ writing: boolean } | undefined>(\n \"@effect-agent/thread/internal/ImportSourcePhase\",\n { defaultValue: () => undefined },\n);\n","import { Context, Effect, Schema } from \"effect\";\n\nimport type { ThreadId } from \"../core/Identifiers.ts\";\nimport { canonicalJson, utf8ByteLength } from \"./Digest.ts\";\nimport { ImportSourcePhase } from \"./internal/thread-transfer-source.ts\";\nimport { transferRecordDependencies } from \"./internal/transfer-dependencies.ts\";\nimport {\n type RecordId,\n CURRENT_RECORD_FORMAT,\n CanonicalSequence,\n type CanonicalRecordEnvelope,\n} from \"./Records.ts\";\nimport {\n MAX_THREAD_EXPORT_PAGE_BYTES,\n ThreadExport,\n ThreadExportRequest,\n ThreadExportSnapshot,\n ThreadExportRejected,\n type ThreadNotMaterialized,\n ThreadStoreError,\n} from \"./ThreadStore.ts\";\n\nexport const transferSections = [\n \"admissions\",\n \"aborts\",\n \"approvals\",\n \"resolutions\",\n \"deliveries\",\n] as const;\n\nexport type TransferSection = (typeof transferSections)[number];\n\nexport type TransferFacts = Pick<ThreadExport, \"admissions\" | \"commands\" | \"deliveries\">;\n\nexport type TransferManifest = Pick<\n ThreadExport,\n \"threadId\" | \"format\" | \"tailSequence\" | \"snapshot\" | \"workerSeal\"\n>;\n\n/** Reads share the adapter's single page transaction. Batch reads hydrate archives. */\nexport class ThreadExporterReader extends Context.Service<\n ThreadExporterReader,\n {\n readonly snapshot: (\n threadId: ThreadId,\n captured?: TransferManifest,\n ) => Effect.Effect<\n TransferManifest,\n ThreadStoreError | ThreadNotMaterialized | ThreadExportRejected\n >;\n readonly batch: (\n threadId: ThreadId,\n fromSequence: number,\n ) => Effect.Effect<\n Pick<ThreadExport, \"records\" | \"batches\">,\n ThreadStoreError | ThreadNotMaterialized\n >;\n /** A keyset read of at most 256 facts. Keys stay bounded independently of fact identities. */\n readonly facts: (\n threadId: ThreadId,\n section: TransferSection,\n after: string | undefined,\n ) => Effect.Effect<\n {\n readonly facts: TransferFacts;\n readonly after: string;\n },\n ThreadStoreError\n >;\n }\n>()(\"@effect-agent/thread/ThreadExporterReader\") {}\n\nexport const TransferManifest = Schema.Struct({\n threadId: ThreadExport.fields.threadId,\n format: ThreadExport.fields.format,\n tailSequence: ThreadExport.fields.tailSequence,\n snapshot: ThreadExportSnapshot,\n workerSeal: ThreadExport.fields.workerSeal,\n});\n\nconst Position = Schema.Struct({\n manifest: TransferManifest,\n fromSequence: Schema.Int.check(Schema.isGreaterThan(0)),\n section: Schema.Int.check(Schema.isBetween({ minimum: 0, maximum: transferSections.length })),\n consumed: Schema.Natural,\n after: Schema.optionalKey(Schema.String),\n});\n\nconst failure = (message: string, cause?: unknown) =>\n ThreadStoreError.make({\n operation: \"Thread transfer\",\n message,\n ...(cause === undefined ? {} : { cause }),\n });\n\nconst nextSection = (position: typeof Position.Type) => {\n const { after: _, ...retained } = position;\n\n return { ...retained, section: position.section + 1, consumed: 0 };\n};\n\n/** Exact manifest equality replaces a redundant stored snapshot fingerprint. */\nexport const sameTransferManifest = Schema.toEquivalence(TransferManifest);\n\n/** Must run BEFORE a source gate, transaction or routed RPC is acquired. */\nexport const checkExportSource = (threadId: ThreadId) =>\n Effect.flatMap(ImportSourcePhase, (phase) =>\n phase?.writing\n ? Effect.fail(ThreadExportRejected.make({ threadId, reason: \"live-import-source\" }))\n : Effect.void,\n );\n\n/** Exact evidence references outside this canonical page. */\nexport const transferDependencies = (\n records: ReadonlyArray<CanonicalRecordEnvelope>,\n): ReadonlyArray<RecordId> =>\n [...new Set(transferRecordDependencies(records.map((entry) => entry.record)))].sort();\n\nconst factCount = (facts: TransferFacts, section: TransferSection): number =>\n section === \"admissions\"\n ? facts.admissions.length\n : section === \"deliveries\"\n ? facts.deliveries.length\n : facts.commands[section].length;\n\nexport const checkTransferPageBytes = (page: ThreadExport) =>\n Schema.encodeEffect(ThreadExport)(page).pipe(\n Effect.mapError(() => failure(\"Transfer page does not encode its canonical wire\")),\n Effect.flatMap((wire) =>\n utf8ByteLength(canonicalJson(wire)) <= MAX_THREAD_EXPORT_PAGE_BYTES\n ? Effect.void\n : Effect.fail(failure(\"Transfer page exceeds 32 MiB\")),\n ),\n );\n\n/** Stateless pages require application quiescence; no transfer counter is maintained on writes. */\nexport const exportThreadPage = Effect.fnUntraced(function* (input: ThreadExportRequest) {\n const reader = yield* ThreadExporterReader;\n\n const request = yield* Schema.decodeEffect(ThreadExportRequest)(input).pipe(\n Effect.mapError(() => failure(\"Invalid export request\")),\n );\n\n const captured =\n request.cursor === undefined\n ? undefined\n : yield* Schema.decodeEffect(Schema.fromJsonString(Position))(request.cursor).pipe(\n Effect.mapError((cause) => failure(\"Invalid transfer cursor\", cause)),\n );\n\n const manifest = yield* reader.snapshot(request.threadId, captured?.manifest);\n let position = captured ?? { manifest, fromSequence: 1, section: 0, consumed: 0 };\n\n if (!sameTransferManifest(position.manifest, manifest) || manifest.threadId !== request.threadId)\n return yield* ThreadExportRejected.make({\n threadId: request.threadId,\n reason: \"source-changed\",\n });\n if (\n manifest.format !== CURRENT_RECORD_FORMAT ||\n position.fromSequence > manifest.tailSequence + 1\n )\n return yield* failure(\"Unsupported format or invalid canonical transfer position\");\n let canonical: Pick<ThreadExport, \"records\" | \"batches\"> = { records: [], batches: [] };\n\n let facts: TransferFacts = {\n admissions: [],\n commands: { aborts: [], approvals: [], resolutions: [] },\n deliveries: [],\n };\n\n const fromSequence = position.fromSequence;\n\n if (fromSequence <= manifest.tailSequence) {\n canonical = yield* reader.batch(request.threadId, fromSequence);\n if (\n canonical.batches.length !== 1 ||\n canonical.records.length === 0 ||\n canonical.records.length > 256\n )\n return yield* failure(\"A transfer page must contain a complete bounded canonical batch\");\n const batch = canonical.batches[0]!;\n\n for (const [index, entry] of canonical.records.entries())\n if (\n entry.threadId !== request.threadId ||\n entry.sequence !== fromSequence + index ||\n entry.batchId !== batch.batchId\n )\n return yield* failure(\"Canonical batch identity or sequence mismatch\");\n\n position = {\n ...position,\n fromSequence: fromSequence + canonical.records.length,\n };\n } else {\n while (position.section < transferSections.length) {\n const section = transferSections[position.section]!;\n\n if (position.consumed > manifest.snapshot[section])\n return yield* failure(\"Transfer fact cursor exceeds its captured count\");\n if (position.consumed === manifest.snapshot[section]) {\n const probe = yield* reader.facts(request.threadId, section, position.after);\n\n const remaining = factCount(probe.facts, section);\n\n if (remaining !== 0) return yield* failure(\"Native transfer count omits retained facts\");\n position = nextSection(position);\n continue;\n }\n const page = yield* reader.facts(request.threadId, section, position.after);\n\n facts = page.facts;\n\n const count = factCount(facts, section);\n\n if (\n count === 0 ||\n count > 256 ||\n page.after === position.after ||\n position.consumed + count > manifest.snapshot[section]\n )\n return yield* failure(\"Transfer fact page is missing or exceeds its captured count\");\n position = { ...position, consumed: position.consumed + count, after: page.after };\n break;\n }\n }\n while (\n position.section < transferSections.length &&\n position.consumed === manifest.snapshot[transferSections[position.section]!]\n ) {\n const section = transferSections[position.section]!;\n const probe = yield* reader.facts(request.threadId, section, position.after);\n\n const count = factCount(probe.facts, section);\n\n if (count !== 0) return yield* failure(\"Native transfer count omits retained facts\");\n position = nextSection(position);\n }\n\n const more =\n position.fromSequence <= manifest.tailSequence || position.section < transferSections.length;\n\n const cursor = more\n ? yield* Schema.encodeEffect(Schema.fromJsonString(Position))(position).pipe(\n Effect.mapError((cause) => failure(\"Cannot encode transfer cursor\", cause)),\n )\n : undefined;\n\n const page = yield* ThreadExport.makeEffect({\n ...manifest,\n transferFormat: \"effect-agent/thread-transfer@4\",\n fromSequence: Schema.decodeSync(CanonicalSequence)(fromSequence),\n ...canonical,\n ...facts,\n dependencies: transferDependencies(canonical.records),\n ...(cursor === undefined ? {} : { cursor }),\n }).pipe(Effect.mapError(() => failure(\"Transfer page exceeds its schema bounds\")));\n\n yield* checkTransferPageBytes(page);\n\n return page;\n});\n"],"mappings":"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"}
1
+ {"version":3,"file":"ThreadTransfer-3jigUl3g.mjs","names":[],"sources":["../src/durable/internal/thread-transfer-source.ts","../src/durable/ThreadTransfer.ts"],"sourcesContent":["import { Context } from \"effect\";\n\n/** Installed before opening the source pull, so producer fibers observe the same phase. */\nexport const ImportSourcePhase = Context.Reference<{ writing: boolean } | undefined>(\n \"@effect-agent/thread/internal/ImportSourcePhase\",\n { defaultValue: () => undefined },\n);\n","import { Context, Effect, Schema } from \"effect\";\n\nimport type { ThreadId } from \"../core/Identifiers.ts\";\nimport { canonicalJson, utf8ByteLength } from \"./Digest.ts\";\nimport { ImportSourcePhase } from \"./internal/thread-transfer-source.ts\";\nimport { transferRecordDependencies } from \"./internal/transfer-dependencies.ts\";\nimport {\n type RecordId,\n CURRENT_RECORD_FORMAT,\n CanonicalSequence,\n type CanonicalRecordEnvelope,\n} from \"./Records.ts\";\nimport {\n MAX_THREAD_EXPORT_PAGE_BYTES,\n ThreadExport,\n ThreadExportRequest,\n ThreadExportSnapshot,\n ThreadExportRejected,\n type ThreadNotMaterialized,\n ThreadStoreError,\n} from \"./ThreadStore.ts\";\n\nexport const transferSections = [\n \"admissions\",\n \"aborts\",\n \"approvals\",\n \"resolutions\",\n \"deliveries\",\n] as const;\n\nexport type TransferSection = (typeof transferSections)[number];\n\nexport type TransferFacts = Pick<ThreadExport, \"admissions\" | \"commands\" | \"deliveries\">;\n\nexport type TransferManifest = Pick<\n ThreadExport,\n \"threadId\" | \"format\" | \"tailSequence\" | \"snapshot\" | \"workerSeal\"\n>;\n\n/** Reads share the adapter's single page transaction. Batch reads hydrate archives. */\nexport class ThreadExporterReader extends Context.Service<\n ThreadExporterReader,\n {\n readonly snapshot: (\n threadId: ThreadId,\n captured?: TransferManifest,\n ) => Effect.Effect<\n TransferManifest,\n ThreadStoreError | ThreadNotMaterialized | ThreadExportRejected\n >;\n readonly batch: (\n threadId: ThreadId,\n fromSequence: number,\n ) => Effect.Effect<\n Pick<ThreadExport, \"records\" | \"batches\">,\n ThreadStoreError | ThreadNotMaterialized\n >;\n /** A keyset read of at most 256 facts. Keys stay bounded independently of fact identities. */\n readonly facts: (\n threadId: ThreadId,\n section: TransferSection,\n after: string | undefined,\n ) => Effect.Effect<\n {\n readonly facts: TransferFacts;\n readonly after: string;\n },\n ThreadStoreError\n >;\n }\n>()(\"@effect-agent/thread/ThreadExporterReader\") {}\n\nexport const TransferManifest = Schema.Struct({\n threadId: ThreadExport.fields.threadId,\n format: ThreadExport.fields.format,\n tailSequence: ThreadExport.fields.tailSequence,\n snapshot: ThreadExportSnapshot,\n workerSeal: ThreadExport.fields.workerSeal,\n});\n\nconst Position = Schema.Struct({\n manifest: TransferManifest,\n fromSequence: Schema.Int.check(Schema.isGreaterThan(0)),\n section: Schema.Int.check(Schema.isBetween({ minimum: 0, maximum: transferSections.length })),\n consumed: Schema.Natural,\n after: Schema.optionalKey(Schema.String),\n});\n\nconst failure = (message: string, cause?: unknown) =>\n ThreadStoreError.make({\n operation: \"Thread transfer\",\n message,\n ...(cause === undefined ? {} : { cause }),\n });\n\nconst nextSection = (position: typeof Position.Type) => {\n const { after: _, ...retained } = position;\n\n return { ...retained, section: position.section + 1, consumed: 0 };\n};\n\n/** Exact manifest equality replaces a redundant stored snapshot fingerprint. */\nexport const sameTransferManifest = Schema.toEquivalence(TransferManifest);\n\n/** Must run BEFORE a source gate, transaction or routed RPC is acquired. */\nexport const checkExportSource = (threadId: ThreadId) =>\n Effect.flatMap(ImportSourcePhase, (phase) =>\n phase?.writing\n ? Effect.fail(ThreadExportRejected.make({ threadId, reason: \"live-import-source\" }))\n : Effect.void,\n );\n\n/** Exact evidence references outside this canonical page. */\nexport const transferDependencies = (\n records: ReadonlyArray<CanonicalRecordEnvelope>,\n): ReadonlyArray<RecordId> =>\n [...new Set(transferRecordDependencies(records.map((entry) => entry.record)))].sort();\n\nconst factCount = (facts: TransferFacts, section: TransferSection): number =>\n section === \"admissions\"\n ? facts.admissions.length\n : section === \"deliveries\"\n ? facts.deliveries.length\n : facts.commands[section].length;\n\nexport const checkTransferPageBytes = (page: ThreadExport) =>\n Schema.encodeEffect(ThreadExport)(page).pipe(\n Effect.mapError(() => failure(\"Transfer page does not encode its canonical wire\")),\n Effect.flatMap((wire) =>\n utf8ByteLength(canonicalJson(wire)) <= MAX_THREAD_EXPORT_PAGE_BYTES\n ? Effect.void\n : Effect.fail(failure(\"Transfer page exceeds 32 MiB\")),\n ),\n );\n\n/** Stateless pages require application quiescence; no transfer counter is maintained on writes. */\nexport const exportThreadPage = Effect.fnUntraced(function* (input: ThreadExportRequest) {\n const reader = yield* ThreadExporterReader;\n\n const request = yield* Schema.decodeEffect(ThreadExportRequest)(input).pipe(\n Effect.mapError(() => failure(\"Invalid export request\")),\n );\n\n const captured =\n request.cursor === undefined\n ? undefined\n : yield* Schema.decodeEffect(Schema.fromJsonString(Position))(request.cursor).pipe(\n Effect.mapError((cause) => failure(\"Invalid transfer cursor\", cause)),\n );\n\n const manifest = yield* reader.snapshot(request.threadId, captured?.manifest);\n let position = captured ?? { manifest, fromSequence: 1, section: 0, consumed: 0 };\n\n if (!sameTransferManifest(position.manifest, manifest) || manifest.threadId !== request.threadId)\n return yield* ThreadExportRejected.make({\n threadId: request.threadId,\n reason: \"source-changed\",\n });\n if (\n manifest.format !== CURRENT_RECORD_FORMAT ||\n position.fromSequence > manifest.tailSequence + 1\n )\n return yield* failure(\"Unsupported format or invalid canonical transfer position\");\n let canonical: Pick<ThreadExport, \"records\" | \"batches\"> = { records: [], batches: [] };\n\n let facts: TransferFacts = {\n admissions: [],\n commands: { aborts: [], approvals: [], resolutions: [] },\n deliveries: [],\n };\n\n const fromSequence = position.fromSequence;\n\n if (fromSequence <= manifest.tailSequence) {\n canonical = yield* reader.batch(request.threadId, fromSequence);\n if (\n canonical.batches.length !== 1 ||\n canonical.records.length === 0 ||\n canonical.records.length > 256\n )\n return yield* failure(\"A transfer page must contain a complete bounded canonical batch\");\n const batch = canonical.batches[0]!;\n\n for (const [index, entry] of canonical.records.entries())\n if (\n entry.threadId !== request.threadId ||\n entry.sequence !== fromSequence + index ||\n entry.batchId !== batch.batchId\n )\n return yield* failure(\"Canonical batch identity or sequence mismatch\");\n\n position = {\n ...position,\n fromSequence: fromSequence + canonical.records.length,\n };\n } else {\n while (position.section < transferSections.length) {\n const section = transferSections[position.section]!;\n\n if (position.consumed > manifest.snapshot[section])\n return yield* failure(\"Transfer fact cursor exceeds its captured count\");\n if (position.consumed === manifest.snapshot[section]) {\n const probe = yield* reader.facts(request.threadId, section, position.after);\n\n const remaining = factCount(probe.facts, section);\n\n if (remaining !== 0) return yield* failure(\"Native transfer count omits retained facts\");\n position = nextSection(position);\n continue;\n }\n const page = yield* reader.facts(request.threadId, section, position.after);\n\n facts = page.facts;\n\n const count = factCount(facts, section);\n\n if (\n count === 0 ||\n count > 256 ||\n page.after === position.after ||\n position.consumed + count > manifest.snapshot[section]\n )\n return yield* failure(\"Transfer fact page is missing or exceeds its captured count\");\n position = { ...position, consumed: position.consumed + count, after: page.after };\n break;\n }\n }\n while (\n position.section < transferSections.length &&\n position.consumed === manifest.snapshot[transferSections[position.section]!]\n ) {\n const section = transferSections[position.section]!;\n const probe = yield* reader.facts(request.threadId, section, position.after);\n\n const count = factCount(probe.facts, section);\n\n if (count !== 0) return yield* failure(\"Native transfer count omits retained facts\");\n position = nextSection(position);\n }\n\n const more =\n position.fromSequence <= manifest.tailSequence || position.section < transferSections.length;\n\n const cursor = more\n ? yield* Schema.encodeEffect(Schema.fromJsonString(Position))(position).pipe(\n Effect.mapError((cause) => failure(\"Cannot encode transfer cursor\", cause)),\n )\n : undefined;\n\n const page = yield* ThreadExport.makeEffect({\n ...manifest,\n transferFormat: \"effect-agent/thread-transfer@4\",\n fromSequence: Schema.decodeSync(CanonicalSequence)(fromSequence),\n ...canonical,\n ...facts,\n dependencies: transferDependencies(canonical.records),\n ...(cursor === undefined ? {} : { cursor }),\n }).pipe(Effect.mapError(() => failure(\"Transfer page exceeds its schema bounds\")));\n\n yield* checkTransferPageBytes(page);\n\n return page;\n});\n"],"mappings":";;;;;;;;AAGA,MAAa,oBAAoB,QAAQ,UACvC,mDACA,EAAE,oBAAoB,KAAA,EAAU,CAClC;;;;;;;;;;;;;ACgBA,MAAa,mBAAmB;CAC9B;CACA;CACA;CACA;CACA;AACF;;AAYA,IAAa,uBAAb,cAA0C,QAAQ,QA8BhD,CAAC,CAAC,2CAA2C,CAAC,CAAC,CAAC;AAElD,MAAa,mBAAmB,OAAO,OAAO;CAC5C,UAAU,aAAa,OAAO;CAC9B,QAAQ,aAAa,OAAO;CAC5B,cAAc,aAAa,OAAO;CAClC,UAAU;CACV,YAAY,aAAa,OAAO;AAClC,CAAC;AAED,MAAM,WAAW,OAAO,OAAO;CAC7B,UAAU;CACV,cAAc,OAAO,IAAI,MAAM,OAAO,cAAc,CAAC,CAAC;CACtD,SAAS,OAAO,IAAI,MAAM,OAAO,UAAU;EAAE,SAAS;EAAG,SAAS,iBAAiB;CAAO,CAAC,CAAC;CAC5F,UAAU,OAAO;CACjB,OAAO,OAAO,YAAY,OAAO,MAAM;AACzC,CAAC;AAED,MAAM,WAAW,SAAiB,UAChC,iBAAiB,KAAK;CACpB,WAAW;CACX;CACA,GAAI,UAAU,KAAA,IAAY,CAAC,IAAI,EAAE,MAAM;AACzC,CAAC;AAEH,MAAM,eAAe,aAAmC;CACtD,MAAM,EAAE,OAAO,GAAG,GAAG,aAAa;CAElC,OAAO;EAAE,GAAG;EAAU,SAAS,SAAS,UAAU;EAAG,UAAU;CAAE;AACnE;;AAGA,MAAa,uBAAuB,OAAO,cAAc,gBAAgB;;AAGzE,MAAa,qBAAqB,aAChC,OAAO,QAAQ,oBAAoB,UACjC,OAAO,UACH,OAAO,KAAK,qBAAqB,KAAK;CAAE;CAAU,QAAQ;AAAqB,CAAC,CAAC,IACjF,OAAO,IACb;;AAGF,MAAa,wBACX,YAEA,CAAC,GAAG,IAAI,IAAI,2BAA2B,QAAQ,KAAK,UAAU,MAAM,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK;AAEtF,MAAM,aAAa,OAAsB,YACvC,YAAY,eACR,MAAM,WAAW,SACjB,YAAY,eACV,MAAM,WAAW,SACjB,MAAM,SAAS,QAAQ,CAAC;AAEhC,MAAa,0BAA0B,SACrC,OAAO,aAAa,YAAY,CAAC,CAAC,IAAI,CAAC,CAAC,KACtC,OAAO,eAAe,QAAQ,kDAAkD,CAAC,GACjF,OAAO,SAAS,SACd,eAAe,cAAc,IAAI,CAAC,KAAA,WAC9B,OAAO,OACP,OAAO,KAAK,QAAQ,8BAA8B,CAAC,CACzD,CACF;;AAGF,MAAa,mBAAmB,OAAO,WAAW,WAAW,OAA4B;CACvF,MAAM,SAAS,OAAO;CAEtB,MAAM,UAAU,OAAO,OAAO,aAAa,mBAAmB,CAAC,CAAC,KAAK,CAAC,CAAC,KACrE,OAAO,eAAe,QAAQ,wBAAwB,CAAC,CACzD;CAEA,MAAM,WACJ,QAAQ,WAAW,KAAA,IACf,KAAA,IACA,OAAO,OAAO,aAAa,OAAO,eAAe,QAAQ,CAAC,CAAC,CAAC,QAAQ,MAAM,CAAC,CAAC,KAC1E,OAAO,UAAU,UAAU,QAAQ,2BAA2B,KAAK,CAAC,CACtE;CAEN,MAAM,WAAW,OAAO,OAAO,SAAS,QAAQ,UAAU,UAAU,QAAQ;CAC5E,IAAI,WAAW,YAAY;EAAE;EAAU,cAAc;EAAG,SAAS;EAAG,UAAU;CAAE;CAEhF,IAAI,CAAC,qBAAqB,SAAS,UAAU,QAAQ,KAAK,SAAS,aAAa,QAAQ,UACtF,OAAO,OAAO,qBAAqB,KAAK;EACtC,UAAU,QAAQ;EAClB,QAAQ;CACV,CAAC;CACH,IACE,SAAS,WAAA,2BACT,SAAS,eAAe,SAAS,eAAe,GAEhD,OAAO,OAAO,QAAQ,2DAA2D;CACnF,IAAI,YAAuD;EAAE,SAAS,CAAC;EAAG,SAAS,CAAC;CAAE;CAEtF,IAAI,QAAuB;EACzB,YAAY,CAAC;EACb,UAAU;GAAE,QAAQ,CAAC;GAAG,WAAW,CAAC;GAAG,aAAa,CAAC;EAAE;EACvD,YAAY,CAAC;CACf;CAEA,MAAM,eAAe,SAAS;CAE9B,IAAI,gBAAgB,SAAS,cAAc;EACzC,YAAY,OAAO,OAAO,MAAM,QAAQ,UAAU,YAAY;EAC9D,IACE,UAAU,QAAQ,WAAW,KAC7B,UAAU,QAAQ,WAAW,KAC7B,UAAU,QAAQ,SAAS,KAE3B,OAAO,OAAO,QAAQ,iEAAiE;EACzF,MAAM,QAAQ,UAAU,QAAQ;EAEhC,KAAK,MAAM,CAAC,OAAO,UAAU,UAAU,QAAQ,QAAQ,GACrD,IACE,MAAM,aAAa,QAAQ,YAC3B,MAAM,aAAa,eAAe,SAClC,MAAM,YAAY,MAAM,SAExB,OAAO,OAAO,QAAQ,+CAA+C;EAEzE,WAAW;GACT,GAAG;GACH,cAAc,eAAe,UAAU,QAAQ;EACjD;CACF,OACE,OAAO,SAAS,UAAU,iBAAiB,QAAQ;EACjD,MAAM,UAAU,iBAAiB,SAAS;EAE1C,IAAI,SAAS,WAAW,SAAS,SAAS,UACxC,OAAO,OAAO,QAAQ,iDAAiD;EACzE,IAAI,SAAS,aAAa,SAAS,SAAS,UAAU;GACpD,MAAM,QAAQ,OAAO,OAAO,MAAM,QAAQ,UAAU,SAAS,SAAS,KAAK;GAI3E,IAFkB,UAAU,MAAM,OAAO,OAE7B,MAAM,GAAG,OAAO,OAAO,QAAQ,4CAA4C;GACvF,WAAW,YAAY,QAAQ;GAC/B;EACF;EACA,MAAM,OAAO,OAAO,OAAO,MAAM,QAAQ,UAAU,SAAS,SAAS,KAAK;EAE1E,QAAQ,KAAK;EAEb,MAAM,QAAQ,UAAU,OAAO,OAAO;EAEtC,IACE,UAAU,KACV,QAAQ,OACR,KAAK,UAAU,SAAS,SACxB,SAAS,WAAW,QAAQ,SAAS,SAAS,UAE9C,OAAO,OAAO,QAAQ,6DAA6D;EACrF,WAAW;GAAE,GAAG;GAAU,UAAU,SAAS,WAAW;GAAO,OAAO,KAAK;EAAM;EACjF;CACF;CAEF,OACE,SAAS,UAAU,iBAAiB,UACpC,SAAS,aAAa,SAAS,SAAS,iBAAiB,SAAS,WAClE;EACA,MAAM,UAAU,iBAAiB,SAAS;EAC1C,MAAM,QAAQ,OAAO,OAAO,MAAM,QAAQ,UAAU,SAAS,SAAS,KAAK;EAI3E,IAFc,UAAU,MAAM,OAAO,OAE7B,MAAM,GAAG,OAAO,OAAO,QAAQ,4CAA4C;EACnF,WAAW,YAAY,QAAQ;CACjC;CAKA,MAAM,SAFJ,SAAS,gBAAgB,SAAS,gBAAgB,SAAS,UAAU,iBAAiB,SAGpF,OAAO,OAAO,aAAa,OAAO,eAAe,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,KACpE,OAAO,UAAU,UAAU,QAAQ,iCAAiC,KAAK,CAAC,CAC5E,IACA,KAAA;CAEJ,MAAM,OAAO,OAAO,aAAa,WAAW;EAC1C,GAAG;EACH,gBAAgB;EAChB,cAAc,OAAO,WAAW,iBAAiB,CAAC,CAAC,YAAY;EAC/D,GAAG;EACH,GAAG;EACH,cAAc,qBAAqB,UAAU,OAAO;EACpD,GAAI,WAAW,KAAA,IAAY,CAAC,IAAI,EAAE,OAAO;CAC3C,CAAC,CAAC,CAAC,KAAK,OAAO,eAAe,QAAQ,yCAAyC,CAAC,CAAC;CAEjF,OAAO,uBAAuB,IAAI;CAElC,OAAO;AACT,CAAC"}
@@ -2,9 +2,9 @@ import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.mjs";
2
2
  import { c as WorkerError } from "./Worker-DZjdMjZn.mjs";
3
3
  import { It as WorkerOrigin, Lt as WorkerOriginRecorded, W as ProducerId, X as RecordEnvelope, Z as RecordId, c as CanonicalBatch, i as BatchId, jt as WorkerAdmission, yt as ThreadCreated } from "./Records-BiuJDWNe.mjs";
4
4
  import { AdmissionConflict, AdmissionPolicyError, AdmissionRequest, LedgerError, MarkReadyRequest, SubmissionLedger } from "./durable/SubmissionLedger.mjs";
5
- import { o as definitionDigestsEqual } from "./agent-registration-ByMZ_cK5.mjs";
6
- import { Y as workerOriginRecordId } from "./RunJournal-kfKVxJj7.mjs";
7
- import { $ as ThreadTailRequest, F as ThreadIdentityRequest, I as ThreadMaterialization, J as ThreadStore, L as ThreadNotMaterialized, X as ThreadStoreError, n as AppendRequest, t as AppendConflict } from "./ThreadStore-CEekRa80.mjs";
5
+ import { o as definitionDigestsEqual } from "./agent-registration-DRbyhAu-.mjs";
6
+ import { Y as workerOriginRecordId } from "./RunJournal-CNZqA3Ge.mjs";
7
+ import { $ as ThreadTailRequest, F as ThreadIdentityRequest, I as ThreadMaterialization, J as ThreadStore, L as ThreadNotMaterialized, X as ThreadStoreError, n as AppendRequest, t as AppendConflict } from "./ThreadStore-59uDGXul.mjs";
8
8
  import { DurableRuntimeFailpoint, DurableRuntimeFailpointError } from "./durable/DurableFailpoint.mjs";
9
9
  import { WakeScheduler } from "./durable/WakeScheduler.mjs";
10
10
  import { Context, DateTime, Effect, Schema } from "effect";
@@ -158,4 +158,4 @@ const WorkerAdmissionPort = Context.Reference("@effect-agent/thread/WorkerAdmiss
158
158
  //#endregion
159
159
  export { admitWorker as a, threadCreatedBatchId as c, WorkerAdmission_exports as i, threadCreatedRecordId as l, WorkerAdmissionPort as n, ensureThreadCreated as o, WorkerAdmissionRequest as r, ensureWorkerOrigin as s, WorkerAdmissionFailure as t };
160
160
 
161
- //# sourceMappingURL=WorkerAdmission-DFVbbVh2.mjs.map
161
+ //# sourceMappingURL=WorkerAdmission-DDYJdOsU.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"WorkerAdmission-DFVbbVh2.mjs","names":[],"sources":["../src/durable/internal/thread-initialization.ts","../src/durable/WorkerAdmission.ts"],"sourcesContent":["import { DateTime, Effect, Schema } from \"effect\";\n\nimport type { AgentId, ThreadId } from \"../../core/Identifiers.ts\";\nimport { WorkerError } from \"../../core/Worker.ts\";\nimport { DurableRuntimeFailpoint } from \"../DurableFailpoint.ts\";\nimport {\n BatchId,\n CanonicalBatch,\n RecordEnvelope,\n RecordId,\n ThreadCreated,\n WorkerOrigin,\n WorkerOriginRecorded,\n type DefinitionDigests,\n type DeploymentId,\n type ProducerId,\n} from \"../Records.ts\";\nimport { workerOriginRecordId } from \"../RunJournal.ts\";\nimport type { OwnershipLost } from \"../SubmissionLedger.ts\";\nimport type { AppendConflict, ThreadNotMaterialized, ThreadStoreError } from \"../ThreadStore.ts\";\nimport {\n AppendRequest,\n ThreadIdentityRequest,\n ThreadTailRequest,\n ThreadStore,\n} from \"../ThreadStore.ts\";\nimport { WakeScheduler } from \"../WakeScheduler.ts\";\nimport { definitionDigestsEqual } from \"./agent-registration.ts\";\n\ninterface InitializationConfig {\n readonly producerId: ProducerId;\n readonly deploymentId: DeploymentId;\n}\n\n/** Stable identities retained across admission retries and recovery. */\nexport const threadCreatedBatchId = (threadId: ThreadId): BatchId =>\n Schema.decodeSync(BatchId)(`thread-created:${threadId}`);\n\nexport const threadCreatedRecordId = (threadId: ThreadId): RecordId =>\n Schema.decodeSync(RecordId)(`thread-created:${threadId}`);\n\n/**\n * Coordinator invariant: every Thread's first canonical record is `ThreadCreated`,\n * so `tailSequence >= 1` is the deterministic already-created check. Concurrent admissions\n * re-read this invariant after a tail conflict before considering initialization complete.\n */\nexport const ensureThreadCreated = Effect.fnUntraced(\n function* (\n config: InitializationConfig,\n threadId: ThreadId,\n agentId: AgentId,\n definitions: DefinitionDigests,\n ): Effect.fn.Return<\n void,\n ThreadStoreError | ThreadNotMaterialized | AppendConflict | OwnershipLost,\n ThreadStore | WakeScheduler\n > {\n const store = yield* ThreadStore;\n const wake = yield* WakeScheduler;\n const tail = yield* store.inspectTail(ThreadTailRequest.make({ threadId }));\n\n if (tail.tailSequence > 0) return;\n\n const record = yield* Effect.map(DateTime.now, (createdAt) =>\n RecordEnvelope.make({\n recordId: threadCreatedRecordId(threadId),\n family: \"thread\",\n schemaVersion: 1,\n createdAt,\n deploymentId: config.deploymentId,\n payload: ThreadCreated.make({ agentId, definitions }),\n }),\n );\n\n yield* store\n .append(\n AppendRequest.make({\n threadId,\n batch: CanonicalBatch.make({\n batchId: threadCreatedBatchId(threadId),\n producerId: config.producerId,\n records: [record],\n }),\n expectedTailSequence: tail.tailSequence,\n }),\n )\n .pipe(\n Effect.catchTag(\"AppendConflict\", (error) =>\n store\n .inspectTail(ThreadTailRequest.make({ threadId }))\n .pipe(\n Effect.flatMap((current) =>\n current.tailSequence > 0 ? Effect.void : Effect.fail(error),\n ),\n ),\n ),\n Effect.andThen(wake.notify(threadId)),\n Effect.asVoid,\n );\n },\n (effect) =>\n effect.pipe(\n Effect.retry({\n times: 7,\n while: (error) => error._tag === \"AppendConflict\",\n }),\n ),\n);\n\nconst sameOrigin = Schema.toEquivalence(WorkerOrigin);\n\nexport const ensureWorkerOrigin = Effect.fnUntraced(\n function* (config: InitializationConfig, origin: WorkerOrigin) {\n const store = yield* ThreadStore;\n const failpoint = yield* DurableRuntimeFailpoint;\n\n for (let attempt = 0; attempt < 16; attempt++) {\n const current = yield* store.readIdentity(\n ThreadIdentityRequest.make({ threadId: origin.worker.threadId }),\n );\n\n const existing = current.records.find(\n ({ record }) => record.payload._tag === \"WorkerOriginRecorded\",\n )?.record.payload;\n\n if (existing?._tag === \"WorkerOriginRecorded\") {\n if (!sameOrigin(existing.origin, origin))\n return yield* WorkerError.make({ operation: \"start\", reason: \"worker-mismatch\" });\n\n return;\n }\n const first = current.records[0]?.record.payload;\n\n if (\n first?._tag !== \"ThreadCreated\" ||\n first.agentId !== origin.worker.targetAgentId ||\n !definitionDigestsEqual(first.definitions, origin.targetDigests) ||\n current.records.some(({ record }) => record.payload._tag === \"SubagentLineageRecorded\")\n )\n return yield* WorkerError.make({ operation: \"start\", reason: \"worker-mismatch\" });\n const id = workerOriginRecordId(origin.worker.threadId);\n\n yield* failpoint.hit(\"worker:before-origin-append\");\n\n const appended = yield* store\n .append(\n AppendRequest.make({\n threadId: origin.worker.threadId,\n expectedTailSequence: current.tailSequence,\n\n batch: CanonicalBatch.make({\n batchId: Schema.decodeSync(BatchId)(id),\n producerId: config.producerId,\n records: [\n RecordEnvelope.make({\n recordId: id,\n family: \"thread\",\n schemaVersion: 1,\n createdAt: DateTime.makeUnsafe(origin.createdAtMillis),\n deploymentId: config.deploymentId,\n payload: WorkerOriginRecorded.make({ origin }),\n }),\n ],\n }),\n }),\n )\n .pipe(\n Effect.as(true),\n Effect.catchTag(\"AppendConflict\", () => Effect.succeed(false)),\n );\n\n if (appended) {\n yield* failpoint.hit(\"worker:after-origin-append\");\n\n return;\n }\n }\n\n return yield* WorkerError.make({ operation: \"start\", reason: \"storage\" });\n },\n Effect.mapError((cause) =>\n cause._tag === \"WorkerError\"\n ? cause\n : WorkerError.make({ operation: \"start\", reason: \"storage\", cause }),\n ),\n);\n","import { Context, Effect, Schema } from \"effect\";\n\nimport { DurableRuntimeFailpoint, DurableRuntimeFailpointError } from \"./DurableFailpoint.ts\";\nimport { ensureThreadCreated, ensureWorkerOrigin } from \"./internal/thread-initialization.ts\";\nimport { ProducerId, WorkerAdmission } from \"./Records.ts\";\nimport {\n AdmissionConflict,\n AdmissionPolicyError,\n AdmissionRequest,\n LedgerError,\n MarkReadyRequest,\n SubmissionLedger,\n} from \"./SubmissionLedger.ts\";\nimport {\n AppendConflict,\n ThreadMaterialization,\n ThreadNotMaterialized,\n ThreadStore,\n ThreadStoreError,\n} from \"./ThreadStore.ts\";\nimport { WakeScheduler } from \"./WakeScheduler.ts\";\n\n/**\n * Storage admission after source authorization, input validation and capacity reservation.\n * This is an internal host port, not an authorization entrypoint. Hosts route the whole\n * operation to the destination owner and enroll recovery before executing it.\n */\nexport class WorkerAdmissionRequest extends Schema.Class<WorkerAdmissionRequest>(\n \"@effect-agent/thread/WorkerAdmissionRequest\",\n)({\n ...AdmissionRequest.fields,\n workerAdmission: WorkerAdmission,\n producerId: ProducerId,\n}) {}\n\nexport const WorkerAdmissionFailure = Schema.Union([\n AdmissionConflict,\n AdmissionPolicyError,\n LedgerError,\n ThreadStoreError,\n ThreadNotMaterialized,\n AppendConflict,\n DurableRuntimeFailpointError,\n]);\n\n/** Local implementation shared by every host; retries finish the same admitted row. */\nexport const admitWorker = Effect.fnUntraced(function* (request: WorkerAdmissionRequest) {\n const origin = request.workerAdmission.origin;\n\n if (\n origin.worker.threadId !== request.threadId ||\n origin.worker.targetAgentId !== request.agentId ||\n request.parentLinkage !== undefined\n )\n return yield* LedgerError.make({\n operation: \"admit worker\",\n message: \"Worker admission does not belong to the destination Thread\",\n });\n\n const ledger = yield* SubmissionLedger;\n const store = yield* ThreadStore;\n const wake = yield* WakeScheduler;\n const failpoint = yield* DurableRuntimeFailpoint;\n const admitted = yield* ledger.admit(AdmissionRequest.make(request));\n\n yield* failpoint.hit(\"submit:after-admit\");\n if (admitted.replayed && admitted.state !== \"admitted\") return admitted;\n\n yield* store.materialize(\n ThreadMaterialization.make({\n threadId: request.threadId,\n }),\n );\n\n const config = {\n producerId: request.producerId,\n deploymentId: request.deploymentId,\n };\n\n yield* ensureThreadCreated(config, request.threadId, request.agentId, request.agentDigests);\n yield* ensureWorkerOrigin(config, origin).pipe(\n Effect.mapError((cause) =>\n LedgerError.make({ operation: \"worker-origin\", message: cause.reason, cause }),\n ),\n );\n yield* failpoint.hit(\"submit:after-materialize\");\n yield* ledger.markReady(MarkReadyRequest.make({ submissionId: admitted.submissionId }));\n yield* wake.notify(request.threadId);\n\n return admitted;\n});\n\n/** Placement adapter for the composite operation; local hosts use the same implementation. */\nexport const WorkerAdmissionPort = Context.Reference<{ readonly admit: typeof admitWorker }>(\n \"@effect-agent/thread/WorkerAdmissionPort\",\n { defaultValue: () => ({ admit: admitWorker }) },\n);\n"],"mappings":"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"}
1
+ {"version":3,"file":"WorkerAdmission-DDYJdOsU.mjs","names":[],"sources":["../src/durable/internal/thread-initialization.ts","../src/durable/WorkerAdmission.ts"],"sourcesContent":["import { DateTime, Effect, Schema } from \"effect\";\n\nimport type { AgentId, ThreadId } from \"../../core/Identifiers.ts\";\nimport { WorkerError } from \"../../core/Worker.ts\";\nimport { DurableRuntimeFailpoint } from \"../DurableFailpoint.ts\";\nimport {\n BatchId,\n CanonicalBatch,\n RecordEnvelope,\n RecordId,\n ThreadCreated,\n WorkerOrigin,\n WorkerOriginRecorded,\n type DefinitionDigests,\n type DeploymentId,\n type ProducerId,\n} from \"../Records.ts\";\nimport { workerOriginRecordId } from \"../RunJournal.ts\";\nimport type { OwnershipLost } from \"../SubmissionLedger.ts\";\nimport type { AppendConflict, ThreadNotMaterialized, ThreadStoreError } from \"../ThreadStore.ts\";\nimport {\n AppendRequest,\n ThreadIdentityRequest,\n ThreadTailRequest,\n ThreadStore,\n} from \"../ThreadStore.ts\";\nimport { WakeScheduler } from \"../WakeScheduler.ts\";\nimport { definitionDigestsEqual } from \"./agent-registration.ts\";\n\ninterface InitializationConfig {\n readonly producerId: ProducerId;\n readonly deploymentId: DeploymentId;\n}\n\n/** Stable identities retained across admission retries and recovery. */\nexport const threadCreatedBatchId = (threadId: ThreadId): BatchId =>\n Schema.decodeSync(BatchId)(`thread-created:${threadId}`);\n\nexport const threadCreatedRecordId = (threadId: ThreadId): RecordId =>\n Schema.decodeSync(RecordId)(`thread-created:${threadId}`);\n\n/**\n * Coordinator invariant: every Thread's first canonical record is `ThreadCreated`,\n * so `tailSequence >= 1` is the deterministic already-created check. Concurrent admissions\n * re-read this invariant after a tail conflict before considering initialization complete.\n */\nexport const ensureThreadCreated = Effect.fnUntraced(\n function* (\n config: InitializationConfig,\n threadId: ThreadId,\n agentId: AgentId,\n definitions: DefinitionDigests,\n ): Effect.fn.Return<\n void,\n ThreadStoreError | ThreadNotMaterialized | AppendConflict | OwnershipLost,\n ThreadStore | WakeScheduler\n > {\n const store = yield* ThreadStore;\n const wake = yield* WakeScheduler;\n const tail = yield* store.inspectTail(ThreadTailRequest.make({ threadId }));\n\n if (tail.tailSequence > 0) return;\n\n const record = yield* Effect.map(DateTime.now, (createdAt) =>\n RecordEnvelope.make({\n recordId: threadCreatedRecordId(threadId),\n family: \"thread\",\n schemaVersion: 1,\n createdAt,\n deploymentId: config.deploymentId,\n payload: ThreadCreated.make({ agentId, definitions }),\n }),\n );\n\n yield* store\n .append(\n AppendRequest.make({\n threadId,\n batch: CanonicalBatch.make({\n batchId: threadCreatedBatchId(threadId),\n producerId: config.producerId,\n records: [record],\n }),\n expectedTailSequence: tail.tailSequence,\n }),\n )\n .pipe(\n Effect.catchTag(\"AppendConflict\", (error) =>\n store\n .inspectTail(ThreadTailRequest.make({ threadId }))\n .pipe(\n Effect.flatMap((current) =>\n current.tailSequence > 0 ? Effect.void : Effect.fail(error),\n ),\n ),\n ),\n Effect.andThen(wake.notify(threadId)),\n Effect.asVoid,\n );\n },\n (effect) =>\n effect.pipe(\n Effect.retry({\n times: 7,\n while: (error) => error._tag === \"AppendConflict\",\n }),\n ),\n);\n\nconst sameOrigin = Schema.toEquivalence(WorkerOrigin);\n\nexport const ensureWorkerOrigin = Effect.fnUntraced(\n function* (config: InitializationConfig, origin: WorkerOrigin) {\n const store = yield* ThreadStore;\n const failpoint = yield* DurableRuntimeFailpoint;\n\n for (let attempt = 0; attempt < 16; attempt++) {\n const current = yield* store.readIdentity(\n ThreadIdentityRequest.make({ threadId: origin.worker.threadId }),\n );\n\n const existing = current.records.find(\n ({ record }) => record.payload._tag === \"WorkerOriginRecorded\",\n )?.record.payload;\n\n if (existing?._tag === \"WorkerOriginRecorded\") {\n if (!sameOrigin(existing.origin, origin))\n return yield* WorkerError.make({ operation: \"start\", reason: \"worker-mismatch\" });\n\n return;\n }\n const first = current.records[0]?.record.payload;\n\n if (\n first?._tag !== \"ThreadCreated\" ||\n first.agentId !== origin.worker.targetAgentId ||\n !definitionDigestsEqual(first.definitions, origin.targetDigests) ||\n current.records.some(({ record }) => record.payload._tag === \"SubagentLineageRecorded\")\n )\n return yield* WorkerError.make({ operation: \"start\", reason: \"worker-mismatch\" });\n const id = workerOriginRecordId(origin.worker.threadId);\n\n yield* failpoint.hit(\"worker:before-origin-append\");\n\n const appended = yield* store\n .append(\n AppendRequest.make({\n threadId: origin.worker.threadId,\n expectedTailSequence: current.tailSequence,\n\n batch: CanonicalBatch.make({\n batchId: Schema.decodeSync(BatchId)(id),\n producerId: config.producerId,\n records: [\n RecordEnvelope.make({\n recordId: id,\n family: \"thread\",\n schemaVersion: 1,\n createdAt: DateTime.makeUnsafe(origin.createdAtMillis),\n deploymentId: config.deploymentId,\n payload: WorkerOriginRecorded.make({ origin }),\n }),\n ],\n }),\n }),\n )\n .pipe(\n Effect.as(true),\n Effect.catchTag(\"AppendConflict\", () => Effect.succeed(false)),\n );\n\n if (appended) {\n yield* failpoint.hit(\"worker:after-origin-append\");\n\n return;\n }\n }\n\n return yield* WorkerError.make({ operation: \"start\", reason: \"storage\" });\n },\n Effect.mapError((cause) =>\n cause._tag === \"WorkerError\"\n ? cause\n : WorkerError.make({ operation: \"start\", reason: \"storage\", cause }),\n ),\n);\n","import { Context, Effect, Schema } from \"effect\";\n\nimport { DurableRuntimeFailpoint, DurableRuntimeFailpointError } from \"./DurableFailpoint.ts\";\nimport { ensureThreadCreated, ensureWorkerOrigin } from \"./internal/thread-initialization.ts\";\nimport { ProducerId, WorkerAdmission } from \"./Records.ts\";\nimport {\n AdmissionConflict,\n AdmissionPolicyError,\n AdmissionRequest,\n LedgerError,\n MarkReadyRequest,\n SubmissionLedger,\n} from \"./SubmissionLedger.ts\";\nimport {\n AppendConflict,\n ThreadMaterialization,\n ThreadNotMaterialized,\n ThreadStore,\n ThreadStoreError,\n} from \"./ThreadStore.ts\";\nimport { WakeScheduler } from \"./WakeScheduler.ts\";\n\n/**\n * Storage admission after source authorization, input validation and capacity reservation.\n * This is an internal host port, not an authorization entrypoint. Hosts route the whole\n * operation to the destination owner and enroll recovery before executing it.\n */\nexport class WorkerAdmissionRequest extends Schema.Class<WorkerAdmissionRequest>(\n \"@effect-agent/thread/WorkerAdmissionRequest\",\n)({\n ...AdmissionRequest.fields,\n workerAdmission: WorkerAdmission,\n producerId: ProducerId,\n}) {}\n\nexport const WorkerAdmissionFailure = Schema.Union([\n AdmissionConflict,\n AdmissionPolicyError,\n LedgerError,\n ThreadStoreError,\n ThreadNotMaterialized,\n AppendConflict,\n DurableRuntimeFailpointError,\n]);\n\n/** Local implementation shared by every host; retries finish the same admitted row. */\nexport const admitWorker = Effect.fnUntraced(function* (request: WorkerAdmissionRequest) {\n const origin = request.workerAdmission.origin;\n\n if (\n origin.worker.threadId !== request.threadId ||\n origin.worker.targetAgentId !== request.agentId ||\n request.parentLinkage !== undefined\n )\n return yield* LedgerError.make({\n operation: \"admit worker\",\n message: \"Worker admission does not belong to the destination Thread\",\n });\n\n const ledger = yield* SubmissionLedger;\n const store = yield* ThreadStore;\n const wake = yield* WakeScheduler;\n const failpoint = yield* DurableRuntimeFailpoint;\n const admitted = yield* ledger.admit(AdmissionRequest.make(request));\n\n yield* failpoint.hit(\"submit:after-admit\");\n if (admitted.replayed && admitted.state !== \"admitted\") return admitted;\n\n yield* store.materialize(\n ThreadMaterialization.make({\n threadId: request.threadId,\n }),\n );\n\n const config = {\n producerId: request.producerId,\n deploymentId: request.deploymentId,\n };\n\n yield* ensureThreadCreated(config, request.threadId, request.agentId, request.agentDigests);\n yield* ensureWorkerOrigin(config, origin).pipe(\n Effect.mapError((cause) =>\n LedgerError.make({ operation: \"worker-origin\", message: cause.reason, cause }),\n ),\n );\n yield* failpoint.hit(\"submit:after-materialize\");\n yield* ledger.markReady(MarkReadyRequest.make({ submissionId: admitted.submissionId }));\n yield* wake.notify(request.threadId);\n\n return admitted;\n});\n\n/** Placement adapter for the composite operation; local hosts use the same implementation. */\nexport const WorkerAdmissionPort = Context.Reference<{ readonly admit: typeof admitWorker }>(\n \"@effect-agent/thread/WorkerAdmissionPort\",\n { defaultValue: () => ({ admit: admitWorker }) },\n);\n"],"mappings":"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"}
@@ -2,11 +2,11 @@ import { AgentId } from "./core/Identifiers.mjs";
2
2
  import { getToolExecutionKind } from "./core/SubagentContract.mjs";
3
3
  import { a as PinnedTool, l as ToolNamespace, n as DiscoveryTool, r as IncludesCatalogDocumentation, t as AdditionalToolCatalog } from "./ToolExposure-hTJT2ekj.mjs";
4
4
  import { BackgroundReporting, WorkerReportPreparationFailure } from "./engine/SubagentHost.mjs";
5
- import { S as withAttempt } from "./AgentRuntime-CQ-qcETl.mjs";
5
+ import { S as withAttempt } from "./AgentRuntime-B6qZlD3f.mjs";
6
6
  import { ContextRolloverTool } from "./engine/ContextWindow.mjs";
7
7
  import { getToolExecutionClass } from "./engine/DurableStep.mjs";
8
8
  import { tt as ReplayContract, v as DefinitionDigests } from "./Records-BiuJDWNe.mjs";
9
- import { o as digestDefinitions, s as digestJson, t as DigestError } from "./Digest-DCuPlhNk.mjs";
9
+ import { o as digestDefinitions, s as digestJson, t as DigestError } from "./Digest-EpeqWEdv.mjs";
10
10
  import { Context, Crypto, Effect, Layer, Option, References, Schema, Scope, Tracer } from "effect";
11
11
  import { Tool } from "effect/ai";
12
12
  //#region src/durable/internal/agent-registration.ts
@@ -24,6 +24,7 @@ const fallbackContracts = /* @__PURE__ */ new WeakMap();
24
24
  /** Hash current operation contracts; no historical definitions or schemas are retained. */
25
25
  const toolReplayContracts = Effect.fnUntraced(function* (definition, versions, fallbackVersion = null) {
26
26
  const crypto = Option.getOrUndefined(yield* Effect.serviceOption(Crypto.Crypto));
27
+ const invalidContracts = () => DigestError.make({ message: "Operation contracts require serializable codecs and a version for every Tool" });
27
28
  const prepared = yield* Effect.try({
28
29
  try: () => {
29
30
  const tools = Object.values(definition.toolkit.tools);
@@ -44,35 +45,7 @@ const toolReplayContracts = Effect.fnUntraced(function* (definition, versions, f
44
45
  };
45
46
  return {
46
47
  _tag: "Compile",
47
- declarations: tools.map((tool) => {
48
- const version = versions === void 0 ? fallbackVersion : versions.tools[tool.name];
49
- if (version === void 0 || versions !== void 0 && !Object.hasOwn(versions.tools, tool.name)) throw new Error("Every Tool needs an explicit replay semantic version");
50
- return {
51
- name: tool.name,
52
- contract: {
53
- version,
54
- ...Tool.isProviderDefined(tool) ? {
55
- provider: {
56
- id: tool.id,
57
- providerName: tool.providerName,
58
- args: Schema.decodeUnknownSync(Schema.Json)(tool.args ?? null),
59
- requiresHandler: tool.requiresHandler
60
- },
61
- readonly: Context.get(tool.annotations, Tool.Readonly)
62
- } : {},
63
- parameters: jsonSchema(tool.parametersSchema),
64
- success: jsonSchema(tool.successSchema),
65
- failure: jsonSchema(tool.failureSchema),
66
- failureMode: tool.failureMode,
67
- needsApproval: typeof tool.needsApproval === "function" ? "dynamic" : tool.needsApproval ?? false,
68
- executionClass: getToolExecutionClass(tool),
69
- executionKind: getToolExecutionKind(tool.annotations),
70
- contextRollover: Context.get(tool.annotations, ContextRolloverTool),
71
- completion: definition.completion?.tool === tool.name,
72
- completionFromTool: definition.completionFromTools?.some((declaration) => declaration.tool === tool.name) ?? false
73
- }
74
- };
75
- }),
48
+ jsonSchema,
76
49
  cacheable,
77
50
  tools,
78
51
  completionTool,
@@ -82,7 +55,45 @@ const toolReplayContracts = Effect.fnUntraced(function* (definition, versions, f
82
55
  catch: () => DigestError.make({ message: "Operation contracts require serializable codecs and a version for every Tool" })
83
56
  });
84
57
  if (prepared._tag === "Cached") return prepared.contracts;
85
- const contracts = Object.fromEntries(yield* Effect.forEach(prepared.declarations, ({ name, contract }) => digestJson(contract).pipe(Effect.map((digest) => [name, digest]))));
58
+ const declarations = yield* Effect.forEach(prepared.tools, Effect.fnUntraced(function* (tool) {
59
+ const { version, present } = yield* Effect.try({
60
+ try: () => ({
61
+ version: versions === void 0 ? fallbackVersion : versions.tools[tool.name],
62
+ present: versions === void 0 || Object.hasOwn(versions.tools, tool.name)
63
+ }),
64
+ catch: invalidContracts
65
+ });
66
+ if (version === void 0 || !present) return yield* invalidContracts();
67
+ return yield* Effect.try({
68
+ try: () => ({
69
+ name: tool.name,
70
+ contract: {
71
+ version,
72
+ ...Tool.isProviderDefined(tool) ? {
73
+ provider: {
74
+ id: tool.id,
75
+ providerName: tool.providerName,
76
+ args: Schema.decodeUnknownSync(Schema.Json)(tool.args ?? null),
77
+ requiresHandler: tool.requiresHandler
78
+ },
79
+ readonly: Context.get(tool.annotations, Tool.Readonly)
80
+ } : {},
81
+ parameters: prepared.jsonSchema(tool.parametersSchema),
82
+ success: prepared.jsonSchema(tool.successSchema),
83
+ failure: prepared.jsonSchema(tool.failureSchema),
84
+ failureMode: tool.failureMode,
85
+ needsApproval: typeof tool.needsApproval === "function" ? "dynamic" : tool.needsApproval ?? false,
86
+ executionClass: getToolExecutionClass(tool),
87
+ executionKind: getToolExecutionKind(tool.annotations),
88
+ contextRollover: Context.get(tool.annotations, ContextRolloverTool),
89
+ completion: definition.completion?.tool === tool.name,
90
+ completionFromTool: definition.completionFromTools?.some((declaration) => declaration.tool === tool.name) ?? false
91
+ }
92
+ }),
93
+ catch: invalidContracts
94
+ });
95
+ }));
96
+ const contracts = Object.fromEntries(yield* Effect.forEach(declarations, ({ name, contract }) => digestJson(contract).pipe(Effect.map((digest) => [name, digest]))));
86
97
  if (prepared.cacheable && crypto !== void 0) {
87
98
  const cache = fallbackContracts.get(crypto) ?? /* @__PURE__ */ new WeakMap();
88
99
  cache.set(definition.toolkit.tools, {
@@ -118,18 +129,18 @@ const backgroundReports = (definition) => [...new Set(Object.values(definition.t
118
129
  const report = Context.get(tool.annotations, BackgroundReporting);
119
130
  return report === void 0 ? [] : [report];
120
131
  }))];
121
- const capture = (agent, attemptLayer) => Effect.map(Effect.context().pipe(Effect.map(withoutTraceContext)), (context) => ({
132
+ const capture = (agent, prepare) => Effect.map(Effect.context().pipe(Effect.map(withoutTraceContext)), (context) => ({
122
133
  agentId: agent.definition.id,
123
134
  definition: agent.definition,
124
135
  attempt: (driver, threadId, claim) => {
125
- const execute = withAttempt(driver(agent, threadId, claim), threadId, claim.submissionId, claim.attemptId);
126
- return (attemptLayer === void 0 ? execute : execute.pipe(Effect.provide(Layer.fresh(attemptLayer({
136
+ return prepare(withAttempt(driver(agent, threadId, claim), threadId, claim.submissionId, claim.attemptId), {
127
137
  threadId,
128
138
  submissionId: claim.submissionId,
129
139
  attemptId: claim.attemptId
130
- }))))).pipe(Effect.provide(context));
140
+ }).pipe(Effect.provide(context));
131
141
  }
132
142
  }));
143
+ const captureWithAttemptLayer = (agent, attemptLayer) => capture(agent, (execute, context) => execute.pipe(Effect.provide(Layer.fresh(attemptLayer(context)))));
133
144
  /**
134
145
  * Build one exact worker registration from an executable Agent Binding and
135
146
  * its already-computed definition digests.
@@ -140,7 +151,7 @@ const capture = (agent, attemptLayer) => Effect.map(Effect.context().pipe(Effect
140
151
  * may supply a previously computed digest triple directly.
141
152
  */
142
153
  const DurableWorkerBinding = { make: (agent, digests) => Effect.gen(function* () {
143
- const binding = yield* capture(agent);
154
+ const binding = yield* capture(agent, (execute) => execute);
144
155
  const reporting = yield* captureReporting(backgroundReports(agent.definition));
145
156
  return {
146
157
  ...binding,
@@ -149,7 +160,7 @@ const DurableWorkerBinding = { make: (agent, digests) => Effect.gen(function* ()
149
160
  };
150
161
  }) };
151
162
  /** INTERNAL identity-only capture retained for the legacy direct worker path. */
152
- const makeLegacyWorkerBinding = capture;
163
+ const makeLegacyWorkerBinding = (agent) => capture(agent, (execute) => execute);
153
164
  const resolveWorkerBinding = Effect.fnUntraced(function* (bindings, submission) {
154
165
  const selection = yield* CurrentBindingSelection;
155
166
  const definition = selection === void 0 ? void 0 : yield* selection.select(submission);
@@ -223,27 +234,29 @@ const registrationDefinitions = (entry) => {
223
234
  }
224
235
  };
225
236
  };
226
- const compileRegistration = (entry) => Effect.flatMap(Effect.try({
227
- try: () => registrationDefinitions(entry),
228
- catch: () => DigestError.make({ message: "Agent update schema has no serializable wire contract" })
229
- }), (definitions) => Effect.gen(function* () {
230
- const binding = yield* capture(entry.model === void 0 ? entry.agent : {
231
- definition: entry.agent,
232
- model: entry.model
233
- }, entry.attemptLayer);
234
- const reporting = yield* captureReporting(backgroundReports(binding.definition));
235
- return {
236
- ...binding,
237
- ...yield* compileBindingContracts(binding.definition, definitions, entry.continuity?.versions),
238
- reporting
239
- };
240
- }));
237
+ function compileRegistration(entry) {
238
+ return Effect.flatMap(Effect.try({
239
+ try: () => registrationDefinitions(entry),
240
+ catch: () => DigestError.make({ message: "Agent update schema has no serializable wire contract" })
241
+ }), (definitions) => Effect.gen(function* () {
242
+ const agent = entry.model === void 0 ? entry.agent : {
243
+ definition: entry.agent,
244
+ model: entry.model
245
+ };
246
+ const binding = yield* entry.attemptLayer === void 0 ? capture(agent, (execute) => execute) : captureWithAttemptLayer(agent, entry.attemptLayer);
247
+ const reporting = yield* captureReporting(backgroundReports(binding.definition));
248
+ return {
249
+ ...binding,
250
+ ...yield* compileBindingContracts(binding.definition, definitions, entry.continuity?.versions),
251
+ reporting
252
+ };
253
+ }));
254
+ }
241
255
  /** Compile heterogeneous Agent descriptors into exact, dependency-closed worker registrations. */
242
256
  const compileRegistrations = (entries) => {
243
- const compileEntry = compileRegistration;
244
- return Effect.forEach(entries, compileEntry);
257
+ return Effect.forEach(entries, compileRegistration);
245
258
  };
246
259
  //#endregion
247
260
  export { compileRegistrations as a, resolveDefinitionBinding as c, compileBindingContracts as i, resolveWorkerBinding as l, CurrentBindingSelection as n, definitionDigestsEqual as o, DurableWorkerBinding as r, makeLegacyWorkerBinding as s, BindingUnavailable as t, toolReplayContracts as u };
248
261
 
249
- //# sourceMappingURL=agent-registration-ByMZ_cK5.mjs.map
262
+ //# sourceMappingURL=agent-registration-DRbyhAu-.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-registration-DRbyhAu-.mjs","names":["withProvisionalTextAttempt","run"],"sources":["../src/durable/internal/agent-registration.ts"],"sourcesContent":["import { Crypto, Option, Scope, Context, Effect, Layer, References, Schema, Tracer } from \"effect\";\nimport { Tool } from \"effect/ai\";\n\nimport type * as Agent from \"../../core/Agent.ts\";\nimport {\n type InputPromptSource,\n type InstructionSource,\n type ModelServices,\n type RunDispositionDeclaration,\n} from \"../../core/Agent.ts\";\nimport { type ThreadId, AgentId } from \"../../core/Identifiers.ts\";\nimport { getToolExecutionKind } from \"../../core/SubagentContract.ts\";\nimport {\n AdditionalToolCatalog,\n DiscoveryTool,\n IncludesCatalogDocumentation,\n PinnedTool,\n ToolNamespace,\n} from \"../../core/ToolExposure.ts\";\nimport { type RuntimeBinding } from \"../../engine/AgentRuntime.ts\";\nimport { ContextRolloverTool } from \"../../engine/ContextWindow.ts\";\nimport { getToolExecutionClass } from \"../../engine/DurableStep.ts\";\nimport { withAttempt as withProvisionalTextAttempt } from \"../../engine/internal/provisional-text.ts\";\nimport {\n BackgroundReporting,\n WorkerReportPreparationFailure,\n type WorkerReporting,\n} from \"../../engine/SubagentHost.ts\";\nimport { digestDefinitions, digestJson, DigestError } from \"../Digest.ts\";\nimport type { DurableWorkerFailure, DurableWorkerRequirements } from \"../DurableAgentRuntime.ts\";\nimport type { DefinitionDigestInput, Digest, PersistedJson } from \"../Records.ts\";\nimport { DefinitionDigests, ReplayContract } from \"../Records.ts\";\nimport type { Claim, Settlement, SubmissionSnapshot } from \"../SubmissionLedger.ts\";\n\n/** No unique current Binding can execute the stable Agent identity or decode its accepted input. */\nexport class BindingUnavailable extends Schema.TaggedError<BindingUnavailable>()(\n \"BindingUnavailable\",\n { agentId: AgentId, message: Schema.String },\n) {}\n\nexport type DurableBindingFailure = BindingUnavailable;\n\n/**\n * Submission execution/recovery routing for stable identities shared by current Definitions.\n * Worker declarations and peer-messaging endpoints still require unique Agent identities.\n */\nexport interface BindingSelection {\n /** Change when routing changes, so hosts can retry parked work without rewriting admission. */\n readonly key: string;\n /**\n * Select an exact registered Definition using the canonical Submission and authoritative host\n * state. Undefined retains unique-identity resolution. Never grant authority or mutate here;\n * input decoding, replay contracts and current Tool authorization still apply after selection.\n */\n readonly select: (\n submission: SubmissionSnapshot,\n ) => Effect.Effect<Agent.AnyDefinition | undefined, DurableWorkerFailure | BindingUnavailable>;\n}\n\n/** Captured at runtime construction; callers cannot replace routing during an Attempt. */\nexport const CurrentBindingSelection = Context.Reference<BindingSelection | undefined>(\n \"@effect-agent/thread/CurrentBindingSelection\",\n { defaultValue: () => undefined },\n);\n\n/** Exact immutable admission, lineage and delivery evidence; never an executable-code gate. */\nexport const definitionDigestsEqual = (\n left: DefinitionDigests,\n right: DefinitionDigests,\n): boolean =>\n left.agent === right.agent &&\n left.model === right.model &&\n left.tools === right.tools &&\n Schema.toEquivalence(Schema.UndefinedOr(ReplayContract))(left.replay, right.replay);\n\n/**\n * Explicit versions must cover every current Tool. Change a version when handler meaning,\n * durable Step names/codecs, external idempotency keys, authorization, completion projection,\n * or child/report protocols change. JSON Schema cannot detect handler or codec-transform changes.\n */\nexport interface ReplayVersions {\n readonly tools: Readonly<Record<string, PersistedJson>>;\n}\n\n// These are immutable declaration projections, never model or admission contexts.\nconst replaySchemaProjections = new WeakMap<Schema.Top, Schema.Json>();\n\ntype CachedFallbackContracts = {\n readonly tools: ReadonlyArray<Tool.Any>;\n readonly completionTool: string | undefined;\n readonly completionFromTools: ReadonlyArray<string>;\n readonly version: PersistedJson;\n readonly contracts: Record<string, Digest>;\n};\n\nconst fallbackContracts = new WeakMap<Crypto.Crypto, WeakMap<object, CachedFallbackContracts>>();\n\n/** Hash current operation contracts; no historical definitions or schemas are retained. */\nexport const toolReplayContracts = Effect.fnUntraced(function* (\n definition: Agent.AnyDefinition,\n versions?: ReplayVersions,\n fallbackVersion: PersistedJson = null,\n) {\n // Optional lookup preserves validation before a missing-service defect. A\n // different host Crypto service must never inherit another host's digest map.\n const crypto = Option.getOrUndefined(yield* Effect.serviceOption(Crypto.Crypto));\n\n const invalidContracts = () =>\n DigestError.make({\n message: \"Operation contracts require serializable codecs and a version for every Tool\",\n });\n\n const prepared = yield* Effect.try({\n try: () => {\n const tools = Object.values(definition.toolkit.tools);\n const completionTool = definition.completion?.tool;\n const completionFromTools = definition.completionFromTools?.map(({ tool }) => tool) ?? [];\n // Object-valued versions may be mutable caller data. Only primitive fallback\n // versions can reuse a result, and only one result is retained per toolkit.\n\n const cacheable =\n versions === undefined && (fallbackVersion === null || typeof fallbackVersion !== \"object\");\n\n const cached =\n cacheable && crypto !== undefined\n ? fallbackContracts.get(crypto)?.get(definition.toolkit.tools)\n : undefined;\n\n if (\n cached !== undefined &&\n cached.version === fallbackVersion &&\n cached.completionTool === completionTool &&\n cached.completionFromTools.length === completionFromTools.length &&\n cached.completionFromTools.every((tool, index) => tool === completionFromTools[index]) &&\n cached.tools.length === tools.length &&\n cached.tools.every((tool, index) => tool === tools[index])\n )\n return { _tag: \"Cached\" as const, contracts: { ...cached.contracts } };\n\n const jsonSchema = (schema: Schema.Top) => {\n const cached = replaySchemaProjections.get(schema);\n\n if (cached !== undefined) return cached;\n\n const projection = Schema.decodeUnknownSync(Schema.Json)(\n Tool.getJsonSchemaFromSchema(schema),\n );\n\n replaySchemaProjections.set(schema, projection);\n\n return projection;\n };\n\n return {\n _tag: \"Compile\" as const,\n jsonSchema,\n cacheable,\n tools,\n completionTool,\n completionFromTools,\n };\n },\n catch: () =>\n DigestError.make({\n message: \"Operation contracts require serializable codecs and a version for every Tool\",\n }),\n });\n\n if (prepared._tag === \"Cached\") return prepared.contracts;\n\n const declarations = yield* Effect.forEach(\n prepared.tools,\n Effect.fnUntraced(function* (tool) {\n const { version, present } = yield* Effect.try({\n try: () => ({\n version: versions === undefined ? fallbackVersion : versions.tools[tool.name],\n present: versions === undefined || Object.hasOwn(versions.tools, tool.name),\n }),\n catch: invalidContracts,\n });\n\n if (version === undefined || !present) return yield* invalidContracts();\n\n return yield* Effect.try({\n try: () => ({\n name: tool.name,\n contract: {\n version,\n ...(Tool.isProviderDefined(tool)\n ? {\n provider: {\n id: tool.id,\n providerName: tool.providerName,\n args: Schema.decodeUnknownSync(Schema.Json)(tool.args ?? null),\n requiresHandler: tool.requiresHandler,\n },\n readonly: Context.get(tool.annotations, Tool.Readonly),\n }\n : {}),\n parameters: prepared.jsonSchema(tool.parametersSchema),\n success: prepared.jsonSchema(tool.successSchema),\n failure: prepared.jsonSchema(tool.failureSchema),\n failureMode: tool.failureMode,\n needsApproval:\n typeof tool.needsApproval === \"function\" ? \"dynamic\" : (tool.needsApproval ?? false),\n executionClass: getToolExecutionClass(tool),\n executionKind: getToolExecutionKind(tool.annotations),\n contextRollover: Context.get(tool.annotations, ContextRolloverTool),\n completion: definition.completion?.tool === tool.name,\n completionFromTool:\n definition.completionFromTools?.some(\n (declaration) => declaration.tool === tool.name,\n ) ?? false,\n },\n }),\n catch: invalidContracts,\n });\n }),\n );\n\n const contracts = Object.fromEntries(\n yield* Effect.forEach(declarations, ({ name, contract }) =>\n digestJson(contract).pipe(Effect.map((digest) => [name, digest] as const)),\n ),\n );\n\n if (prepared.cacheable && crypto !== undefined) {\n const cache = fallbackContracts.get(crypto) ?? new WeakMap<object, CachedFallbackContracts>();\n\n cache.set(definition.toolkit.tools, {\n tools: prepared.tools,\n completionTool: prepared.completionTool,\n completionFromTools: prepared.completionFromTools,\n version: fallbackVersion,\n contracts: { ...contracts },\n });\n fallbackContracts.set(crypto, cache);\n }\n\n return contracts;\n});\n\n/** Compile current metadata without acquiring executable services. */\nexport const compileBindingContracts = Effect.fnUntraced(function* (\n definition: Agent.AnyDefinition,\n definitions: DefinitionDigestInput,\n versions?: ReplayVersions,\n): Effect.fn.Return<Pick<ResolvedBinding, \"digests\">, DigestError, Crypto.Crypto> {\n const digests = yield* digestDefinitions(definitions);\n const tools = yield* toolReplayContracts(definition, versions, definitions.tools);\n\n return {\n digests: DefinitionDigests.make({\n ...digests,\n replay: ReplayContract.make({ agent: digests.agent, tools }),\n }),\n };\n});\n\ntype ExecutableDefinition = Agent.AnyDefinition & {\n readonly instructions: InstructionSource<never, unknown, unknown>;\n readonly inputPrompt?: InputPromptSource<never, unknown, unknown> | undefined;\n};\n\n/** Executable model Binding accepted by durable registration descriptors. */\nexport type ExecutableAgentBinding = {\n readonly definition: ExecutableDefinition;\n readonly model: Layer.Layer<ModelServices, never, unknown>;\n};\n\n/**\n * Internal coordinator entry point for one fenced Attempt over an already-granted claim.\n * The generic signature matches `runAttempt` and is specialized for each captured Agent.\n */\ntype ResolvedAttemptDriver = <\n InputSchema extends Schema.Top,\n OutputSchema extends Schema.Top,\n Instructions,\n Tools extends Record<string, Tool.Any>,\n Provider,\n ModelProvides,\n ModelRequires,\n InstructionError,\n InstructionRequirements,\n RunDispositionValue extends\n | RunDispositionDeclaration<OutputSchema[\"Type\"], Schema.Top>\n | undefined,\n InputPromptValue extends InputPromptSource<InputSchema[\"Type\"], unknown, unknown> | undefined,\n UpdatesSchema extends Schema.Top | undefined,\n>(\n agent: RuntimeBinding<\n InputSchema,\n OutputSchema,\n Instructions,\n Tools,\n Provider,\n ModelProvides,\n ModelRequires,\n InstructionError,\n InstructionRequirements,\n RunDispositionValue,\n InputPromptValue,\n UpdatesSchema\n >,\n threadId: ThreadId,\n claim: Claim,\n) => Effect.Effect<\n Option.Option<Settlement>,\n DurableWorkerFailure | DurableBindingFailure,\n DurableWorkerRequirements<\n RuntimeBinding<\n InputSchema,\n OutputSchema,\n Instructions,\n Tools,\n Provider,\n ModelProvides,\n ModelRequires,\n InstructionError,\n InstructionRequirements,\n RunDispositionValue,\n InputPromptValue,\n UpdatesSchema\n >,\n InstructionRequirements\n >\n>;\n\ntype CapturedAttempt<A extends ExecutableAgentBinding> = (\n agent: A,\n threadId: ThreadId,\n claim: Claim,\n) => Effect.Effect<\n Option.Option<Settlement>,\n DurableWorkerFailure | DurableBindingFailure,\n DurableWorkerRequirements<A>\n>;\n\n/**\n * An Agent with its worker services captured, ready to drive a fenced Attempt.\n * Concrete Schema and model types stay inside this closure when registrations are collected.\n */\ninterface CapturedBinding {\n readonly agentId: AgentId;\n /** Exact immutable definition whose codecs and behavior the worker captured. */\n readonly definition: Agent.AnyDefinition;\n /** Captured independently from per-Attempt services: report preparation has no fenced Claim. */\n readonly reporting?: ReadonlyArray<WorkerReporting<WorkerReportPreparationFailure>>;\n readonly attempt: (\n driver: ResolvedAttemptDriver,\n threadId: ThreadId,\n claim: Claim,\n ) => Effect.Effect<Option.Option<Settlement>, DurableWorkerFailure | DurableBindingFailure>;\n}\n\n// Registrations outlive their construction span. Dependencies remain captured,\n// while every attempt/report inherits the invoking fiber's tracing state.\nconst omitTraceContext = Context.omit(\n Scope.Scope,\n Tracer.ParentSpan,\n Tracer.Tracer,\n Tracer.MinimumTraceLevel,\n Tracer.CurrentTraceLevel,\n References.TracerEnabled,\n References.TracerTimingEnabled,\n References.TracerSpanAnnotations,\n References.TracerSpanLinks,\n References.CurrentLoggers,\n References.CurrentLogLevel,\n References.MinimumLogLevel,\n References.CurrentStackFrame,\n References.CurrentLogAnnotations,\n References.CurrentLogSpans,\n);\n\n// R describes captured application services; ParentSpan is supplied by the\n// live invocation rather than stored as a registration dependency.\nconst withoutTraceContext = <R>(context: Context.Context<R>): Context.Context<R> =>\n omitTraceContext(context) as Context.Context<R>;\n\nconst captureReporting = <E, R>(reports: ReadonlyArray<WorkerReporting<E, R>>) =>\n Effect.map(\n Effect.context<Exclude<R, Scope.Scope>>().pipe(Effect.map(withoutTraceContext)),\n (context) =>\n reports.map((report): WorkerReporting<WorkerReportPreparationFailure> => ({\n ...report,\n prepare: (value) =>\n Effect.scoped(Effect.suspend(() => report.prepare(value))).pipe(\n Effect.provide(context),\n Effect.mapError((error) =>\n Schema.is(WorkerReportPreparationFailure)(error)\n ? error\n : WorkerReportPreparationFailure.make({ stage: \"preparation\" }),\n ),\n ),\n })),\n );\n\nconst backgroundReports = (definition: Agent.AnyDefinition) => [\n ...new Set(\n Object.values(definition.toolkit.tools).flatMap((tool) => {\n const report = Context.get(tool.annotations, BackgroundReporting);\n\n return report === undefined ? [] : [report];\n }),\n ),\n];\n\n/** One exact executable registration used by durable claim-time resolution. */\nexport interface ResolvedBinding extends CapturedBinding {\n readonly digests: DefinitionDigests;\n}\n\n/** Trusted claim identity for resolving per-Attempt application services. Not model input. */\nexport interface AgentAttemptContext {\n readonly threadId: ThreadId;\n readonly submissionId: Claim[\"submissionId\"];\n readonly attemptId: Claim[\"attemptId\"];\n}\n\nconst capture = <A extends ExecutableAgentBinding, Requires>(\n agent: A,\n prepare: (\n execute: ReturnType<CapturedAttempt<A>>,\n context: AgentAttemptContext,\n ) => Effect.Effect<\n Option.Option<Settlement>,\n DurableWorkerFailure | DurableBindingFailure,\n Requires\n >,\n): Effect.Effect<CapturedBinding, never, Requires> =>\n Effect.map(\n Effect.context<Requires>().pipe(Effect.map(withoutTraceContext)),\n (context): CapturedBinding => ({\n agentId: agent.definition.id,\n definition: agent.definition,\n attempt: (driver, threadId, claim) => {\n // Registration closes one concrete Binding before heterogeneous registrations are\n // collected. TypeScript cannot instantiate the higher-rank RuntimeBinding parameters\n // from the intentionally erased public shape, so specialize the driver back to A here.\n const run = driver as unknown as CapturedAttempt<A>;\n\n const execute = withProvisionalTextAttempt(\n run(agent, threadId, claim),\n threadId,\n claim.submissionId,\n claim.attemptId,\n );\n\n return prepare(execute, {\n threadId,\n submissionId: claim.submissionId,\n attemptId: claim.attemptId,\n }).pipe(Effect.provide(context));\n },\n }),\n );\n\nconst captureWithAttemptLayer = <A extends ExecutableAgentBinding, Provides, Requires>(\n agent: A,\n attemptLayer: (context: AgentAttemptContext) => Layer.Layer<Provides, never, Requires>,\n) =>\n capture(agent, (execute, context) =>\n execute.pipe(Effect.provide(Layer.fresh(attemptLayer(context)))),\n );\n\n/**\n * Build one exact worker registration from an executable Agent Binding and\n * its already-computed definition digests.\n *\n * `make(agent, digests)` captures the binding plus its worker-requirement\n * Context at Layer/effect construction time. Hosts that start from application\n * version declarations should use `compileRegistrations`; low-level fixtures\n * may supply a previously computed digest triple directly.\n */\nexport const DurableWorkerBinding = {\n make: <A extends ExecutableAgentBinding>(\n agent: A,\n digests: DefinitionDigests,\n ): Effect.Effect<ResolvedBinding, never, DurableWorkerRequirements<A>> =>\n Effect.gen(function* () {\n const binding = yield* capture(agent, (execute) => execute);\n const reporting = yield* captureReporting(backgroundReports(agent.definition));\n\n return { ...binding, digests, reporting };\n }),\n} as const;\n\n/** INTERNAL identity-only capture retained for the legacy direct worker path. */\nexport const makeLegacyWorkerBinding = <A extends ExecutableAgentBinding>(agent: A) =>\n capture(agent, (execute) => execute);\n\nexport const resolveWorkerBinding = Effect.fnUntraced(function* (\n bindings: ReadonlyArray<ResolvedBinding>,\n submission: SubmissionSnapshot,\n) {\n const selection = yield* CurrentBindingSelection;\n const definition = selection === undefined ? undefined : yield* selection.select(submission);\n\n const registered = bindings.filter(\n (binding) =>\n binding.agentId === submission.agentId &&\n (definition === undefined || Object.is(binding.definition, definition)),\n );\n\n const binding = registered[0];\n\n if (registered.length !== 1 || binding === undefined)\n return yield* BindingUnavailable.make({\n agentId: submission.agentId,\n message: \"Exactly one current Agent Binding must match the accepted Submission\",\n });\n\n return binding;\n});\n\n/** Resolve authoring-time admission through exact host registration, never by identity alone. */\nexport const resolveDefinitionBinding = (\n bindings: ReadonlyArray<ResolvedBinding>,\n definition: Pick<Agent.AnyDefinition, \"id\">,\n): Effect.Effect<ResolvedBinding, BindingUnavailable> => {\n const candidates = bindings.filter(\n (binding) => binding.agentId === definition.id && Object.is(binding.definition, definition),\n );\n\n const binding = candidates[0];\n\n return candidates.length === 1 && binding !== undefined\n ? Effect.succeed(binding)\n : Effect.fail(\n BindingUnavailable.make({\n agentId: definition.id,\n message:\n \"Registered admission requires exactly one registration of the exact Agent Definition\",\n }),\n );\n};\n\n/** Application versions and a model Layer, supplied directly or through an existing Binding. */\nexport type AgentRegistration<A extends ExecutableAgentBinding = ExecutableAgentBinding> = (\n | { readonly agent: A; readonly model?: never; readonly definitions: DefinitionDigestInput }\n | {\n readonly agent: A[\"definition\"];\n readonly model: A[\"model\"];\n readonly definitions: DefinitionDigestInput;\n }\n) & {\n /** Explicit operation versions let unchanged unfinished handlers survive toolbox changes. */\n readonly continuity?: {\n readonly versions: ReplayVersions;\n };\n /**\n * Build fresh services for exactly one fenced Attempt, across all its Tool/model turns.\n * Finalizes on completion, suspension, failure and interruption. Never reused after eviction.\n * Resolve invocation authority from the trusted claim identity, not captured caller state.\n * Keep fallible resource acquisition lazy in typed Tool operations; this Layer cannot fail.\n * Provide DurableApprovalSuspension here when resources need retention before approval waits.\n */\n readonly attemptLayer?: (context: AgentAttemptContext) => Layer.Layer<never, never, unknown>;\n};\n\ntype EntryWorkerRequirements<Entry> = Entry extends {\n readonly agent: infer A extends ExecutableAgentBinding;\n}\n ? DurableWorkerRequirements<A>\n : Entry extends {\n readonly agent: infer D extends ExecutableDefinition;\n readonly model: infer M extends ExecutableAgentBinding[\"model\"];\n }\n ? DurableWorkerRequirements<{ readonly definition: D; readonly model: M }>\n : never;\n\ntype AttemptLayerRequirements<Requirements, AttemptLayer> = AttemptLayer extends (\n context: AgentAttemptContext,\n) => Layer.Layer<infer Provides, never, infer Requires>\n ? Exclude<Requirements, Provides> | Requires\n : Requirements;\n\n// Conditional options retain every service they may consume. An absent attempt Layer\n// still needs the original worker services; only a definite Layer can remove them.\ntype EntryRequirements<Entry> = Entry extends unknown\n ? AttemptLayerRequirements<\n EntryWorkerRequirements<Entry>,\n \"attemptLayer\" extends keyof Entry ? Entry[\"attemptLayer\"] : undefined\n >\n : never;\n\ntype RegistrationRequirements<Entries extends ReadonlyArray<AgentRegistration>> = EntryRequirements<\n Entries[number]\n>;\n\nconst registrationDefinitions = (entry: AgentRegistration): DefinitionDigestInput => {\n const definition = entry.model === undefined ? entry.agent.definition : entry.agent;\n const automatic = backgroundReports(definition);\n\n const declaredDefinitions =\n definition.updates === undefined\n ? entry.definitions\n : {\n ...entry.definitions,\n agent: {\n declaration: entry.definitions.agent,\n updates: Schema.decodeUnknownSync(Schema.Json)(\n Tool.getJsonSchemaFromSchema(definition.updates),\n ),\n updateProtocol: { schemaVersion: 1, tool: \"emit_update\" },\n },\n };\n\n const definitions =\n automatic.length === 0\n ? declaredDefinitions\n : {\n ...declaredDefinitions,\n agent: {\n declaration: declaredDefinitions.agent,\n backgroundReporting: automatic.map((report) => ({\n delegationId: report.delegationId,\n targetAgentId: report.target.id,\n mode: \"standard\",\n // Preserve the fingerprint of existing standard registrations.\n destinationDelegationId: null,\n })),\n },\n };\n\n const exposure = definition.toolExposure;\n\n if (\n exposure === undefined &&\n !Object.values(definition.toolkit.tools).some(\n (tool) =>\n Context.get(tool.annotations, DiscoveryTool) || Context.get(tool.annotations, PinnedTool),\n )\n )\n return definitions;\n\n return {\n ...definitions,\n agent: {\n declaration: definitions.agent,\n toolExposure: {\n initialToolNames: exposure === undefined ? null : [...(exposure.initialToolNames ?? [])],\n maxTools: exposure?.maxTools ?? 64,\n maxSchemaBytes: exposure?.maxSchemaBytes ?? 262_144,\n requiredCompletion:\n definition.completion?.required === true ? definition.completion.tool : null,\n tools: Object.values(definition.toolkit.tools).map((tool) => ({\n name: tool.name,\n pinned: Context.get(tool.annotations, PinnedTool),\n discovery: Context.get(tool.annotations, DiscoveryTool),\n namespace: Context.get(tool.annotations, ToolNamespace) ?? null,\n includesCatalogDocumentation: Context.get(tool.annotations, IncludesCatalogDocumentation),\n additional: Context.get(tool.annotations, AdditionalToolCatalog).map((entry) => ({\n name: entry.tool.name,\n namespace: entry.namespace,\n method: entry.method,\n })),\n })),\n },\n },\n };\n};\n\n// The public signature distributes over descriptors, including optional attempt Layers.\n// The implementation consumes their erased union and captures the selected Layer's context.\nfunction compileRegistration<Entry extends AgentRegistration>(\n entry: Entry,\n): Effect.Effect<ResolvedBinding, DigestError, Crypto.Crypto | EntryRequirements<Entry>>;\nfunction compileRegistration(entry: AgentRegistration) {\n return Effect.flatMap(\n Effect.try({\n try: () => registrationDefinitions(entry),\n catch: () =>\n DigestError.make({ message: \"Agent update schema has no serializable wire contract\" }),\n }),\n (definitions) =>\n Effect.gen(function* () {\n const agent =\n // The heterogeneous descriptor erases model services; the overload retains EntryRequirements.\n // @effect-diagnostics-next-line anyUnknownInErrorContext:off\n entry.model === undefined ? entry.agent : { definition: entry.agent, model: entry.model };\n\n // Omitted attempt services need no Layer construction or provisioning scope.\n const binding = yield* entry.attemptLayer === undefined\n ? // Capture closes the erased requirements over the registration's actual Context.\n // @effect-diagnostics-next-line anyUnknownInErrorContext:off\n capture(agent, (execute) => execute)\n : // The selected Layer discharges its services before the remaining Context is captured.\n // @effect-diagnostics-next-line anyUnknownInErrorContext:off\n captureWithAttemptLayer(agent, entry.attemptLayer);\n\n const reporting = yield* captureReporting(backgroundReports(binding.definition));\n\n return {\n ...binding,\n ...(yield* compileBindingContracts(\n binding.definition,\n definitions,\n entry.continuity?.versions,\n )),\n reporting,\n };\n }),\n );\n}\n\n/** Compile heterogeneous Agent descriptors into exact, dependency-closed worker registrations. */\nexport const compileRegistrations = <const Entries extends ReadonlyArray<AgentRegistration>>(\n entries: Entries,\n): Effect.Effect<\n ReadonlyArray<ResolvedBinding>,\n DigestError,\n Crypto.Crypto | RegistrationRequirements<Entries>\n> => {\n return Effect.forEach(entries, compileRegistration<Entries[number]>);\n};\n"],"mappings":"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"}
@@ -102,7 +102,7 @@ const ApprovalAuditMemoryLive = Layer.effect(ApprovalAudit, Effect.gen(function*
102
102
  pending: /* @__PURE__ */ new Set()
103
103
  });
104
104
  return ApprovalAudit.of({
105
- recordRequest: (request) => Effect.gen(function* () {
105
+ recordRequest: Effect.fnUntraced(function* (request) {
106
106
  const recordedAt = DateTime.toUtc(DateTime.makeUnsafe(yield* Clock.currentTimeMillis));
107
107
  const error = yield* Ref.modify(state, (current) => {
108
108
  const reservedSize = current.events.length + current.pending.size + 2;
@@ -122,7 +122,7 @@ const ApprovalAuditMemoryLive = Layer.effect(ApprovalAudit, Effect.gen(function*
122
122
  });
123
123
  if (error !== void 0) return yield* error;
124
124
  }),
125
- recordDecision: (decision) => Effect.gen(function* () {
125
+ recordDecision: Effect.fnUntraced(function* (decision) {
126
126
  const recordedAt = DateTime.toUtc(DateTime.makeUnsafe(yield* Clock.currentTimeMillis));
127
127
  const error = yield* Ref.modify(state, (current) => {
128
128
  if (!current.pending.has(decision.requestId)) return [ApprovalDecisionMismatch.make({
@@ -1 +1 @@
1
- {"version":3,"file":"Approval.mjs","names":[],"sources":["../../src/capabilities/Approval.ts"],"sourcesContent":["import { Clock, Context, DateTime, Duration, Effect, Layer, Ref, Schema } from \"effect\";\n\nimport { ThreadId, RunId, ToolCallId } from \"../core/Identifiers.ts\";\nimport { utf8ByteLength } from \"../core/internal/utf8.ts\";\nimport { RedactedPreview, Redactor, type RedactionError } from \"./Redaction.ts\";\n\nconst MAX_APPROVAL_TARGETS = 32;\nconst MAX_APPROVAL_TARGET_BYTES = 64 * 1024;\nconst MAX_APPROVAL_AUDIT_EVENTS = 2_048;\n\nconst ApprovalTargets = Schema.Array(Schema.String.check(Schema.isMaxLength(2 * 1024)))\n .check(Schema.isMaxLength(MAX_APPROVAL_TARGETS))\n .pipe(\n Schema.refine(\n (targets): targets is ReadonlyArray<string> =>\n targets.reduce((total, target) => total + utf8ByteLength(target), 0) <=\n MAX_APPROVAL_TARGET_BYTES,\n { expected: `approval targets totaling at most ${MAX_APPROVAL_TARGET_BYTES} UTF-8 bytes` },\n ),\n );\n\nconst ApprovalRequestFields = {\n requestId: Schema.NonEmptyString,\n runId: RunId,\n threadId: ThreadId,\n toolCallId: ToolCallId,\n toolName: Schema.NonEmptyString,\n actionSummary: Schema.String.check(Schema.isMaxLength(2 * 1024)),\n resourceTargets: ApprovalTargets,\n risk: Schema.Literals([\"low\", \"medium\", \"high\", \"critical\"]),\n expiresAt: Schema.DateTimeUtcFromString,\n denial: Schema.Literals([\"terminal\", \"recoverable\"]),\n} as const;\n\n/** Decoded approval metadata before the Redactor owns Tool input preview creation. */\nexport class ApprovalRequestDraft extends Schema.Class<ApprovalRequestDraft>(\n \"@effect-agent/capabilities/ApprovalRequestDraft\",\n)(ApprovalRequestFields) {}\n\n/** Fully decoded, structurally redacted approval input. */\nexport class ApprovalRequest extends Schema.Class<ApprovalRequest>(\n \"@effect-agent/capabilities/ApprovalRequest\",\n)({\n ...ApprovalRequestFields,\n redactedInputPreview: RedactedPreview,\n}) {}\n\nexport class ApprovalApproved extends Schema.TaggedClass<ApprovalApproved>()(\"ApprovalApproved\", {\n requestId: Schema.NonEmptyString,\n decidedAt: Schema.DateTimeUtcFromString,\n resolver: Schema.NonEmptyString,\n}) {}\n\nexport class ApprovalDenied extends Schema.TaggedClass<ApprovalDenied>()(\"ApprovalDenied\", {\n requestId: Schema.NonEmptyString,\n decidedAt: Schema.DateTimeUtcFromString,\n resolver: Schema.NonEmptyString,\n reason: Schema.String.check(Schema.isMaxLength(2 * 1024)),\n timedOut: Schema.Boolean,\n}) {}\n\nexport const ApprovalDecision = Schema.Union([ApprovalApproved, ApprovalDenied]);\nexport type ApprovalDecision = typeof ApprovalDecision.Type;\n\n/** Resolver infrastructure failed before it could make a policy decision. */\nexport class ApprovalResolverError extends Schema.TaggedError<ApprovalResolverError>()(\n \"ApprovalResolverError\",\n { message: Schema.String },\n) {}\n\n/** The resolver explicitly observed its request deadline; callers turn this into a denial. */\nexport class ApprovalTimedOut extends Schema.TaggedError<ApprovalTimedOut>()(\"ApprovalTimedOut\", {\n requestId: Schema.NonEmptyString,\n}) {}\n\n/** First-class approval authority. Interactive, policy, and remote adapters implement this service. */\nexport class ApprovalResolver extends Context.Service<\n ApprovalResolver,\n {\n readonly request: (\n request: ApprovalRequest,\n ) => Effect.Effect<ApprovalDecision, ApprovalResolverError | ApprovalTimedOut>;\n }\n>()(\"@effect-agent/capabilities/ApprovalResolver\") {}\n\nexport class ApprovalRequestRecorded extends Schema.TaggedClass<ApprovalRequestRecorded>()(\n \"ApprovalRequestRecorded\",\n {\n sequence: Schema.Natural,\n recordedAt: Schema.DateTimeUtcFromString,\n request: ApprovalRequest,\n },\n) {}\n\nexport class ApprovalDecisionRecorded extends Schema.TaggedClass<ApprovalDecisionRecorded>()(\n \"ApprovalDecisionRecorded\",\n {\n sequence: Schema.Natural,\n recordedAt: Schema.DateTimeUtcFromString,\n decision: ApprovalDecision,\n },\n) {}\n\nexport const ApprovalAuditEvent = Schema.Union([ApprovalRequestRecorded, ApprovalDecisionRecorded]);\nexport type ApprovalAuditEvent = typeof ApprovalAuditEvent.Type;\n\nexport const ApprovalAuditEvents = Schema.Array(ApprovalAuditEvent).check(\n Schema.isMaxLength(MAX_APPROVAL_AUDIT_EVENTS),\n);\n\nexport class ApprovalAuditLimitExceeded extends Schema.TaggedError<ApprovalAuditLimitExceeded>()(\n \"ApprovalAuditLimitExceeded\",\n {\n limitValue: Schema.Natural,\n observedValue: Schema.Natural,\n },\n) {}\n\n/** A resolver or audit sink tried to associate a decision with another request. */\nexport class ApprovalDecisionMismatch extends Schema.TaggedError<ApprovalDecisionMismatch>()(\n \"ApprovalDecisionMismatch\",\n {\n expectedRequestId: Schema.NonEmptyString,\n observedRequestId: Schema.NonEmptyString,\n },\n) {}\n\n/** P2 semantic audit sink; durable runtimes replace this with canonical records. */\nexport class ApprovalAudit extends Context.Service<\n ApprovalAudit,\n {\n readonly recordRequest: (\n request: ApprovalRequest,\n ) => Effect.Effect<void, ApprovalAuditLimitExceeded>;\n readonly recordDecision: (\n decision: ApprovalDecision,\n ) => Effect.Effect<void, ApprovalAuditLimitExceeded | ApprovalDecisionMismatch>;\n readonly events: Effect.Effect<ReadonlyArray<ApprovalAuditEvent>>;\n }\n>()(\"@effect-agent/capabilities/ApprovalAudit\") {}\n\n/** Scoped in-memory audit projection with monotonic event order. */\nexport const ApprovalAuditMemoryLive = Layer.effect(\n ApprovalAudit,\n Effect.gen(function* () {\n interface AuditState {\n readonly events: ReadonlyArray<ApprovalAuditEvent>;\n readonly pending: ReadonlySet<string>;\n }\n const state = yield* Ref.make<AuditState>({ events: [], pending: new Set() });\n\n return ApprovalAudit.of({\n recordRequest: (request) =>\n Effect.gen(function* () {\n const recordedAt = DateTime.toUtc(DateTime.makeUnsafe(yield* Clock.currentTimeMillis));\n\n const error = yield* Ref.modify(state, (current) => {\n // Each accepted request atomically reserves room for its decision.\n const reservedSize = current.events.length + current.pending.size + 2;\n\n if (reservedSize > MAX_APPROVAL_AUDIT_EVENTS) {\n return [\n ApprovalAuditLimitExceeded.make({\n limitValue: MAX_APPROVAL_AUDIT_EVENTS,\n observedValue: reservedSize,\n }),\n current,\n ] as const;\n }\n\n const event = ApprovalRequestRecorded.make({\n sequence: current.events.length,\n recordedAt,\n request,\n });\n\n return [\n undefined,\n {\n events: [...current.events, event],\n pending: new Set(current.pending).add(request.requestId),\n },\n ] as const;\n });\n\n if (error !== undefined) return yield* error;\n }),\n recordDecision: (decision) =>\n Effect.gen(function* () {\n const recordedAt = DateTime.toUtc(DateTime.makeUnsafe(yield* Clock.currentTimeMillis));\n\n const error = yield* Ref.modify(state, (current) => {\n if (!current.pending.has(decision.requestId)) {\n return [\n ApprovalDecisionMismatch.make({\n expectedRequestId: [...current.pending][0] ?? \"no-pending-request\",\n observedRequestId: decision.requestId,\n }),\n current,\n ] as const;\n }\n const pending = new Set(current.pending);\n\n pending.delete(decision.requestId);\n\n const event = ApprovalDecisionRecorded.make({\n sequence: current.events.length,\n recordedAt,\n decision,\n });\n\n return [\n undefined,\n {\n events: [...current.events, event],\n pending,\n },\n ] as const;\n });\n\n if (error !== undefined) return yield* error;\n }),\n events: Ref.get(state).pipe(Effect.map((current) => current.events)),\n });\n }),\n);\n\n/** Construct an ApprovalRequest only after decoded input passes the configured Redactor. */\nexport const makeApprovalRequest = Effect.fnUntraced(function* (\n draft: ApprovalRequestDraft,\n decodedToolInput: unknown,\n): Effect.fn.Return<ApprovalRequest, RedactionError, Redactor> {\n const redactor = yield* Redactor;\n const redactedInputPreview = yield* redactor.redact(decodedToolInput);\n\n return ApprovalRequest.make({\n requestId: draft.requestId,\n runId: draft.runId,\n threadId: draft.threadId,\n toolCallId: draft.toolCallId,\n toolName: draft.toolName,\n actionSummary: draft.actionSummary,\n resourceTargets: draft.resourceTargets,\n risk: draft.risk,\n expiresAt: draft.expiresAt,\n denial: draft.denial,\n redactedInputPreview,\n });\n});\n\nconst timeoutDenial = (request: ApprovalRequest, decidedAt: DateTime.Utc): ApprovalDenied =>\n ApprovalDenied.make({\n requestId: request.requestId,\n decidedAt,\n resolver: \"effect-agent.timeout-deny\",\n reason: \"Approval request expired before a decision was available\",\n timedOut: true,\n });\n\n/**\n * Resolve with fail-closed deadline semantics and record request/decision audit\n * events around every successful, denied, timed-out, or resolver-failed\n * resolution. A resolver infrastructure failure records a synthetic denial so\n * the audit reservation is released before the typed error propagates.\n */\nexport const requestApproval = Effect.fnUntraced(function* (request: ApprovalRequest) {\n const audit = yield* ApprovalAudit;\n\n yield* audit.recordRequest(request);\n const nowMillis = yield* Clock.currentTimeMillis;\n const now = DateTime.toUtc(DateTime.makeUnsafe(nowMillis));\n const remainingMillis = DateTime.toEpochMillis(request.expiresAt) - nowMillis;\n\n let decision: ApprovalDecision;\n\n if (remainingMillis <= 0) {\n decision = timeoutDenial(request, now);\n } else {\n const resolver = yield* ApprovalResolver;\n\n decision = yield* resolver.request(request).pipe(\n Effect.timeoutOrElse({\n duration: Duration.millis(remainingMillis),\n orElse: () =>\n Clock.currentTimeMillis.pipe(\n Effect.map((millis) =>\n timeoutDenial(request, DateTime.toUtc(DateTime.makeUnsafe(millis))),\n ),\n ),\n }),\n Effect.catchTag(\"ApprovalTimedOut\", () =>\n Clock.currentTimeMillis.pipe(\n Effect.map((millis) =>\n timeoutDenial(request, DateTime.toUtc(DateTime.makeUnsafe(millis))),\n ),\n ),\n ),\n Effect.tapError(() =>\n Clock.currentTimeMillis.pipe(\n Effect.flatMap((millis) =>\n audit.recordDecision(\n ApprovalDenied.make({\n requestId: request.requestId,\n decidedAt: DateTime.toUtc(DateTime.makeUnsafe(millis)),\n resolver: \"effect-agent.resolver-error\",\n reason: \"Approval resolver failed before making a policy decision\",\n timedOut: false,\n }),\n ),\n ),\n ),\n ),\n );\n }\n if (decision.requestId !== request.requestId) {\n const mismatch = ApprovalDecisionMismatch.make({\n expectedRequestId: request.requestId,\n observedRequestId: decision.requestId,\n });\n\n const denied = ApprovalDenied.make({\n requestId: request.requestId,\n decidedAt: DateTime.toUtc(DateTime.makeUnsafe(yield* Clock.currentTimeMillis)),\n resolver: \"effect-agent.correlation-check\",\n reason: \"Approval resolver returned a decision for another request\",\n timedOut: false,\n });\n\n yield* audit.recordDecision(denied);\n\n return yield* mismatch;\n }\n yield* audit.recordDecision(decision);\n\n return decision;\n});\n\n/** Deterministic policy layer for tests and deny-by-default deployments. */\nexport const ApprovalDenyAll = Layer.succeed(ApprovalResolver)({\n request: (request) =>\n Clock.currentTimeMillis.pipe(\n Effect.map((millis) =>\n ApprovalDenied.make({\n requestId: request.requestId,\n decidedAt: DateTime.toUtc(DateTime.makeUnsafe(millis)),\n resolver: \"effect-agent.deny-all\",\n reason: \"No approving policy is configured\",\n timedOut: false,\n }),\n ),\n ),\n});\n"],"mappings":"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"}
1
+ {"version":3,"file":"Approval.mjs","names":[],"sources":["../../src/capabilities/Approval.ts"],"sourcesContent":["import { Clock, Context, DateTime, Duration, Effect, Layer, Ref, Schema } from \"effect\";\n\nimport { ThreadId, RunId, ToolCallId } from \"../core/Identifiers.ts\";\nimport { utf8ByteLength } from \"../core/internal/utf8.ts\";\nimport { RedactedPreview, Redactor, type RedactionError } from \"./Redaction.ts\";\n\nconst MAX_APPROVAL_TARGETS = 32;\nconst MAX_APPROVAL_TARGET_BYTES = 64 * 1024;\nconst MAX_APPROVAL_AUDIT_EVENTS = 2_048;\n\nconst ApprovalTargets = Schema.Array(Schema.String.check(Schema.isMaxLength(2 * 1024)))\n .check(Schema.isMaxLength(MAX_APPROVAL_TARGETS))\n .pipe(\n Schema.refine(\n (targets): targets is ReadonlyArray<string> =>\n targets.reduce((total, target) => total + utf8ByteLength(target), 0) <=\n MAX_APPROVAL_TARGET_BYTES,\n { expected: `approval targets totaling at most ${MAX_APPROVAL_TARGET_BYTES} UTF-8 bytes` },\n ),\n );\n\nconst ApprovalRequestFields = {\n requestId: Schema.NonEmptyString,\n runId: RunId,\n threadId: ThreadId,\n toolCallId: ToolCallId,\n toolName: Schema.NonEmptyString,\n actionSummary: Schema.String.check(Schema.isMaxLength(2 * 1024)),\n resourceTargets: ApprovalTargets,\n risk: Schema.Literals([\"low\", \"medium\", \"high\", \"critical\"]),\n expiresAt: Schema.DateTimeUtcFromString,\n denial: Schema.Literals([\"terminal\", \"recoverable\"]),\n} as const;\n\n/** Decoded approval metadata before the Redactor owns Tool input preview creation. */\nexport class ApprovalRequestDraft extends Schema.Class<ApprovalRequestDraft>(\n \"@effect-agent/capabilities/ApprovalRequestDraft\",\n)(ApprovalRequestFields) {}\n\n/** Fully decoded, structurally redacted approval input. */\nexport class ApprovalRequest extends Schema.Class<ApprovalRequest>(\n \"@effect-agent/capabilities/ApprovalRequest\",\n)({\n ...ApprovalRequestFields,\n redactedInputPreview: RedactedPreview,\n}) {}\n\nexport class ApprovalApproved extends Schema.TaggedClass<ApprovalApproved>()(\"ApprovalApproved\", {\n requestId: Schema.NonEmptyString,\n decidedAt: Schema.DateTimeUtcFromString,\n resolver: Schema.NonEmptyString,\n}) {}\n\nexport class ApprovalDenied extends Schema.TaggedClass<ApprovalDenied>()(\"ApprovalDenied\", {\n requestId: Schema.NonEmptyString,\n decidedAt: Schema.DateTimeUtcFromString,\n resolver: Schema.NonEmptyString,\n reason: Schema.String.check(Schema.isMaxLength(2 * 1024)),\n timedOut: Schema.Boolean,\n}) {}\n\nexport const ApprovalDecision = Schema.Union([ApprovalApproved, ApprovalDenied]);\nexport type ApprovalDecision = typeof ApprovalDecision.Type;\n\n/** Resolver infrastructure failed before it could make a policy decision. */\nexport class ApprovalResolverError extends Schema.TaggedError<ApprovalResolverError>()(\n \"ApprovalResolverError\",\n { message: Schema.String },\n) {}\n\n/** The resolver explicitly observed its request deadline; callers turn this into a denial. */\nexport class ApprovalTimedOut extends Schema.TaggedError<ApprovalTimedOut>()(\"ApprovalTimedOut\", {\n requestId: Schema.NonEmptyString,\n}) {}\n\n/** First-class approval authority. Interactive, policy, and remote adapters implement this service. */\nexport class ApprovalResolver extends Context.Service<\n ApprovalResolver,\n {\n readonly request: (\n request: ApprovalRequest,\n ) => Effect.Effect<ApprovalDecision, ApprovalResolverError | ApprovalTimedOut>;\n }\n>()(\"@effect-agent/capabilities/ApprovalResolver\") {}\n\nexport class ApprovalRequestRecorded extends Schema.TaggedClass<ApprovalRequestRecorded>()(\n \"ApprovalRequestRecorded\",\n {\n sequence: Schema.Natural,\n recordedAt: Schema.DateTimeUtcFromString,\n request: ApprovalRequest,\n },\n) {}\n\nexport class ApprovalDecisionRecorded extends Schema.TaggedClass<ApprovalDecisionRecorded>()(\n \"ApprovalDecisionRecorded\",\n {\n sequence: Schema.Natural,\n recordedAt: Schema.DateTimeUtcFromString,\n decision: ApprovalDecision,\n },\n) {}\n\nexport const ApprovalAuditEvent = Schema.Union([ApprovalRequestRecorded, ApprovalDecisionRecorded]);\nexport type ApprovalAuditEvent = typeof ApprovalAuditEvent.Type;\n\nexport const ApprovalAuditEvents = Schema.Array(ApprovalAuditEvent).check(\n Schema.isMaxLength(MAX_APPROVAL_AUDIT_EVENTS),\n);\n\nexport class ApprovalAuditLimitExceeded extends Schema.TaggedError<ApprovalAuditLimitExceeded>()(\n \"ApprovalAuditLimitExceeded\",\n {\n limitValue: Schema.Natural,\n observedValue: Schema.Natural,\n },\n) {}\n\n/** A resolver or audit sink tried to associate a decision with another request. */\nexport class ApprovalDecisionMismatch extends Schema.TaggedError<ApprovalDecisionMismatch>()(\n \"ApprovalDecisionMismatch\",\n {\n expectedRequestId: Schema.NonEmptyString,\n observedRequestId: Schema.NonEmptyString,\n },\n) {}\n\n/** P2 semantic audit sink; durable runtimes replace this with canonical records. */\nexport class ApprovalAudit extends Context.Service<\n ApprovalAudit,\n {\n readonly recordRequest: (\n request: ApprovalRequest,\n ) => Effect.Effect<void, ApprovalAuditLimitExceeded>;\n readonly recordDecision: (\n decision: ApprovalDecision,\n ) => Effect.Effect<void, ApprovalAuditLimitExceeded | ApprovalDecisionMismatch>;\n readonly events: Effect.Effect<ReadonlyArray<ApprovalAuditEvent>>;\n }\n>()(\"@effect-agent/capabilities/ApprovalAudit\") {}\n\n/** Scoped in-memory audit projection with monotonic event order. */\nexport const ApprovalAuditMemoryLive = Layer.effect(\n ApprovalAudit,\n Effect.gen(function* () {\n interface AuditState {\n readonly events: ReadonlyArray<ApprovalAuditEvent>;\n readonly pending: ReadonlySet<string>;\n }\n const state = yield* Ref.make<AuditState>({ events: [], pending: new Set() });\n\n return ApprovalAudit.of({\n recordRequest: Effect.fnUntraced(function* (request) {\n const recordedAt = DateTime.toUtc(DateTime.makeUnsafe(yield* Clock.currentTimeMillis));\n\n const error = yield* Ref.modify(state, (current) => {\n // Each accepted request atomically reserves room for its decision.\n const reservedSize = current.events.length + current.pending.size + 2;\n\n if (reservedSize > MAX_APPROVAL_AUDIT_EVENTS) {\n return [\n ApprovalAuditLimitExceeded.make({\n limitValue: MAX_APPROVAL_AUDIT_EVENTS,\n observedValue: reservedSize,\n }),\n current,\n ] as const;\n }\n\n const event = ApprovalRequestRecorded.make({\n sequence: current.events.length,\n recordedAt,\n request,\n });\n\n return [\n undefined,\n {\n events: [...current.events, event],\n pending: new Set(current.pending).add(request.requestId),\n },\n ] as const;\n });\n\n if (error !== undefined) return yield* error;\n }),\n recordDecision: Effect.fnUntraced(function* (decision) {\n const recordedAt = DateTime.toUtc(DateTime.makeUnsafe(yield* Clock.currentTimeMillis));\n\n const error = yield* Ref.modify(state, (current) => {\n if (!current.pending.has(decision.requestId)) {\n return [\n ApprovalDecisionMismatch.make({\n expectedRequestId: [...current.pending][0] ?? \"no-pending-request\",\n observedRequestId: decision.requestId,\n }),\n current,\n ] as const;\n }\n const pending = new Set(current.pending);\n\n pending.delete(decision.requestId);\n\n const event = ApprovalDecisionRecorded.make({\n sequence: current.events.length,\n recordedAt,\n decision,\n });\n\n return [\n undefined,\n {\n events: [...current.events, event],\n pending,\n },\n ] as const;\n });\n\n if (error !== undefined) return yield* error;\n }),\n events: Ref.get(state).pipe(Effect.map((current) => current.events)),\n });\n }),\n);\n\n/** Construct an ApprovalRequest only after decoded input passes the configured Redactor. */\nexport const makeApprovalRequest = Effect.fnUntraced(function* (\n draft: ApprovalRequestDraft,\n decodedToolInput: unknown,\n): Effect.fn.Return<ApprovalRequest, RedactionError, Redactor> {\n const redactor = yield* Redactor;\n const redactedInputPreview = yield* redactor.redact(decodedToolInput);\n\n return ApprovalRequest.make({\n requestId: draft.requestId,\n runId: draft.runId,\n threadId: draft.threadId,\n toolCallId: draft.toolCallId,\n toolName: draft.toolName,\n actionSummary: draft.actionSummary,\n resourceTargets: draft.resourceTargets,\n risk: draft.risk,\n expiresAt: draft.expiresAt,\n denial: draft.denial,\n redactedInputPreview,\n });\n});\n\nconst timeoutDenial = (request: ApprovalRequest, decidedAt: DateTime.Utc): ApprovalDenied =>\n ApprovalDenied.make({\n requestId: request.requestId,\n decidedAt,\n resolver: \"effect-agent.timeout-deny\",\n reason: \"Approval request expired before a decision was available\",\n timedOut: true,\n });\n\n/**\n * Resolve with fail-closed deadline semantics and record request/decision audit\n * events around every successful, denied, timed-out, or resolver-failed\n * resolution. A resolver infrastructure failure records a synthetic denial so\n * the audit reservation is released before the typed error propagates.\n */\nexport const requestApproval = Effect.fnUntraced(function* (request: ApprovalRequest) {\n const audit = yield* ApprovalAudit;\n\n yield* audit.recordRequest(request);\n const nowMillis = yield* Clock.currentTimeMillis;\n const now = DateTime.toUtc(DateTime.makeUnsafe(nowMillis));\n const remainingMillis = DateTime.toEpochMillis(request.expiresAt) - nowMillis;\n\n let decision: ApprovalDecision;\n\n if (remainingMillis <= 0) {\n decision = timeoutDenial(request, now);\n } else {\n const resolver = yield* ApprovalResolver;\n\n decision = yield* resolver.request(request).pipe(\n Effect.timeoutOrElse({\n duration: Duration.millis(remainingMillis),\n orElse: () =>\n Clock.currentTimeMillis.pipe(\n Effect.map((millis) =>\n timeoutDenial(request, DateTime.toUtc(DateTime.makeUnsafe(millis))),\n ),\n ),\n }),\n Effect.catchTag(\"ApprovalTimedOut\", () =>\n Clock.currentTimeMillis.pipe(\n Effect.map((millis) =>\n timeoutDenial(request, DateTime.toUtc(DateTime.makeUnsafe(millis))),\n ),\n ),\n ),\n Effect.tapError(() =>\n Clock.currentTimeMillis.pipe(\n Effect.flatMap((millis) =>\n audit.recordDecision(\n ApprovalDenied.make({\n requestId: request.requestId,\n decidedAt: DateTime.toUtc(DateTime.makeUnsafe(millis)),\n resolver: \"effect-agent.resolver-error\",\n reason: \"Approval resolver failed before making a policy decision\",\n timedOut: false,\n }),\n ),\n ),\n ),\n ),\n );\n }\n if (decision.requestId !== request.requestId) {\n const mismatch = ApprovalDecisionMismatch.make({\n expectedRequestId: request.requestId,\n observedRequestId: decision.requestId,\n });\n\n const denied = ApprovalDenied.make({\n requestId: request.requestId,\n decidedAt: DateTime.toUtc(DateTime.makeUnsafe(yield* Clock.currentTimeMillis)),\n resolver: \"effect-agent.correlation-check\",\n reason: \"Approval resolver returned a decision for another request\",\n timedOut: false,\n });\n\n yield* audit.recordDecision(denied);\n\n return yield* mismatch;\n }\n yield* audit.recordDecision(decision);\n\n return decision;\n});\n\n/** Deterministic policy layer for tests and deny-by-default deployments. */\nexport const ApprovalDenyAll = Layer.succeed(ApprovalResolver)({\n request: (request) =>\n Clock.currentTimeMillis.pipe(\n Effect.map((millis) =>\n ApprovalDenied.make({\n requestId: request.requestId,\n decidedAt: DateTime.toUtc(DateTime.makeUnsafe(millis)),\n resolver: \"effect-agent.deny-all\",\n reason: \"No approving policy is configured\",\n timedOut: false,\n }),\n ),\n ),\n});\n"],"mappings":"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"}