@yielded/agent 0.1.0-beta.173 → 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-B943ebI_.d.mts → MessageDelivery-BGDm-c46.d.mts} +42 -42
  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-DpHxjBrA.d.mts → ThreadImport-CMgzttvr.d.mts} +5 -5
  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
@@ -105,6 +105,11 @@ export const toolReplayContracts = Effect.fnUntraced(function* (
105
105
  // different host Crypto service must never inherit another host's digest map.
106
106
  const crypto = Option.getOrUndefined(yield* Effect.serviceOption(Crypto.Crypto));
107
107
 
108
+ const invalidContracts = () =>
109
+ DigestError.make({
110
+ message: "Operation contracts require serializable codecs and a version for every Tool",
111
+ });
112
+
108
113
  const prepared = yield* Effect.try({
109
114
  try: () => {
110
115
  const tools = Object.values(definition.toolkit.tools);
@@ -146,16 +151,38 @@ export const toolReplayContracts = Effect.fnUntraced(function* (
146
151
  return projection;
147
152
  };
148
153
 
149
- const declarations = tools.map((tool) => {
150
- const version = versions === undefined ? fallbackVersion : versions.tools[tool.name];
154
+ return {
155
+ _tag: "Compile" as const,
156
+ jsonSchema,
157
+ cacheable,
158
+ tools,
159
+ completionTool,
160
+ completionFromTools,
161
+ };
162
+ },
163
+ catch: () =>
164
+ DigestError.make({
165
+ message: "Operation contracts require serializable codecs and a version for every Tool",
166
+ }),
167
+ });
168
+
169
+ if (prepared._tag === "Cached") return prepared.contracts;
151
170
 
152
- if (
153
- version === undefined ||
154
- (versions !== undefined && !Object.hasOwn(versions.tools, tool.name))
155
- )
156
- throw new Error("Every Tool needs an explicit replay semantic version");
171
+ const declarations = yield* Effect.forEach(
172
+ prepared.tools,
173
+ Effect.fnUntraced(function* (tool) {
174
+ const { version, present } = yield* Effect.try({
175
+ try: () => ({
176
+ version: versions === undefined ? fallbackVersion : versions.tools[tool.name],
177
+ present: versions === undefined || Object.hasOwn(versions.tools, tool.name),
178
+ }),
179
+ catch: invalidContracts,
180
+ });
157
181
 
158
- return {
182
+ if (version === undefined || !present) return yield* invalidContracts();
183
+
184
+ return yield* Effect.try({
185
+ try: () => ({
159
186
  name: tool.name,
160
187
  contract: {
161
188
  version,
@@ -170,9 +197,9 @@ export const toolReplayContracts = Effect.fnUntraced(function* (
170
197
  readonly: Context.get(tool.annotations, Tool.Readonly),
171
198
  }
172
199
  : {}),
173
- parameters: jsonSchema(tool.parametersSchema),
174
- success: jsonSchema(tool.successSchema),
175
- failure: jsonSchema(tool.failureSchema),
200
+ parameters: prepared.jsonSchema(tool.parametersSchema),
201
+ success: prepared.jsonSchema(tool.successSchema),
202
+ failure: prepared.jsonSchema(tool.failureSchema),
176
203
  failureMode: tool.failureMode,
177
204
  needsApproval:
178
205
  typeof tool.needsApproval === "function" ? "dynamic" : (tool.needsApproval ?? false),
@@ -185,28 +212,14 @@ export const toolReplayContracts = Effect.fnUntraced(function* (
185
212
  (declaration) => declaration.tool === tool.name,
186
213
  ) ?? false,
187
214
  },
188
- };
215
+ }),
216
+ catch: invalidContracts,
189
217
  });
190
-
191
- return {
192
- _tag: "Compile" as const,
193
- declarations,
194
- cacheable,
195
- tools,
196
- completionTool,
197
- completionFromTools,
198
- };
199
- },
200
- catch: () =>
201
- DigestError.make({
202
- message: "Operation contracts require serializable codecs and a version for every Tool",
203
- }),
204
- });
205
-
206
- if (prepared._tag === "Cached") return prepared.contracts;
218
+ }),
219
+ );
207
220
 
208
221
  const contracts = Object.fromEntries(
209
- yield* Effect.forEach(prepared.declarations, ({ name, contract }) =>
222
+ yield* Effect.forEach(declarations, ({ name, contract }) =>
210
223
  digestJson(contract).pipe(Effect.map((digest) => [name, digest] as const)),
211
224
  ),
212
225
  );
@@ -365,7 +378,7 @@ const omitTraceContext = Context.omit(
365
378
  const withoutTraceContext = <R>(context: Context.Context<R>): Context.Context<R> =>
366
379
  omitTraceContext(context) as Context.Context<R>;
367
380
 
368
- const captureReporting = <R>(reports: ReadonlyArray<WorkerReporting<unknown, R>>) =>
381
+ const captureReporting = <E, R>(reports: ReadonlyArray<WorkerReporting<E, R>>) =>
369
382
  Effect.map(
370
383
  Effect.context<Exclude<R, Scope.Scope>>().pipe(Effect.map(withoutTraceContext)),
371
384
  (context) =>
@@ -405,18 +418,19 @@ export interface AgentAttemptContext {
405
418
  readonly attemptId: Claim["attemptId"];
406
419
  }
407
420
 
408
- const capture = <A extends ExecutableAgentBinding, Provides = never, Requires = never>(
421
+ const capture = <A extends ExecutableAgentBinding, Requires>(
409
422
  agent: A,
410
- attemptLayer?: (context: AgentAttemptContext) => Layer.Layer<Provides, never, Requires>,
411
- ): Effect.Effect<
412
- CapturedBinding,
413
- never,
414
- Exclude<DurableWorkerRequirements<A>, Provides> | Requires
415
- > =>
423
+ prepare: (
424
+ execute: ReturnType<CapturedAttempt<A>>,
425
+ context: AgentAttemptContext,
426
+ ) => Effect.Effect<
427
+ Option.Option<Settlement>,
428
+ DurableWorkerFailure | DurableBindingFailure,
429
+ Requires
430
+ >,
431
+ ): Effect.Effect<CapturedBinding, never, Requires> =>
416
432
  Effect.map(
417
- Effect.context<Exclude<DurableWorkerRequirements<A>, Provides> | Requires>().pipe(
418
- Effect.map(withoutTraceContext),
419
- ),
433
+ Effect.context<Requires>().pipe(Effect.map(withoutTraceContext)),
420
434
  (context): CapturedBinding => ({
421
435
  agentId: agent.definition.id,
422
436
  definition: agent.definition,
@@ -433,29 +447,23 @@ const capture = <A extends ExecutableAgentBinding, Provides = never, Requires =
433
447
  claim.attemptId,
434
448
  );
435
449
 
436
- const scoped =
437
- attemptLayer === undefined
438
- ? execute
439
- : execute.pipe(
440
- Effect.provide(
441
- Layer.fresh(
442
- attemptLayer({
443
- threadId,
444
- submissionId: claim.submissionId,
445
- attemptId: claim.attemptId,
446
- }),
447
- ),
448
- ),
449
- );
450
-
451
- return scoped.pipe(Effect.provide(context)) as Effect.Effect<
452
- Option.Option<Settlement>,
453
- DurableWorkerFailure | DurableBindingFailure
454
- >;
450
+ return prepare(execute, {
451
+ threadId,
452
+ submissionId: claim.submissionId,
453
+ attemptId: claim.attemptId,
454
+ }).pipe(Effect.provide(context));
455
455
  },
456
456
  }),
457
457
  );
458
458
 
459
+ const captureWithAttemptLayer = <A extends ExecutableAgentBinding, Provides, Requires>(
460
+ agent: A,
461
+ attemptLayer: (context: AgentAttemptContext) => Layer.Layer<Provides, never, Requires>,
462
+ ) =>
463
+ capture(agent, (execute, context) =>
464
+ execute.pipe(Effect.provide(Layer.fresh(attemptLayer(context)))),
465
+ );
466
+
459
467
  /**
460
468
  * Build one exact worker registration from an executable Agent Binding and
461
469
  * its already-computed definition digests.
@@ -471,7 +479,7 @@ export const DurableWorkerBinding = {
471
479
  digests: DefinitionDigests,
472
480
  ): Effect.Effect<ResolvedBinding, never, DurableWorkerRequirements<A>> =>
473
481
  Effect.gen(function* () {
474
- const binding = yield* capture(agent);
482
+ const binding = yield* capture(agent, (execute) => execute);
475
483
  const reporting = yield* captureReporting(backgroundReports(agent.definition));
476
484
 
477
485
  return { ...binding, digests, reporting };
@@ -479,7 +487,8 @@ export const DurableWorkerBinding = {
479
487
  } as const;
480
488
 
481
489
  /** INTERNAL identity-only capture retained for the legacy direct worker path. */
482
- export const makeLegacyWorkerBinding = capture;
490
+ export const makeLegacyWorkerBinding = <A extends ExecutableAgentBinding>(agent: A) =>
491
+ capture(agent, (execute) => execute);
483
492
 
484
493
  export const resolveWorkerBinding = Effect.fnUntraced(function* (
485
494
  bindings: ReadonlyArray<ResolvedBinding>,
@@ -576,11 +585,9 @@ type EntryRequirements<Entry> = Entry extends unknown
576
585
  >
577
586
  : never;
578
587
 
579
- type RegistrationRequirements<Entries extends ReadonlyArray<AgentRegistration>> = [
580
- Entries[number],
581
- ] extends [never]
582
- ? never
583
- : EntryRequirements<Entries[number]>;
588
+ type RegistrationRequirements<Entries extends ReadonlyArray<AgentRegistration>> = EntryRequirements<
589
+ Entries[number]
590
+ >;
584
591
 
585
592
  const registrationDefinitions = (entry: AgentRegistration): DefinitionDigestInput => {
586
593
  const definition = entry.model === undefined ? entry.agent.definition : entry.agent;
@@ -655,10 +662,13 @@ const registrationDefinitions = (entry: AgentRegistration): DefinitionDigestInpu
655
662
  };
656
663
  };
657
664
 
658
- const compileRegistration = <Entry extends AgentRegistration>(
665
+ // The public signature distributes over descriptors, including optional attempt Layers.
666
+ // The implementation consumes their erased union and captures the selected Layer's context.
667
+ function compileRegistration<Entry extends AgentRegistration>(
659
668
  entry: Entry,
660
- ): Effect.Effect<ResolvedBinding, DigestError, Crypto.Crypto | EntryRequirements<Entry>> =>
661
- Effect.flatMap(
669
+ ): Effect.Effect<ResolvedBinding, DigestError, Crypto.Crypto | EntryRequirements<Entry>>;
670
+ function compileRegistration(entry: AgentRegistration) {
671
+ return Effect.flatMap(
662
672
  Effect.try({
663
673
  try: () => registrationDefinitions(entry),
664
674
  catch: () =>
@@ -666,10 +676,19 @@ const compileRegistration = <Entry extends AgentRegistration>(
666
676
  }),
667
677
  (definitions) =>
668
678
  Effect.gen(function* () {
669
- const binding = yield* capture(
670
- entry.model === undefined ? entry.agent : { definition: entry.agent, model: entry.model },
671
- entry.attemptLayer,
672
- );
679
+ const agent =
680
+ // The heterogeneous descriptor erases model services; the overload retains EntryRequirements.
681
+ // @effect-diagnostics-next-line anyUnknownInErrorContext:off
682
+ entry.model === undefined ? entry.agent : { definition: entry.agent, model: entry.model };
683
+
684
+ // Omitted attempt services need no Layer construction or provisioning scope.
685
+ const binding = yield* entry.attemptLayer === undefined
686
+ ? // Capture closes the erased requirements over the registration's actual Context.
687
+ // @effect-diagnostics-next-line anyUnknownInErrorContext:off
688
+ capture(agent, (execute) => execute)
689
+ : // The selected Layer discharges its services before the remaining Context is captured.
690
+ // @effect-diagnostics-next-line anyUnknownInErrorContext:off
691
+ captureWithAttemptLayer(agent, entry.attemptLayer);
673
692
 
674
693
  const reporting = yield* captureReporting(backgroundReports(binding.definition));
675
694
 
@@ -683,9 +702,8 @@ const compileRegistration = <Entry extends AgentRegistration>(
683
702
  reporting,
684
703
  };
685
704
  }),
686
- // The erased descriptor accepts arbitrary provided services. Restore the concrete entry's
687
- // Exclude<worker requirements, provided services> | layer requirements at this collection seam.
688
- ) as Effect.Effect<ResolvedBinding, DigestError, Crypto.Crypto | EntryRequirements<Entry>>;
705
+ );
706
+ }
689
707
 
690
708
  /** Compile heterogeneous Agent descriptors into exact, dependency-closed worker registrations. */
691
709
  export const compileRegistrations = <const Entries extends ReadonlyArray<AgentRegistration>>(
@@ -695,16 +713,5 @@ export const compileRegistrations = <const Entries extends ReadonlyArray<AgentRe
695
713
  DigestError,
696
714
  Crypto.Crypto | RegistrationRequirements<Entries>
697
715
  > => {
698
- // `Effect.forEach` instantiates a generic callback at its constraint. Specialize the callback to
699
- // this tuple's distributed requirement union before collection so empty and heterogeneous tuples
700
- // retain their exact service requirements.
701
- const compileEntry = compileRegistration as unknown as (
702
- entry: Entries[number],
703
- ) => Effect.Effect<
704
- ResolvedBinding,
705
- DigestError,
706
- Crypto.Crypto | RegistrationRequirements<Entries>
707
- >;
708
-
709
- return Effect.forEach(entries, compileEntry);
716
+ return Effect.forEach(entries, compileRegistration<Entries[number]>);
710
717
  };
@@ -1,4 +1,4 @@
1
- import { Array, type Schema } from "effect";
1
+ import { Array, Predicate, Result, Schema } from "effect";
2
2
 
3
3
  interface JsonLimits {
4
4
  readonly depth: number;
@@ -7,19 +7,36 @@ interface JsonLimits {
7
7
  readonly textUnits: number;
8
8
  }
9
9
 
10
+ export class CanonicalJsonLimitError extends Schema.TaggedError<CanonicalJsonLimitError>()(
11
+ "CanonicalJsonLimitError",
12
+ { message: Schema.String },
13
+ ) {}
14
+
15
+ // Only this codec's private synchronous aborts become typed bounds failures.
16
+ const boundsFailures = new WeakMap<object, string>();
17
+
18
+ const exceeded = (bound: "text" | "traversal" | "collection"): never => {
19
+ const message = `Canonical JSON exceeds its ${bound} bound`;
20
+ // oxlint-disable-next-line effect/no-native-error -- Private synchronous codec abort; the Result boundary translates only errors owned here.
21
+ const error = new RangeError(message);
22
+
23
+ boundsFailures.set(error, message);
24
+ // oxlint-disable-next-line effect/no-untyped-throw -- Abort synchronous JSON traversal at the first exceeded bound; the Result boundary catches this owned error.
25
+ throw error;
26
+ };
27
+
10
28
  /** Values have already crossed their Schema boundary; visit each serialized occurrence. */
11
- export const canonicalJson = (value: Schema.Json, limits?: JsonLimits): string => {
29
+ const serialize = (value: Schema.Json, limits?: JsonLimits): string => {
12
30
  let nodes = 0;
13
31
  let textUnits = 0;
14
32
 
15
33
  const charge = (length: number) => {
16
- if (limits !== undefined && (textUnits += length) > limits.textUnits)
17
- throw new RangeError("Canonical JSON exceeds its text bound");
34
+ if (limits !== undefined && (textUnits += length) > limits.textUnits) return exceeded("text");
18
35
  };
19
36
 
20
37
  const visit = (value: Schema.Json, depth: number): string => {
21
38
  if (limits !== undefined && (depth > limits.depth || ++nodes > limits.nodes))
22
- throw new RangeError("Canonical JSON exceeds its traversal bound");
39
+ return exceeded("traversal");
23
40
  if (
24
41
  value === null ||
25
42
  typeof value === "boolean" ||
@@ -34,30 +51,54 @@ export const canonicalJson = (value: Schema.Json, limits?: JsonLimits): string =
34
51
  }
35
52
  if (Array.isArray<Schema.Json>(value)) {
36
53
  if (limits !== undefined && value.length > limits.collectionLength)
37
- throw new RangeError("Canonical JSON exceeds its collection bound");
54
+ return exceeded("collection");
38
55
  charge(2 + Math.max(0, value.length - 1));
39
56
 
40
- return `[${globalThis.Array.from(value, (entry) => visit(entry, depth + 1)).join(",")}]`;
57
+ let json = "[";
58
+
59
+ for (let index = 0; index < value.length; index++) {
60
+ if (index > 0) json += ",";
61
+ json += visit(value[index], depth + 1);
62
+ }
63
+
64
+ return `${json}]`;
41
65
  }
42
66
 
43
- const entries = Object.entries(value).sort(([left], [right]) =>
44
- left < right ? -1 : left > right ? 1 : 0,
45
- );
67
+ const keys = Object.keys(value).sort();
46
68
 
47
- if (limits !== undefined && entries.length > limits.collectionLength)
48
- throw new RangeError("Canonical JSON exceeds its collection bound");
49
- charge(2 + Math.max(0, entries.length - 1));
69
+ if (limits !== undefined && keys.length > limits.collectionLength)
70
+ return exceeded("collection");
71
+ charge(2 + Math.max(0, keys.length - 1));
72
+ let json = "{";
50
73
 
51
- return `{${entries
52
- .map(([key, entry]) => {
53
- const encodedKey = JSON.stringify(key);
74
+ for (let index = 0; index < keys.length; index++) {
75
+ const key = keys[index];
76
+ const encodedKey = JSON.stringify(key);
54
77
 
55
- charge(encodedKey.length + 1);
78
+ charge(encodedKey.length + 1);
79
+ if (index > 0) json += ",";
80
+ json += `${encodedKey}:${visit(value[key], depth + 1)}`;
81
+ }
56
82
 
57
- return `${encodedKey}:${visit(entry, depth + 1)}`;
58
- })
59
- .join(",")}}`;
83
+ return `${json}}`;
60
84
  };
61
85
 
62
86
  return visit(value, 0);
63
87
  };
88
+
89
+ export const canonicalJson = (value: Schema.Json): string => serialize(value);
90
+
91
+ export const boundedCanonicalJson = (
92
+ value: Schema.Json,
93
+ limits: JsonLimits,
94
+ ): Result.Result<string, CanonicalJsonLimitError> => {
95
+ try {
96
+ return Result.succeed(serialize(value, limits));
97
+ } catch (cause) {
98
+ const message = Predicate.isObjectKeyword(cause) ? boundsFailures.get(cause) : undefined;
99
+
100
+ if (message !== undefined) return Result.fail(CanonicalJsonLimitError.make({ message }));
101
+ // oxlint-disable-next-line effect/no-untyped-throw -- Foreign JSON/getter errors retain their identity for the caller's typed capture boundary.
102
+ throw cause;
103
+ }
104
+ };
@@ -1,4 +1,4 @@
1
- import { Effect, Option, Schema, Stream } from "effect";
1
+ import { Effect, Option, Result, Schema, Stream } from "effect";
2
2
  import { Prompt } from "effect/ai";
3
3
 
4
4
  import type { RunId, ThreadId } from "../../core/Identifiers.ts";
@@ -87,7 +87,8 @@ function hydratePart(part: Prompt.PartEncoded): Prompt.Part {
87
87
  case "tool-approval-response":
88
88
  return Prompt.toolApprovalResponsePart(part);
89
89
  }
90
- throw new Error(`Unhandled Prompt part: ${part satisfies never}`);
90
+
91
+ return part satisfies never;
91
92
  }
92
93
 
93
94
  const hydrateMessage = (message: Prompt.MessageEncoded): Prompt.Message => {
@@ -116,7 +117,8 @@ const hydrateMessage = (message: Prompt.MessageEncoded): Prompt.Message => {
116
117
  content: message.content.map((p) => hydratePart(p)),
117
118
  });
118
119
  }
119
- throw new Error(`Unhandled Prompt message: ${message satisfies never}`);
120
+
121
+ return message satisfies never;
120
122
  };
121
123
 
122
124
  export interface PromptHistory {
@@ -291,7 +293,14 @@ export const makeCommittedPromptSuffix = (original: CanonicalRecordEnvelope) =>
291
293
  // as readPrompt, never raw provider values. Failure invalidates this derivative, not the commit.
292
294
  try {
293
295
  for (const fact of facts) {
294
- const owned = captureRecord(fact);
296
+ const captured = captureRecord(fact);
297
+
298
+ if (Result.isFailure(captured)) {
299
+ discard();
300
+
301
+ return;
302
+ }
303
+ const owned = captured.success;
295
304
  const payload = owned.canonical.payload;
296
305
 
297
306
  if (