@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
@@ -1544,6 +1544,7 @@ export function layer<
1544
1544
  };
1545
1545
 
1546
1546
  if (childBinding.definition !== delegation.target) {
1547
+ // oxlint-disable-next-line effect/no-untyped-throw, effect/no-native-error -- Subagent.layer synchronously requires the exact declared target before constructing its Layer.
1547
1548
  throw new Error("Subagent.layer requires the delegation's exact target Definition");
1548
1549
  }
1549
1550
 
@@ -2304,41 +2305,27 @@ export function layer<
2304
2305
  ): SubagentToolFailure<Failure>["Type"] =>
2305
2306
  failure instanceof GenuineEngineSignal ? failure.signal : failure;
2306
2307
 
2307
- const handlerImpl = (
2308
+ const handlerImpl = Effect.fnUntraced(function* (
2308
2309
  parameters: Parameters["Type"],
2309
2310
  handlerContext: Toolkit.HandlerContext<
2310
2311
  SubagentTool<Name, Parameters, Success, Failure, Mode>
2311
2312
  >,
2312
- ) =>
2313
- Effect.gen(function* () {
2314
- // Resolve the engine-provided per-call services before providing the
2315
- // captured construction context and re-provide them innermost: if the
2316
- // Layer was constructed inside another Run's Tool batch, the captured
2317
- // context would otherwise shadow this Run's `AgentSpawner` (and its
2318
- // delegation depth), this batch's live `RunEventSink`, and this
2319
- // batch's live `SubagentDurability` mode.
2320
- const spawner = yield* AgentSpawner;
2321
- const sink = yield* RunEventSink;
2322
- const durability = yield* SubagentDurability;
2323
-
2324
- // Service-mode dispatch (S2 plan §2): the engine states ephemeral
2325
- // mode explicitly when no durable coordinator supplied the hook, so
2326
- // absence keeps the S1 in-process spawn semantics honestly.
2327
- if (durability.mode === "durable") {
2328
- const durable = invokeDurable(parameters, handlerContext, durability).pipe(
2329
- Effect.scoped,
2330
- Effect.provideService(AgentSpawner, spawner),
2331
- Effect.provideService(RunEventSink, sink),
2332
- Effect.provideService(SubagentDurability, durability),
2333
- Effect.provide(captured),
2334
- );
2335
-
2336
- return yield* contained
2337
- ? durable.pipe(Effect.catch(containSignals))
2338
- : durable.pipe(Effect.mapError(unwrapSignals));
2339
- }
2313
+ ) {
2314
+ // Resolve the engine-provided per-call services before providing the
2315
+ // captured construction context and re-provide them innermost: if the
2316
+ // Layer was constructed inside another Run's Tool batch, the captured
2317
+ // context would otherwise shadow this Run's `AgentSpawner` (and its
2318
+ // delegation depth), this batch's live `RunEventSink`, and this
2319
+ // batch's live `SubagentDurability` mode.
2320
+ const spawner = yield* AgentSpawner;
2321
+ const sink = yield* RunEventSink;
2322
+ const durability = yield* SubagentDurability;
2340
2323
 
2341
- const ephemeral = invoke(parameters, handlerContext).pipe(
2324
+ // Service-mode dispatch (S2 plan §2): the engine states ephemeral
2325
+ // mode explicitly when no durable coordinator supplied the hook, so
2326
+ // absence keeps the S1 in-process spawn semantics honestly.
2327
+ if (durability.mode === "durable") {
2328
+ const durable = invokeDurable(parameters, handlerContext, durability).pipe(
2342
2329
  Effect.scoped,
2343
2330
  Effect.provideService(AgentSpawner, spawner),
2344
2331
  Effect.provideService(RunEventSink, sink),
@@ -2347,9 +2334,22 @@ export function layer<
2347
2334
  );
2348
2335
 
2349
2336
  return yield* contained
2350
- ? ephemeral.pipe(Effect.catch(containSignals))
2351
- : ephemeral.pipe(Effect.mapError(unwrapSignals));
2352
- });
2337
+ ? durable.pipe(Effect.catch(containSignals))
2338
+ : durable.pipe(Effect.mapError(unwrapSignals));
2339
+ }
2340
+
2341
+ const ephemeral = invoke(parameters, handlerContext).pipe(
2342
+ Effect.scoped,
2343
+ Effect.provideService(AgentSpawner, spawner),
2344
+ Effect.provideService(RunEventSink, sink),
2345
+ Effect.provideService(SubagentDurability, durability),
2346
+ Effect.provide(captured),
2347
+ );
2348
+
2349
+ return yield* contained
2350
+ ? ephemeral.pipe(Effect.catch(containSignals))
2351
+ : ephemeral.pipe(Effect.mapError(unwrapSignals));
2352
+ });
2353
2353
 
2354
2354
  // `handlerImpl`'s channels are the UNION of both modes because
2355
2355
  // `contained` is a runtime branch TypeScript cannot relate to the
@@ -327,6 +327,14 @@ type TransitionResult<A, E> =
327
327
  const ok = <A>(value: A): TransitionResult<A, never> => ({ _tag: "ok", value });
328
328
  const fail = <E>(error: E): TransitionResult<never, E> => ({ _tag: "error", error });
329
329
 
330
+ /** Corrupt internal accounting is a defect, never an expected reservation failure. */
331
+ class ReservationLedgerCorrupt extends Schema.TaggedError<ReservationLedgerCorrupt>()(
332
+ "ReservationLedgerCorrupt",
333
+ {
334
+ message: Schema.String,
335
+ },
336
+ ) {}
337
+
330
338
  const resolve = <A, E>(result: TransitionResult<A, E>): Effect.Effect<A, E> => {
331
339
  switch (result._tag) {
332
340
  case "ok":
@@ -334,7 +342,7 @@ const resolve = <A, E>(result: TransitionResult<A, E>): Effect.Effect<A, E> => {
334
342
  case "error":
335
343
  return Effect.fail(result.error);
336
344
  case "corrupt":
337
- return Effect.die(new Error(result.message));
345
+ return Effect.die(ReservationLedgerCorrupt.make({ message: result.message }));
338
346
  }
339
347
  };
340
348
 
@@ -246,6 +246,7 @@ const HOST_PATTERN = /^(\*\.)?[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]
246
246
 
247
247
  const compileUrlPolicy = (patterns: ReadonlyArray<string>): ReadonlyArray<string> => {
248
248
  if (patterns.length === 0) {
249
+ // oxlint-disable-next-line effect/no-untyped-throw, effect/no-native-error -- WebCapture constructors synchronously require an explicit host allowlist.
249
250
  throw new Error(
250
251
  "Web capture requires at least one allowed host pattern; capture is deny-by-default",
251
252
  );
@@ -256,6 +257,7 @@ const compileUrlPolicy = (patterns: ReadonlyArray<string>): ReadonlyArray<string
256
257
  const pattern = raw.trim().toLowerCase();
257
258
 
258
259
  if (!HOST_PATTERN.test(pattern)) {
260
+ // oxlint-disable-next-line effect/no-untyped-throw, effect/no-native-error -- WebCapture constructors synchronously reject malformed host allowlist patterns.
259
261
  throw new Error(
260
262
  `Web capture host pattern ${JSON.stringify(raw)} must be a bare host name such as docs.example.com or *.example.com — no scheme, path, port, or credentials`,
261
263
  );
@@ -282,6 +284,7 @@ const validateMaxResponseBytes = (value: number | undefined): number => {
282
284
 
283
285
  // Fail closed on an invalid budget: NaN would make every comparison false.
284
286
  if (!Number.isSafeInteger(bytes) || bytes < 1_024 || bytes > 1024 * 1024) {
287
+ // oxlint-disable-next-line effect/no-untyped-throw, effect/no-native-error -- WebCapture constructors synchronously reject invalid response-size bounds.
285
288
  throw new Error(
286
289
  `Web capture maxResponseBytes must be an integer between 1024 and ${1024 * 1024}; received ${String(value)}`,
287
290
  );
@@ -396,6 +399,7 @@ const make = <const Name extends string>(
396
399
  const actions = Object.freeze([...new Set(options.actions ?? allActions)]);
397
400
 
398
401
  if (actions.length === 0) {
402
+ // oxlint-disable-next-line effect/no-untyped-throw, effect/no-native-error -- WebCapture.make synchronously requires at least one model-selectable action.
399
403
  throw new Error("Web capture requires at least one model-selectable action");
400
404
  }
401
405
 
@@ -519,6 +523,7 @@ const makeExtract = <const Name extends string, S extends Schema.Top>(
519
523
  const prompt = options.prompt;
520
524
 
521
525
  if (prompt !== undefined && (prompt.length === 0 || prompt.length > 8_192)) {
526
+ // oxlint-disable-next-line effect/no-untyped-throw, effect/no-native-error -- WebCapture.extract synchronously validates its fixed extraction prompt length.
522
527
  throw new Error("Web capture extraction prompt must be between 1 and 8192 characters");
523
528
  }
524
529
 
@@ -530,6 +535,7 @@ const makeExtract = <const Name extends string, S extends Schema.Top>(
530
535
  const decoded = Schema.decodeUnknownOption(PageCaptureResponseFormat)(jsonSchema);
531
536
 
532
537
  if (Option.isNone(decoded)) {
538
+ // oxlint-disable-next-line effect/no-untyped-throw, effect/no-native-error -- WebCapture.extract synchronously requires a bounded object response schema.
533
539
  throw new Error(
534
540
  `Web capture cannot derive a bounded object JSON response format from the extraction Schema for ${name}`,
535
541
  );
@@ -89,6 +89,7 @@ export const native = <T extends Tool.AnyProviderDefined>(options: Pick<Options<
89
89
  options.tool.requiresHandler ||
90
90
  !["web_search", "web_search_preview"].includes(options.tool.providerName)
91
91
  ) {
92
+ // oxlint-disable-next-line effect/no-untyped-throw, effect/no-native-error -- WebSearch.native synchronously requires a provider-executed search Tool.
92
93
  throw new Error("WebSearch.native requires a provider-executed web_search tool");
93
94
  }
94
95
 
@@ -97,6 +98,7 @@ export const native = <T extends Tool.AnyProviderDefined>(options: Pick<Options<
97
98
 
98
99
  const boundedInteger = (name: string, value: number, maximum: number): number => {
99
100
  if (!Number.isSafeInteger(value) || value < 1 || value > maximum) {
101
+ // oxlint-disable-next-line effect/no-untyped-throw, effect/no-native-error -- WebSearch.layer synchronously validates request and response bounds before creating its Layer.
100
102
  throw new Error(`WebSearch ${name} must be an integer between 1 and ${maximum}`);
101
103
  }
102
104
 
@@ -117,6 +119,7 @@ export const layer = <T extends Tool.AnyProviderDefined>(options: Options<T>) =>
117
119
  !Tool.isProviderDefined(options.tool) ||
118
120
  !["web_search", "web_search_preview"].includes(options.tool.providerName)
119
121
  ) {
122
+ // oxlint-disable-next-line effect/no-untyped-throw, effect/no-native-error -- WebSearch.layer synchronously requires a provider-defined search Tool.
120
123
  throw new Error("WebSearch requires a native provider-defined web_search tool");
121
124
  }
122
125
  const searchTool = options.tool;
@@ -150,14 +153,14 @@ export const layer = <T extends Tool.AnyProviderDefined>(options: Options<T>) =>
150
153
  return {
151
154
  WebSearch: Effect.fnUntraced(function* (input) {
152
155
  const { query } = yield* Schema.decodeEffect(Parameters)(input).pipe(
153
- Effect.mapError(() => new Failure({ reason: "invalid-query" })),
156
+ Effect.mapError(() => Failure.make({ reason: "invalid-query" })),
154
157
  );
155
158
 
156
159
  const response = yield* generateWithContext(query).pipe(
157
- Effect.mapError(() => new Failure({ reason: "provider" })),
160
+ Effect.mapError(() => Failure.make({ reason: "provider" })),
158
161
  Effect.timeoutOrElse({
159
162
  duration: timeoutMillis,
160
- orElse: () => Effect.fail(new Failure({ reason: "timeout" })),
163
+ orElse: () => Effect.fail(Failure.make({ reason: "timeout" })),
161
164
  }),
162
165
  );
163
166
 
@@ -170,10 +173,10 @@ export const layer = <T extends Tool.AnyProviderDefined>(options: Options<T>) =>
170
173
  );
171
174
  })
172
175
  ) {
173
- return yield* new Failure({ reason: "provider" });
176
+ return yield* Failure.make({ reason: "provider" });
174
177
  }
175
178
  if (!response.toolResults.some((result) => result.name === searchTool.name)) {
176
- return yield* new Failure({ reason: "search-not-executed" });
179
+ return yield* Failure.make({ reason: "search-not-executed" });
177
180
  }
178
181
 
179
182
  const sources = response.content.flatMap((part) =>
@@ -192,11 +195,11 @@ export const layer = <T extends Tool.AnyProviderDefined>(options: Options<T>) =>
192
195
  };
193
196
 
194
197
  if (utf8ByteLength(JSON.stringify(result)) > maxOutputBytes) {
195
- return yield* new Failure({ reason: "output-limit" });
198
+ return yield* Failure.make({ reason: "output-limit" });
196
199
  }
197
200
 
198
201
  return yield* Schema.decodeEffect(Result)(result).pipe(
199
- Effect.mapError(() => new Failure({ reason: "invalid-response" })),
202
+ Effect.mapError(() => Failure.make({ reason: "invalid-response" })),
200
203
  );
201
204
  }),
202
205
  };
@@ -304,48 +304,47 @@ const operations = <
304
304
  encodedGrant,
305
305
  ...(options.continuationOf === undefined ? {} : { continuationOf: options.continuationOf }),
306
306
  ...(options.budgetScope === undefined ? {} : { budgetScope: options.budgetScope }),
307
- prepare: (budgetScope) =>
308
- Effect.gen(function* () {
309
- const encodedInput = yield* prepare(parameters, caller);
310
-
311
- const effectiveTarget = yield* service.resolveTargetPolicy({
312
- target: declaration.target,
313
- encodedInput,
314
- ...(options.continuationOf === undefined
307
+ prepare: Effect.fnUntraced(function* (budgetScope) {
308
+ const encodedInput = yield* prepare(parameters, caller);
309
+
310
+ const effectiveTarget = yield* service.resolveTargetPolicy({
311
+ target: declaration.target,
312
+ encodedInput,
313
+ ...(options.continuationOf === undefined
314
+ ? {}
315
+ : { continuationOf: options.continuationOf }),
316
+ });
317
+
318
+ const resolvedTarget = Option.getOrUndefined(effectiveTarget);
319
+
320
+ const resolved = resolveSubagentPolicy(
321
+ declaration,
322
+ budgetScope === "worker-run"
323
+ ? (resolvedTarget ?? declaration.target.policy)
324
+ : caller.policy,
325
+ undefined,
326
+ budgetScope === "worker-run" ? "root-attached" : "conserved",
327
+ resolvedTarget,
328
+ );
329
+
330
+ return {
331
+ encodedInput,
332
+ policy: resolved.childPolicy,
333
+ budget: SubagentBudgetReservation.make({
334
+ caps: resolved.caps,
335
+ allocation: resolved.allocation,
336
+ ...(resolved.policy.descendantInvocations === undefined
315
337
  ? {}
316
- : { continuationOf: options.continuationOf }),
317
- });
318
-
319
- const resolvedTarget = Option.getOrUndefined(effectiveTarget);
320
-
321
- const resolved = resolveSubagentPolicy(
322
- declaration,
323
- budgetScope === "worker-run"
324
- ? (resolvedTarget ?? declaration.target.policy)
325
- : caller.policy,
326
- undefined,
327
- budgetScope === "worker-run" ? "root-attached" : "conserved",
328
- resolvedTarget,
329
- );
330
-
331
- return {
332
- encodedInput,
333
- policy: resolved.childPolicy,
334
- budget: SubagentBudgetReservation.make({
335
- caps: resolved.caps,
336
- allocation: resolved.allocation,
337
- ...(resolved.policy.descendantInvocations === undefined
338
- ? {}
339
- : { descendantInvocations: resolved.policy.descendantInvocations }),
340
- }),
341
- toolCallAllowance: resolveToolCallAllowance(
342
- declaration.toolCallAllowance,
343
- parameters,
344
- resolved.policy,
345
- resolved.childPolicy,
346
- ),
347
- };
348
- }),
338
+ : { descendantInvocations: resolved.policy.descendantInvocations }),
339
+ }),
340
+ toolCallAllowance: resolveToolCallAllowance(
341
+ declaration.toolCallAllowance,
342
+ parameters,
343
+ resolved.policy,
344
+ resolved.childPolicy,
345
+ ),
346
+ };
347
+ }),
349
348
  });
350
349
 
351
350
  const validated = yield* Schema.decodeEffect(WorkerStarted)(started).pipe(
@@ -632,33 +631,32 @@ export const followUp = <
632
631
  ) => operations(declaration).followUp(worker, parameters, options);
633
632
 
634
633
  /** Inspect a continuing worker with the same summary contract returned by list. */
635
- export const summary = <const Name extends string>(
634
+ export const summary = Effect.fnUntraced(function* <const Name extends string>(
636
635
  declaration: WorkerDeclaration<Name> & { readonly target: AnyDefinition },
637
636
  worker: Worker<Name>,
638
- ) =>
639
- Effect.gen(function* () {
640
- const service = yield* host;
637
+ ) {
638
+ const service = yield* host;
641
639
 
642
- const validated = yield* Schema.decodeEffect(Worker(declaration))(worker).pipe(
643
- Effect.mapError(() => WorkerError.make({ operation: "inspect", reason: "worker-mismatch" })),
644
- );
640
+ const validated = yield* Schema.decodeEffect(Worker(declaration))(worker).pipe(
641
+ Effect.mapError(() => WorkerError.make({ operation: "inspect", reason: "worker-mismatch" })),
642
+ );
645
643
 
646
- const result = yield* service.summary({ worker: validated, target: declaration.target });
644
+ const result = yield* service.summary({ worker: validated, target: declaration.target });
647
645
 
648
- const value = yield* Schema.decodeEffect(WorkerSummary)(result).pipe(
649
- Effect.mapError(() => WorkerError.make({ operation: "inspect", reason: "corrupt" })),
650
- );
646
+ const value = yield* Schema.decodeEffect(WorkerSummary)(result).pipe(
647
+ Effect.mapError(() => WorkerError.make({ operation: "inspect", reason: "corrupt" })),
648
+ );
651
649
 
652
- if (
653
- value.worker.threadId !== validated.threadId ||
654
- value.worker.delegationId !== validated.delegationId ||
655
- value.worker.targetAgentId !== validated.targetAgentId ||
656
- (value.latestReceipt !== null && value.latestReceipt.threadId !== validated.threadId)
657
- )
658
- return yield* WorkerError.make({ operation: "inspect", reason: "worker-mismatch" });
659
-
660
- return { ...value, worker: validated };
661
- });
650
+ if (
651
+ value.worker.threadId !== validated.threadId ||
652
+ value.worker.delegationId !== validated.delegationId ||
653
+ value.worker.targetAgentId !== validated.targetAgentId ||
654
+ (value.latestReceipt !== null && value.latestReceipt.threadId !== validated.threadId)
655
+ )
656
+ return yield* WorkerError.make({ operation: "inspect", reason: "worker-mismatch" });
657
+
658
+ return { ...value, worker: validated };
659
+ });
662
660
 
663
661
  /** Inspect a worker summary, retained MessageRef, or the result of one exact accepted Receipt. */
664
662
  export function inspect<
@@ -762,33 +760,32 @@ export const observe = <const Name extends string>(
762
760
  );
763
761
 
764
762
  /** Seal a continuing worker, retaining a stable command identity across retries and Runs. */
765
- export const stop = <const Name extends string>(
763
+ export const stop = Effect.fnUntraced(function* <const Name extends string>(
766
764
  declaration: WorkerDeclaration<Name> & { readonly target: AnyDefinition },
767
765
  worker: Worker<Name>,
768
766
  options: { readonly idempotencyKey: IdempotencyKey },
769
- ) =>
770
- Effect.gen(function* () {
771
- const service = yield* host;
772
-
773
- const command = yield* Schema.decodeEffect(WorkerStop)({ worker, ...options }).pipe(
774
- Effect.mapError((cause) => WorkerError.make({ operation: "stop", reason: "corrupt", cause })),
775
- );
767
+ ) {
768
+ const service = yield* host;
776
769
 
777
- if (
778
- worker.delegationId !== declaration.delegationId ||
779
- worker.targetAgentId !== declaration.target.id
780
- )
781
- return yield* WorkerError.make({ operation: "stop", reason: "worker-mismatch" });
770
+ const command = yield* Schema.decodeEffect(WorkerStop)({ worker, ...options }).pipe(
771
+ Effect.mapError((cause) => WorkerError.make({ operation: "stop", reason: "corrupt", cause })),
772
+ );
782
773
 
783
- return yield* service.stop({ ...command, target: declaration.target }).pipe(
784
- Effect.flatMap(Schema.decodeEffect(WorkerStopped)),
785
- Effect.mapError((cause) =>
786
- Schema.is(WorkerError)(cause)
787
- ? cause
788
- : WorkerError.make({ operation: "stop", reason: "corrupt", cause }),
789
- ),
790
- );
791
- });
774
+ if (
775
+ worker.delegationId !== declaration.delegationId ||
776
+ worker.targetAgentId !== declaration.target.id
777
+ )
778
+ return yield* WorkerError.make({ operation: "stop", reason: "worker-mismatch" });
779
+
780
+ return yield* service.stop({ ...command, target: declaration.target }).pipe(
781
+ Effect.flatMap(Schema.decodeEffect(WorkerStopped)),
782
+ Effect.mapError((cause) =>
783
+ Schema.is(WorkerError)(cause)
784
+ ? cause
785
+ : WorkerError.make({ operation: "stop", reason: "corrupt", cause }),
786
+ ),
787
+ );
788
+ });
792
789
 
793
790
  /** Wait for the exact Receipt. Interrupting this Effect never cancels accepted work. */
794
791
  export const awaitWorker = <
@@ -1066,6 +1063,21 @@ const modelKey = Effect.fnUntraced(function* (operation: "start" | "followUp") {
1066
1063
  );
1067
1064
  });
1068
1065
 
1066
+ type SelectionServices<Flag, Requirements> = Flag extends true ? Requirements : never;
1067
+
1068
+ // Conditional flags retain services for either possible runtime branch. Disabled operations
1069
+ // never run the capture effect and cannot install a handler that consumes those services.
1070
+ const captureSelected = <Flag extends true | undefined>(flag: Flag) => {
1071
+ function capture<A, R>(
1072
+ effect: Effect.Effect<A, never, R>,
1073
+ ): Effect.Effect<Option.Option<A>, never, SelectionServices<Flag, R>>;
1074
+ function capture<A, R>(effect: Effect.Effect<A, never, R>) {
1075
+ return flag === true ? Effect.map(effect, Option.some) : Effect.succeedNone;
1076
+ }
1077
+
1078
+ return capture;
1079
+ };
1080
+
1069
1081
  // Construction-local service keys distinguish projections for co-registered parent versions.
1070
1082
  // These keys are never persisted; worker/run identity and registration digests remain canonical.
1071
1083
  let reportingServiceId = 0;
@@ -1196,64 +1208,88 @@ export const background = <
1196
1208
  | Parameters["DecodingServices"]
1197
1209
  | Output["DecodingServices"]
1198
1210
  | Success["EncodingServices"];
1199
- type Services = PrepareServices | ProjectServices;
1200
- type SelectionServices<Flag, Requirements> = Flag extends true ? Requirements : never;
1201
1211
 
1202
1212
  const build = Effect.gen(function* () {
1203
- const captured = yield* Effect.context<Services>();
1213
+ const start = yield* captureSelected<Selected["start"]>(selected.start)(
1214
+ Effect.map(
1215
+ Effect.context<PrepareServices>(),
1216
+ (captured) => (parameters: Parameters["Type"]) =>
1217
+ Effect.gen(function* () {
1218
+ const service = yield* host;
1219
+ const idempotencyKey = yield* modelKey("start");
1220
+
1221
+ return yield* ops
1222
+ .start(parameters, {
1223
+ idempotencyKey,
1224
+ ...(selected.budgetScope === undefined
1225
+ ? {}
1226
+ : { budgetScope: selected.budgetScope }),
1227
+ })
1228
+ .pipe(Effect.provideService(SubagentHost, service), Effect.provide(captured));
1229
+ }),
1230
+ ),
1231
+ );
1204
1232
 
1205
- const handlers = {
1206
- [startTool.name]: (parameters: Parameters["Type"]) =>
1207
- Effect.gen(function* () {
1208
- const service = yield* host;
1209
- const idempotencyKey = yield* modelKey("start");
1210
-
1211
- return yield* ops
1212
- .start(parameters, {
1213
- idempotencyKey,
1214
- ...(selected.budgetScope === undefined ? {} : { budgetScope: selected.budgetScope }),
1215
- })
1216
- .pipe(Effect.provideService(SubagentHost, service), Effect.provide(captured));
1217
- }),
1218
- [followUpTool.name]: (parameters: {
1219
- readonly worker: Worker<Name>;
1220
- readonly parameters: Parameters["Type"];
1221
- }) =>
1222
- Effect.gen(function* () {
1223
- const service = yield* host;
1224
- const idempotencyKey = yield* modelKey("followUp");
1225
-
1226
- return yield* ops
1227
- .followUp(parameters.worker, parameters.parameters, { idempotencyKey })
1228
- .pipe(Effect.provideService(SubagentHost, service), Effect.provide(captured));
1229
- }),
1230
- [inspectTool.name]: (parameters: {
1231
- readonly worker: Worker<Name>;
1232
- readonly message?: MessageRef;
1233
- readonly receipt?: Receipt;
1234
- }) =>
1235
- Effect.gen(function* () {
1236
- const service = yield* host;
1237
-
1238
- if (parameters.message !== undefined)
1239
- return yield* ops.inspectMessage(parameters.worker, parameters.message);
1240
- if (parameters.receipt === undefined)
1241
- return yield* WorkerError.make({ operation: "inspect", reason: "message-mismatch" });
1242
-
1243
- return yield* ops.observe("inspect", parameters.worker, parameters.receipt).pipe(
1244
- Effect.map((observed) => {
1245
- if ("diagnostic" in observed) {
1246
- const { diagnostic: _diagnostic, ...projected } = observed;
1247
-
1248
- return projected;
1249
- }
1250
-
1251
- return observed;
1233
+ const followUp = yield* captureSelected<Selected["followUp"]>(selected.followUp)(
1234
+ Effect.map(
1235
+ Effect.context<PrepareServices>(),
1236
+ (captured) =>
1237
+ (parameters: {
1238
+ readonly worker: Worker<Name>;
1239
+ readonly parameters: Parameters["Type"];
1240
+ }) =>
1241
+ Effect.gen(function* () {
1242
+ const service = yield* host;
1243
+ const idempotencyKey = yield* modelKey("followUp");
1244
+
1245
+ return yield* ops
1246
+ .followUp(parameters.worker, parameters.parameters, { idempotencyKey })
1247
+ .pipe(Effect.provideService(SubagentHost, service), Effect.provide(captured));
1252
1248
  }),
1253
- Effect.provideService(SubagentHost, service),
1254
- Effect.provide(captured),
1255
- );
1256
- }),
1249
+ ),
1250
+ );
1251
+
1252
+ const inspect = yield* captureSelected<Selected["inspect"]>(selected.inspect)(
1253
+ Effect.map(
1254
+ Effect.context<ProjectServices>(),
1255
+ (captured) =>
1256
+ (parameters: {
1257
+ readonly worker: Worker<Name>;
1258
+ readonly message?: MessageRef;
1259
+ readonly receipt?: Receipt;
1260
+ }) =>
1261
+ Effect.gen(function* () {
1262
+ const service = yield* host;
1263
+
1264
+ if (parameters.message !== undefined)
1265
+ return yield* ops.inspectMessage(parameters.worker, parameters.message);
1266
+ if (parameters.receipt === undefined)
1267
+ return yield* WorkerError.make({
1268
+ operation: "inspect",
1269
+ reason: "message-mismatch",
1270
+ });
1271
+
1272
+ return yield* ops.observe("inspect", parameters.worker, parameters.receipt).pipe(
1273
+ Effect.map((observed) => {
1274
+ if ("diagnostic" in observed) {
1275
+ const { diagnostic: _diagnostic, ...projected } = observed;
1276
+
1277
+ return projected;
1278
+ }
1279
+
1280
+ return observed;
1281
+ }),
1282
+ Effect.provideService(SubagentHost, service),
1283
+ Effect.provide(captured),
1284
+ );
1285
+ }),
1286
+ ),
1287
+ );
1288
+
1289
+ const handlers = {
1290
+ ...(Option.isSome(start) ? { [startTool.name]: start.value } : {}),
1291
+ ...(Option.isSome(followUp) ? { [followUpTool.name]: followUp.value } : {}),
1292
+ ...(Option.isSome(inspect) ? { [inspectTool.name]: inspect.value } : {}),
1257
1293
  [listTool.name]: (parameters: typeof ListParameters.Type) => ops.list(parameters),
1258
1294
  [summaryTool.name]: (parameters: { readonly worker: Worker<Name> }) =>
1259
1295
  summary(declaration, parameters.worker),
@@ -1263,7 +1299,7 @@ export const background = <
1263
1299
  }) => ops.cancel(parameters.worker, parameters.receipt),
1264
1300
  };
1265
1301
 
1266
- // Each handler above is paired with its native schema; computed generic names need this bridge.
1302
+ // Each selected handler is paired with its native schema; computed names need this bridge.
1267
1303
  return handlers as unknown as Toolkit.HandlersFrom<Tools>;
1268
1304
  });
1269
1305
 
@@ -1273,18 +1309,20 @@ export const background = <
1273
1309
  | SelectionServices<Selected["inspect"], ProjectServices>
1274
1310
  | SelectionServices<Selected["reportToParent"], Exclude<ProjectServices, Scope.Scope>>;
1275
1311
 
1276
- // Unselected handlers are never installed. Only selected operations consume projection services.
1277
- const reportingLayer =
1278
- report === undefined
1279
- ? Layer.empty
1280
- : Layer.effect(
1281
- reportService,
1282
- Effect.map(
1283
- Effect.context<Effect.Services<ReturnType<typeof report.prepare>>>(),
1284
- (context): WorkerReporting<WorkerReportPreparationFailure> => ({
1285
- ...report,
1312
+ const reportingLayer = Layer.effectContext(
1313
+ Effect.gen(function* () {
1314
+ const capturedReport = yield* captureSelected<Selected["reportToParent"]>(
1315
+ selected.reportToParent,
1316
+ )(
1317
+ Effect.map(
1318
+ Effect.context<Exclude<ProjectServices, Scope.Scope>>(),
1319
+ (context): WorkerReporting<WorkerReportPreparationFailure> => {
1320
+ const reporting = automaticReporting(declaration);
1321
+
1322
+ return {
1323
+ ...reporting,
1286
1324
  prepare: (value) =>
1287
- Effect.scoped(Effect.suspend(() => report.prepare(value))).pipe(
1325
+ Effect.scoped(Effect.suspend(() => reporting.prepare(value))).pipe(
1288
1326
  Effect.provide(context),
1289
1327
  Effect.mapError((error) =>
1290
1328
  Schema.is(WorkerReportPreparationFailure)(error)
@@ -1292,15 +1330,21 @@ export const background = <
1292
1330
  : WorkerReportPreparationFailure.make({ stage: "preparation" }),
1293
1331
  ),
1294
1332
  ),
1295
- }),
1296
- ),
1297
- );
1333
+ };
1334
+ },
1335
+ ),
1336
+ );
1298
1337
 
1299
- const layer = Layer.merge(toolkit.toLayer(build), reportingLayer) as Layer.Layer<
1300
- Tool.HandlersFor<Tools>,
1301
- never,
1302
- SelectedServices
1303
- >;
1338
+ return Option.isNone(capturedReport)
1339
+ ? Context.empty()
1340
+ : Context.make(reportService, capturedReport.value);
1341
+ }),
1342
+ );
1343
+
1344
+ const layer: Layer.Layer<Tool.HandlersFor<Tools>, never, SelectedServices> = Layer.merge(
1345
+ toolkit.toLayer(build),
1346
+ reportingLayer,
1347
+ );
1304
1348
 
1305
1349
  return Object.freeze({ tools: toolkit.tools, toolkit, layer });
1306
1350
  };