@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,4 +1,4 @@
1
- import { DateTime, Predicate, Schema } from "effect";
1
+ import { DateTime, Predicate, Result, Schema } from "effect";
2
2
 
3
3
  import type { RunId } from "../../core/Identifiers.ts";
4
4
  import { utf8ByteLength } from "../../core/internal/utf8.ts";
@@ -13,7 +13,7 @@ import {
13
13
  type RecordJson,
14
14
  type RunContinuation,
15
15
  } from "../Records.ts";
16
- import { canonicalJson } from "./canonical-json.ts";
16
+ import { boundedCanonicalJson, canonicalJson } from "./canonical-json.ts";
17
17
  import {
18
18
  executionRunIds,
19
19
  isPreContinuationFact,
@@ -31,6 +31,11 @@ const recordLimits = {
31
31
  textUnits: MAX_CANONICAL_RECORD_BYTES,
32
32
  };
33
33
 
34
+ export class RecordEncodingError extends Schema.TaggedError<RecordEncodingError>()(
35
+ "RecordEncodingError",
36
+ { message: Schema.String, cause: Schema.optionalKey(Schema.Defect()) },
37
+ ) {}
38
+
34
39
  export interface RecordEncoding {
35
40
  readonly canonical: RecordEnvelope;
36
41
  readonly wire: RecordJson;
@@ -39,6 +44,10 @@ export interface RecordEncoding {
39
44
  readonly progress: ProgressAppendRecord;
40
45
  }
41
46
 
47
+ interface CapturedRecordEncoding extends RecordEncoding {
48
+ readonly wire: typeof RecordEnvelope.Encoded;
49
+ }
50
+
42
51
  /** Private capture metadata, never caller-supplied wire data or execution authority. */
43
52
  export interface ProgressAppendRecord {
44
53
  readonly recordId: RecordEnvelope["recordId"];
@@ -67,7 +76,40 @@ const progressRecord = (record: RecordEnvelope, bytes: number): ProgressAppendRe
67
76
  });
68
77
  };
69
78
 
70
- const captured = new WeakMap<RecordEnvelope, RecordEncoding>();
79
+ const captured = new WeakMap<RecordEnvelope, CapturedRecordEncoding>();
80
+
81
+ // Define own data properties so valid JSON keys never invoke inherited setters.
82
+ const setOwn = (target: object, key: PropertyKey, value: unknown): void => {
83
+ Object.defineProperty(target, key, {
84
+ value,
85
+ writable: true,
86
+ enumerable: true,
87
+ configurable: true,
88
+ });
89
+ };
90
+
91
+ /** JSON arrays use indexed values, even when inherited or non-enumerable. */
92
+ const copyOwn = (value: object): object => {
93
+ if (!Array.isArray(value)) {
94
+ const copy = { ...value };
95
+
96
+ Object.setPrototypeOf(copy, Object.getPrototypeOf(value));
97
+
98
+ return copy;
99
+ }
100
+ const copy: Array<unknown> = [];
101
+
102
+ for (let index = 0; index < value.length; index++) setOwn(copy, index, value[index]);
103
+ for (const key of Reflect.ownKeys(value)) {
104
+ if (
105
+ !Object.hasOwn(copy, key) &&
106
+ Object.getOwnPropertyDescriptor(value, key)?.enumerable === true
107
+ )
108
+ setOwn(copy, key, Reflect.get(value, key));
109
+ }
110
+
111
+ return copy;
112
+ };
71
113
 
72
114
  /** Own every fact before suspension; encoded JSON fields can share these private frozen values. */
73
115
  const capturePayload = (payload: CanonicalRecordPayload) => {
@@ -76,31 +118,26 @@ const capturePayload = (payload: CanonicalRecordPayload) => {
76
118
  Object.setPrototypeOf(copy, Object.getPrototypeOf(payload));
77
119
  const copies = new WeakMap<object, object>([[payload, copy]]);
78
120
 
79
- const pending: Array<{ readonly source: object; readonly target: object }> = [
80
- { source: payload, target: copy },
81
- ];
121
+ const pending: Array<object> = [copy];
82
122
 
83
123
  const owned: Array<object> = [copy];
84
124
 
85
125
  while (pending.length > 0) {
86
126
  const next = pending.pop()!;
87
127
 
88
- for (const [key, value] of Object.entries(next.source)) {
89
- if (!Predicate.isObject(value)) continue;
128
+ for (const [key, value] of Object.entries(next)) {
129
+ if (!Predicate.isObjectOrArray(value)) continue;
90
130
  let child = copies.get(value);
91
131
 
92
132
  if (child === undefined) {
93
- const created: object = Array.isArray(value)
94
- ? []
95
- : Object.create(Object.getPrototypeOf(value));
133
+ const created = copyOwn(value);
96
134
 
97
- Object.assign(created, value);
98
135
  copies.set(value, created);
99
136
  owned.push(created);
100
- pending.push({ source: value, target: created });
137
+ pending.push(created);
101
138
  child = created;
102
139
  }
103
- Reflect.set(next.target, key, child);
140
+ setOwn(next, key, child);
104
141
  }
105
142
  }
106
143
  for (const value of owned) Object.freeze(value);
@@ -109,17 +146,17 @@ const capturePayload = (payload: CanonicalRecordPayload) => {
109
146
  };
110
147
 
111
148
  /** Schema-created structures are private; detach JSON pass-throughs using the same owned copy. */
112
- const ownWire = (wire: RecordJson, copies: WeakMap<object, object>): RecordJson => {
113
- const pending: Array<object> = Predicate.isObject(wire) ? [wire] : [];
149
+ const ownWire = <Wire extends RecordJson>(wire: Wire, copies: WeakMap<object, object>): Wire => {
150
+ const pending: Array<object> = Predicate.isObjectOrArray(wire) ? [wire] : [];
114
151
 
115
152
  while (pending.length > 0) {
116
153
  const next = pending.pop()!;
117
154
 
118
155
  for (const [key, value] of Object.entries(next)) {
119
- if (!Predicate.isObject(value)) continue;
156
+ if (!Predicate.isObjectOrArray(value)) continue;
120
157
  const copy = copies.get(value);
121
158
 
122
- if (copy !== undefined) Reflect.set(next, key, copy);
159
+ if (copy !== undefined) setOwn(next, key, copy);
123
160
  else pending.push(value);
124
161
  }
125
162
  Object.freeze(next);
@@ -129,66 +166,85 @@ const ownWire = (wire: RecordJson, copies: WeakMap<object, object>): RecordJson
129
166
  };
130
167
 
131
168
  /** Capture at the Schema boundary; only the privately owned result can reuse its encoding. */
132
- export const captureRecord = (input: RecordEnvelope): RecordEncoding => {
133
- const existing = captured.get(input);
134
-
135
- if (existing !== undefined) return existing;
136
- const encoded = encodeRecord(input);
137
- const owned = capturePayload(input.payload);
138
- const wire = ownWire(encoded, owned.copies);
139
- const json = canonicalJson(wire, recordLimits);
140
- const bytes = utf8ByteLength(json);
141
-
142
- if (bytes > MAX_CANONICAL_RECORD_BYTES)
143
- throw new RangeError("Canonical JSON exceeds its byte bound");
144
- const createdAt = DateTime.makeUnsafe(DateTime.toEpochMillis(input.createdAt));
145
-
146
- // DateTime fills this cache lazily; populate it before freezing our private copy.
147
- Object.freeze(DateTime.toPartsUtc(createdAt));
148
- Object.freeze(createdAt);
149
-
150
- const canonical = Object.freeze(
151
- new RecordEnvelope(
152
- {
153
- ...input,
154
- createdAt,
155
- payload: owned.payload,
156
- },
157
- { disableChecks: true },
158
- ),
159
- );
160
-
161
- const encoding = Object.freeze({
162
- canonical,
163
- wire,
164
- json,
165
- bytes,
166
- progress: progressRecord(canonical, bytes),
167
- });
169
+ export const captureRecord = (
170
+ input: RecordEnvelope,
171
+ ): Result.Result<CapturedRecordEncoding, RecordEncodingError> => {
172
+ try {
173
+ const existing = captured.get(input);
174
+
175
+ if (existing !== undefined) return Result.succeed(existing);
176
+ const encoded = encodeRecord(input);
177
+ const owned = capturePayload(input.payload);
178
+ const wire = ownWire(encoded, owned.copies);
179
+ const serialized = boundedCanonicalJson(wire, recordLimits);
180
+
181
+ if (Result.isFailure(serialized))
182
+ return Result.fail(RecordEncodingError.make({ message: serialized.failure.message }));
183
+ const json = serialized.success;
184
+ const bytes = utf8ByteLength(json);
168
185
 
169
- captured.set(canonical, encoding);
186
+ if (bytes > MAX_CANONICAL_RECORD_BYTES)
187
+ return Result.fail(
188
+ RecordEncodingError.make({ message: "Canonical JSON exceeds its byte bound" }),
189
+ );
190
+ const createdAt = DateTime.makeUnsafe(DateTime.toEpochMillis(input.createdAt));
191
+
192
+ // DateTime fills this cache lazily; populate it before freezing our private copy.
193
+ Object.freeze(DateTime.toPartsUtc(createdAt));
194
+ Object.freeze(createdAt);
195
+
196
+ const canonical = Object.freeze(
197
+ RecordEnvelope.make(
198
+ {
199
+ ...input,
200
+ createdAt,
201
+ payload: owned.payload,
202
+ },
203
+ { disableChecks: true },
204
+ ),
205
+ );
206
+
207
+ const encoding = Object.freeze({
208
+ canonical,
209
+ wire,
210
+ json,
211
+ bytes,
212
+ progress: progressRecord(canonical, bytes),
213
+ });
170
214
 
171
- return encoding;
215
+ captured.set(canonical, encoding);
216
+
217
+ return Result.succeed(encoding);
218
+ } catch (cause) {
219
+ return Result.fail(
220
+ RecordEncodingError.make({ message: "Canonical record capture failed", cause }),
221
+ );
222
+ }
172
223
  };
173
224
 
174
225
  /** Read evidence retains its original wire; fresh writes use the captured Schema encoding. */
175
- export const recordEncoding = (record: RecordEnvelope): RecordEncoding => {
226
+ export const recordEncoding = (
227
+ record: RecordEnvelope,
228
+ ): Result.Result<RecordEncoding, RecordEncodingError> => {
176
229
  const existing = captured.get(record);
177
230
 
178
- if (existing !== undefined) return existing;
179
- if (record instanceof ExportedRecord) {
180
- const json = canonicalJson(record.wire);
231
+ if (existing !== undefined) return Result.succeed(existing);
181
232
 
233
+ try {
234
+ if (!(record instanceof ExportedRecord)) return captureRecord(record);
235
+ const json = canonicalJson(record.wire);
182
236
  const bytes = utf8ByteLength(json);
183
237
 
184
- return {
238
+ return Result.succeed({
185
239
  canonical: record,
186
240
  wire: record.wire,
187
241
  json,
188
242
  bytes,
189
243
  progress: progressRecord(record, bytes),
190
- };
244
+ });
245
+ } catch (cause) {
246
+ return Result.fail(
247
+ RecordEncodingError.make({ message: "Canonical record encoding failed", cause }),
248
+ );
191
249
  }
192
-
193
- return captureRecord(record);
194
250
  };
@@ -156,14 +156,14 @@ export const scheduleNextAfter = (
156
156
  while (next <= afterMillis) {
157
157
  const following = Cron.next(cron.success, next).getTime();
158
158
 
159
- if (following <= next) throw new Error("Cron did not advance");
159
+ if (following <= next) return invalid("Cron has no supported next firing");
160
160
  next = following;
161
161
  }
162
162
 
163
- return next;
163
+ return checkedInstant(next, "Next cron occurrence");
164
164
  },
165
165
  catch: () => ScheduleValidationError.make({ message: "Cron has no supported next firing" }),
166
- }).pipe(Result.flatMap((next) => checkedInstant(next, "Next cron occurrence")));
166
+ }).pipe(Result.flatMap((result) => result));
167
167
  }
168
168
  }
169
169
  };
@@ -250,15 +250,15 @@ export const scheduleDueOccurrence = (
250
250
  let next = Cron.next(cron.success, intended).getTime();
251
251
 
252
252
  while (next <= nowMillis) {
253
- if (next <= intended) throw new Error("Cron did not advance");
253
+ if (next <= intended) return invalid("Cron has no supported due firing");
254
254
  intended = next;
255
255
  next = Cron.next(cron.success, intended).getTime();
256
256
  }
257
257
 
258
- return { intended, next };
258
+ return Result.succeed({ intended, next });
259
259
  },
260
260
  catch: () => ScheduleValidationError.make({ message: "Cron has no supported due firing" }),
261
- });
261
+ }).pipe(Result.flatMap((result) => result));
262
262
 
263
263
  if (Result.isFailure(due)) return Result.fail(due.failure);
264
264
  const next = checkedInstant(due.success.next, "Next cron occurrence");
@@ -0,0 +1,38 @@
1
+ import { Effect } from "effect";
2
+
3
+ import { summarizeModelUsage, type ModelCallUsage } from "../../core/Usage.ts";
4
+
5
+ /** Captured calls are additive and nonnegative; progress does not need attribution groups. */
6
+ export const continuationUsage = Effect.fnUntraced(function* (
7
+ calls: ReadonlyArray<ModelCallUsage>,
8
+ ) {
9
+ let inputTokens = 0;
10
+ let outputTokens = 0;
11
+ let costMicrousd = 0;
12
+ let knownWebSearchCalls = 0;
13
+
14
+ for (const call of calls) {
15
+ inputTokens += call.inputTokens.total;
16
+ outputTokens += call.outputTokens.total;
17
+ costMicrousd += call.costMicrousd;
18
+ knownWebSearchCalls += call.webSearchCalls ?? 0;
19
+ }
20
+ if (
21
+ Number.isSafeInteger(inputTokens) &&
22
+ Number.isSafeInteger(outputTokens) &&
23
+ Number.isSafeInteger(costMicrousd) &&
24
+ Number.isSafeInteger(knownWebSearchCalls)
25
+ )
26
+ return { modelCalls: calls.length, inputTokens, outputTokens, costMicrousd };
27
+
28
+ // Safe global sums bound every component/group. On overflow retain the full validator,
29
+ // including groups whose hosted-search coverage differs from the aggregate's coverage.
30
+ const summary = yield* summarizeModelUsage(calls);
31
+
32
+ return {
33
+ modelCalls: summary.modelCalls,
34
+ inputTokens: summary.inputTokens.total,
35
+ outputTokens: summary.outputTokens.total,
36
+ costMicrousd: summary.costMicrousd,
37
+ };
38
+ });
@@ -3207,70 +3207,66 @@ export const makeWorkerRuntime = Effect.fnUntraced(function* (options: WorkerRun
3207
3207
  .get({ ownerThreadId: context.source.threadId, messageId })
3208
3208
  .pipe(Effect.mapError(storageFailure("start")));
3209
3209
 
3210
- const replay = (saved: MessageDeliveryRecord) =>
3211
- Effect.gen(function* () {
3212
- const currentPrevious =
3213
- command.continuationOf === undefined
3214
- ? undefined
3215
- : yield* completedContinuation(
3216
- context.source,
3217
- command.continuationOf,
3218
- command.target.id,
3219
- command.delegationId,
3220
- previous?.evidence,
3221
- );
3222
-
3223
- const replayPrincipal = yield* authorize(
3224
- "start",
3225
- "send",
3226
- undefined,
3227
- currentPrevious?.evidence,
3228
- );
3210
+ const replay = Effect.fnUntraced(function* (saved: MessageDeliveryRecord) {
3211
+ const currentPrevious =
3212
+ command.continuationOf === undefined
3213
+ ? undefined
3214
+ : yield* completedContinuation(
3215
+ context.source,
3216
+ command.continuationOf,
3217
+ command.target.id,
3218
+ command.delegationId,
3219
+ previous?.evidence,
3220
+ );
3229
3221
 
3230
- yield* binding(command.target, "start");
3231
- const metadata = saved.envelope.workerAdmission;
3222
+ const replayPrincipal = yield* authorize(
3223
+ "start",
3224
+ "send",
3225
+ undefined,
3226
+ currentPrevious?.evidence,
3227
+ );
3232
3228
 
3233
- if (metadata === undefined) return yield* failure("start", "idempotency-conflict");
3234
- const origin = metadata.origin;
3229
+ yield* binding(command.target, "start");
3230
+ const metadata = saved.envelope.workerAdmission;
3235
3231
 
3236
- if (
3237
- !Schema.toEquivalence(Schema.UndefinedOr(WorkerContinuation))(
3238
- origin.continuationOf,
3239
- currentPrevious?.evidence,
3240
- ) ||
3241
- origin.firstMessageId !== messageId ||
3242
- metadata.messageId !== messageId ||
3243
- origin.source.threadId !== context.source.threadId ||
3244
- origin.worker.delegationId !== command.delegationId ||
3245
- origin.worker.targetAgentId !== command.target.id ||
3246
- !sameJson(metadata.parameters, parameters) ||
3247
- !Schema.toEquivalence(SubagentGrant)(origin.grant, grant) ||
3248
- origin.budgetScope !== effectiveScope ||
3249
- origin.depth !== context.depth + 1 ||
3250
- (!("prepare" in command) &&
3251
- (!samePolicy(origin.policy, command.policy) ||
3252
- !Schema.toEquivalence(WorkerOrigin.fields.budget)(
3253
- origin.budget,
3254
- command.budget,
3255
- ) ||
3256
- origin.toolCallAllowance !== command.toolCallAllowance))
3257
- )
3258
- return yield* failure("start", "idempotency-conflict");
3259
-
3260
- yield* verifyContinuation(origin);
3261
-
3262
- return {
3263
- worker: origin.worker,
3264
- delivery: yield* send(
3265
- origin,
3266
- messageId,
3267
- "prepare" in command ? saved.envelope.input : command.encodedInput,
3268
- parameters,
3269
- replayPrincipal,
3270
- "start",
3271
- ),
3272
- };
3273
- });
3232
+ if (metadata === undefined) return yield* failure("start", "idempotency-conflict");
3233
+ const origin = metadata.origin;
3234
+
3235
+ if (
3236
+ !Schema.toEquivalence(Schema.UndefinedOr(WorkerContinuation))(
3237
+ origin.continuationOf,
3238
+ currentPrevious?.evidence,
3239
+ ) ||
3240
+ origin.firstMessageId !== messageId ||
3241
+ metadata.messageId !== messageId ||
3242
+ origin.source.threadId !== context.source.threadId ||
3243
+ origin.worker.delegationId !== command.delegationId ||
3244
+ origin.worker.targetAgentId !== command.target.id ||
3245
+ !sameJson(metadata.parameters, parameters) ||
3246
+ !Schema.toEquivalence(SubagentGrant)(origin.grant, grant) ||
3247
+ origin.budgetScope !== effectiveScope ||
3248
+ origin.depth !== context.depth + 1 ||
3249
+ (!("prepare" in command) &&
3250
+ (!samePolicy(origin.policy, command.policy) ||
3251
+ !Schema.toEquivalence(WorkerOrigin.fields.budget)(origin.budget, command.budget) ||
3252
+ origin.toolCallAllowance !== command.toolCallAllowance))
3253
+ )
3254
+ return yield* failure("start", "idempotency-conflict");
3255
+
3256
+ yield* verifyContinuation(origin);
3257
+
3258
+ return {
3259
+ worker: origin.worker,
3260
+ delivery: yield* send(
3261
+ origin,
3262
+ messageId,
3263
+ "prepare" in command ? saved.envelope.input : command.encodedInput,
3264
+ parameters,
3265
+ replayPrincipal,
3266
+ "start",
3267
+ ),
3268
+ };
3269
+ });
3274
3270
 
3275
3271
  const existing = yield* retained();
3276
3272
 
@@ -3461,21 +3457,20 @@ export const makeWorkerRuntime = Effect.fnUntraced(function* (options: WorkerRun
3461
3457
  .get({ ownerThreadId: context.source.threadId, messageId })
3462
3458
  .pipe(Effect.mapError(storageFailure("followUp")));
3463
3459
 
3464
- const replay = (saved: MessageDeliveryRecord) =>
3465
- Effect.gen(function* () {
3466
- const replayPrincipal = yield* authorize("followUp", "send", command.worker);
3460
+ const replay = Effect.fnUntraced(function* (saved: MessageDeliveryRecord) {
3461
+ const replayPrincipal = yield* authorize("followUp", "send", command.worker);
3467
3462
 
3468
- yield* currentPolicy;
3463
+ yield* currentPolicy;
3469
3464
 
3470
- return yield* send(
3471
- origin,
3472
- messageId,
3473
- saved.envelope.input,
3474
- command.encodedParameters,
3475
- replayPrincipal,
3476
- "followUp",
3477
- );
3478
- });
3465
+ return yield* send(
3466
+ origin,
3467
+ messageId,
3468
+ saved.envelope.input,
3469
+ command.encodedParameters,
3470
+ replayPrincipal,
3471
+ "followUp",
3472
+ );
3473
+ });
3479
3474
 
3480
3475
  const existing = "prepare" in command ? yield* retained() : null;
3481
3476