@caupulican/pi-adaptative 0.81.41 → 0.81.42

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 (237) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/bundled-resources/runtimes/pi-shell-engine/commands/text.py +5 -1
  3. package/dist/bundled-resources/runtimes/pi-shell-engine/context.py +3 -3
  4. package/dist/bundled-resources/runtimes/pi-shell-engine/errors.py +8 -0
  5. package/dist/bundled-resources/runtimes/pi-shell-engine/exec.py +26 -3
  6. package/dist/bundled-resources/runtimes/pi-shell-engine/expand.py +3 -0
  7. package/dist/bundled-resources/runtimes/pi-shell-engine/main.py +4 -1
  8. package/dist/bundled-resources/runtimes/pi-shell-engine/state.py +2 -1
  9. package/dist/bundled-resources/runtimes/pi-shell-engine/tokens.py +2 -0
  10. package/dist/core/agent-paths.d.ts +32 -0
  11. package/dist/core/agent-paths.d.ts.map +1 -1
  12. package/dist/core/agent-paths.js +65 -0
  13. package/dist/core/agent-paths.js.map +1 -1
  14. package/dist/core/agent-session-contracts.d.ts +19 -1
  15. package/dist/core/agent-session-contracts.d.ts.map +1 -1
  16. package/dist/core/agent-session-contracts.js.map +1 -1
  17. package/dist/core/agent-session.d.ts.map +1 -1
  18. package/dist/core/agent-session.js +4 -9
  19. package/dist/core/agent-session.js.map +1 -1
  20. package/dist/core/autonomy/contracts.d.ts +2 -0
  21. package/dist/core/autonomy/contracts.d.ts.map +1 -1
  22. package/dist/core/autonomy/contracts.js.map +1 -1
  23. package/dist/core/autonomy/envelope-enforcement.d.ts.map +1 -1
  24. package/dist/core/autonomy/envelope-enforcement.js +4 -9
  25. package/dist/core/autonomy/envelope-enforcement.js.map +1 -1
  26. package/dist/core/autonomy/lane-tool-surface.d.ts +3 -1
  27. package/dist/core/autonomy/lane-tool-surface.d.ts.map +1 -1
  28. package/dist/core/autonomy/lane-tool-surface.js +17 -4
  29. package/dist/core/autonomy/lane-tool-surface.js.map +1 -1
  30. package/dist/core/autonomy/path-scope.d.ts +14 -0
  31. package/dist/core/autonomy/path-scope.d.ts.map +1 -1
  32. package/dist/core/autonomy/path-scope.js +37 -6
  33. package/dist/core/autonomy/path-scope.js.map +1 -1
  34. package/dist/core/background-lane-controller.d.ts +27 -1
  35. package/dist/core/background-lane-controller.d.ts.map +1 -1
  36. package/dist/core/background-lane-controller.js +32 -1
  37. package/dist/core/background-lane-controller.js.map +1 -1
  38. package/dist/core/delegation/managed-lane-controller.d.ts +11 -1
  39. package/dist/core/delegation/managed-lane-controller.d.ts.map +1 -1
  40. package/dist/core/delegation/managed-lane-controller.js +84 -41
  41. package/dist/core/delegation/managed-lane-controller.js.map +1 -1
  42. package/dist/core/delegation/session-worker-claim.d.ts.map +1 -1
  43. package/dist/core/delegation/session-worker-claim.js +4 -3
  44. package/dist/core/delegation/session-worker-claim.js.map +1 -1
  45. package/dist/core/delegation/worker-action-journal.d.ts +73 -0
  46. package/dist/core/delegation/worker-action-journal.d.ts.map +1 -0
  47. package/dist/core/delegation/worker-action-journal.js +297 -0
  48. package/dist/core/delegation/worker-action-journal.js.map +1 -0
  49. package/dist/core/delegation/worker-actions.d.ts +36 -1
  50. package/dist/core/delegation/worker-actions.d.ts.map +1 -1
  51. package/dist/core/delegation/worker-actions.js +171 -46
  52. package/dist/core/delegation/worker-actions.js.map +1 -1
  53. package/dist/core/delegation/worker-agent-control-coordinator.d.ts +75 -0
  54. package/dist/core/delegation/worker-agent-control-coordinator.d.ts.map +1 -0
  55. package/dist/core/delegation/worker-agent-control-coordinator.js +218 -0
  56. package/dist/core/delegation/worker-agent-control-coordinator.js.map +1 -0
  57. package/dist/core/delegation/worker-agent-control.d.ts +66 -0
  58. package/dist/core/delegation/worker-agent-control.d.ts.map +1 -0
  59. package/dist/core/delegation/worker-agent-control.js +163 -0
  60. package/dist/core/delegation/worker-agent-control.js.map +1 -0
  61. package/dist/core/delegation/worker-attempt-executor.d.ts +80 -0
  62. package/dist/core/delegation/worker-attempt-executor.d.ts.map +1 -0
  63. package/dist/core/delegation/worker-attempt-executor.js +343 -0
  64. package/dist/core/delegation/worker-attempt-executor.js.map +1 -0
  65. package/dist/core/delegation/worker-claim.d.ts +30 -0
  66. package/dist/core/delegation/worker-claim.d.ts.map +1 -1
  67. package/dist/core/delegation/worker-claim.js +205 -53
  68. package/dist/core/delegation/worker-claim.js.map +1 -1
  69. package/dist/core/delegation/worker-conversation-store.d.ts +116 -0
  70. package/dist/core/delegation/worker-conversation-store.d.ts.map +1 -0
  71. package/dist/core/delegation/worker-conversation-store.js +442 -0
  72. package/dist/core/delegation/worker-conversation-store.js.map +1 -0
  73. package/dist/core/delegation/worker-delegation-controller.d.ts +21 -5
  74. package/dist/core/delegation/worker-delegation-controller.d.ts.map +1 -1
  75. package/dist/core/delegation/worker-delegation-controller.js +386 -251
  76. package/dist/core/delegation/worker-delegation-controller.js.map +1 -1
  77. package/dist/core/delegation/worker-delegation-request.d.ts +14 -0
  78. package/dist/core/delegation/worker-delegation-request.d.ts.map +1 -1
  79. package/dist/core/delegation/worker-delegation-request.js.map +1 -1
  80. package/dist/core/delegation/worker-dispatch-scheduler.d.ts +4 -2
  81. package/dist/core/delegation/worker-dispatch-scheduler.d.ts.map +1 -1
  82. package/dist/core/delegation/worker-dispatch-scheduler.js +16 -6
  83. package/dist/core/delegation/worker-dispatch-scheduler.js.map +1 -1
  84. package/dist/core/delegation/worker-execution-policy.d.ts +2 -1
  85. package/dist/core/delegation/worker-execution-policy.d.ts.map +1 -1
  86. package/dist/core/delegation/worker-execution-policy.js +5 -7
  87. package/dist/core/delegation/worker-execution-policy.js.map +1 -1
  88. package/dist/core/delegation/worker-lifecycle.d.ts +44 -1
  89. package/dist/core/delegation/worker-lifecycle.d.ts.map +1 -1
  90. package/dist/core/delegation/worker-lifecycle.js +120 -0
  91. package/dist/core/delegation/worker-lifecycle.js.map +1 -1
  92. package/dist/core/delegation/worker-process-owner.d.ts +18 -0
  93. package/dist/core/delegation/worker-process-owner.d.ts.map +1 -0
  94. package/dist/core/delegation/worker-process-owner.js +54 -0
  95. package/dist/core/delegation/worker-process-owner.js.map +1 -0
  96. package/dist/core/delegation/worker-profile-resolver.d.ts +5 -1
  97. package/dist/core/delegation/worker-profile-resolver.d.ts.map +1 -1
  98. package/dist/core/delegation/worker-profile-resolver.js +8 -0
  99. package/dist/core/delegation/worker-profile-resolver.js.map +1 -1
  100. package/dist/core/delegation/worker-recovery-coordinator.d.ts +54 -0
  101. package/dist/core/delegation/worker-recovery-coordinator.d.ts.map +1 -0
  102. package/dist/core/delegation/worker-recovery-coordinator.js +181 -0
  103. package/dist/core/delegation/worker-recovery-coordinator.js.map +1 -0
  104. package/dist/core/delegation/worker-resource-catalog.d.ts +32 -0
  105. package/dist/core/delegation/worker-resource-catalog.d.ts.map +1 -0
  106. package/dist/core/delegation/worker-resource-catalog.js +116 -0
  107. package/dist/core/delegation/worker-resource-catalog.js.map +1 -0
  108. package/dist/core/delegation/worker-resource-materializer.d.ts +47 -0
  109. package/dist/core/delegation/worker-resource-materializer.d.ts.map +1 -0
  110. package/dist/core/delegation/worker-resource-materializer.js +137 -0
  111. package/dist/core/delegation/worker-resource-materializer.js.map +1 -0
  112. package/dist/core/delegation/worker-runner.d.ts +3 -1
  113. package/dist/core/delegation/worker-runner.d.ts.map +1 -1
  114. package/dist/core/delegation/worker-runner.js +189 -54
  115. package/dist/core/delegation/worker-runner.js.map +1 -1
  116. package/dist/core/delegation/worker-terminal-finalizer.d.ts +23 -0
  117. package/dist/core/delegation/worker-terminal-finalizer.d.ts.map +1 -0
  118. package/dist/core/delegation/worker-terminal-finalizer.js +12 -0
  119. package/dist/core/delegation/worker-terminal-finalizer.js.map +1 -0
  120. package/dist/core/delegation/worker-write-reservation-coordinator.d.ts +38 -0
  121. package/dist/core/delegation/worker-write-reservation-coordinator.d.ts.map +1 -0
  122. package/dist/core/delegation/worker-write-reservation-coordinator.js +107 -0
  123. package/dist/core/delegation/worker-write-reservation-coordinator.js.map +1 -0
  124. package/dist/core/delegation/worker-write-reservation.d.ts +90 -0
  125. package/dist/core/delegation/worker-write-reservation.d.ts.map +1 -0
  126. package/dist/core/delegation/worker-write-reservation.js +348 -0
  127. package/dist/core/delegation/worker-write-reservation.js.map +1 -0
  128. package/dist/core/models/model-endpoint.d.ts +3 -0
  129. package/dist/core/models/model-endpoint.d.ts.map +1 -0
  130. package/dist/core/models/model-endpoint.js +11 -0
  131. package/dist/core/models/model-endpoint.js.map +1 -0
  132. package/dist/core/orchestration/agent-resume.d.ts +2 -0
  133. package/dist/core/orchestration/agent-resume.d.ts.map +1 -1
  134. package/dist/core/orchestration/agent-resume.js +7 -0
  135. package/dist/core/orchestration/agent-resume.js.map +1 -1
  136. package/dist/core/orchestration/attempt-usage.d.ts +28 -0
  137. package/dist/core/orchestration/attempt-usage.d.ts.map +1 -0
  138. package/dist/core/orchestration/attempt-usage.js +168 -0
  139. package/dist/core/orchestration/attempt-usage.js.map +1 -0
  140. package/dist/core/orchestration/capability-gateway.d.ts +19 -1
  141. package/dist/core/orchestration/capability-gateway.d.ts.map +1 -1
  142. package/dist/core/orchestration/capability-gateway.js +128 -28
  143. package/dist/core/orchestration/capability-gateway.js.map +1 -1
  144. package/dist/core/orchestration/contracts.d.ts +35 -0
  145. package/dist/core/orchestration/contracts.d.ts.map +1 -1
  146. package/dist/core/orchestration/contracts.js +17 -0
  147. package/dist/core/orchestration/contracts.js.map +1 -1
  148. package/dist/core/orchestration/delegation-ledger.d.ts +17 -2
  149. package/dist/core/orchestration/delegation-ledger.d.ts.map +1 -1
  150. package/dist/core/orchestration/delegation-ledger.js +78 -3
  151. package/dist/core/orchestration/delegation-ledger.js.map +1 -1
  152. package/dist/core/orchestration/event-store.d.ts +1 -0
  153. package/dist/core/orchestration/event-store.d.ts.map +1 -1
  154. package/dist/core/orchestration/event-store.js +78 -38
  155. package/dist/core/orchestration/event-store.js.map +1 -1
  156. package/dist/core/orchestration/profile-registry.d.ts.map +1 -1
  157. package/dist/core/orchestration/profile-registry.js +81 -41
  158. package/dist/core/orchestration/profile-registry.js.map +1 -1
  159. package/dist/core/orchestration/profile-store.d.ts.map +1 -1
  160. package/dist/core/orchestration/profile-store.js +18 -4
  161. package/dist/core/orchestration/profile-store.js.map +1 -1
  162. package/dist/core/orchestration/risk-budget.d.ts +2 -0
  163. package/dist/core/orchestration/risk-budget.d.ts.map +1 -1
  164. package/dist/core/orchestration/risk-budget.js +26 -0
  165. package/dist/core/orchestration/risk-budget.js.map +1 -1
  166. package/dist/core/orchestration/task-runtime.d.ts +13 -1
  167. package/dist/core/orchestration/task-runtime.d.ts.map +1 -1
  168. package/dist/core/orchestration/task-runtime.js +127 -16
  169. package/dist/core/orchestration/task-runtime.js.map +1 -1
  170. package/dist/core/orchestration/worker-execution-contract.d.ts +3 -1
  171. package/dist/core/orchestration/worker-execution-contract.d.ts.map +1 -1
  172. package/dist/core/orchestration/worker-execution-contract.js +75 -23
  173. package/dist/core/orchestration/worker-execution-contract.js.map +1 -1
  174. package/dist/core/orchestration/worker-result-adapter.d.ts +9 -3
  175. package/dist/core/orchestration/worker-result-adapter.d.ts.map +1 -1
  176. package/dist/core/orchestration/worker-result-adapter.js +167 -14
  177. package/dist/core/orchestration/worker-result-adapter.js.map +1 -1
  178. package/dist/core/reflection-controller.d.ts +1 -1
  179. package/dist/core/reflection-controller.d.ts.map +1 -1
  180. package/dist/core/reflection-controller.js +90 -54
  181. package/dist/core/reflection-controller.js.map +1 -1
  182. package/dist/core/research/evidence-bundle.d.ts +20 -0
  183. package/dist/core/research/evidence-bundle.d.ts.map +1 -1
  184. package/dist/core/research/evidence-bundle.js +173 -69
  185. package/dist/core/research/evidence-bundle.js.map +1 -1
  186. package/dist/core/runtime-builder.d.ts +7 -0
  187. package/dist/core/runtime-builder.d.ts.map +1 -1
  188. package/dist/core/runtime-builder.js +15 -1
  189. package/dist/core/runtime-builder.js.map +1 -1
  190. package/dist/core/session-artifact-bundle.d.ts +35 -0
  191. package/dist/core/session-artifact-bundle.d.ts.map +1 -0
  192. package/dist/core/session-artifact-bundle.js +61 -0
  193. package/dist/core/session-artifact-bundle.js.map +1 -0
  194. package/dist/core/tools/delegate-status.d.ts +6 -1
  195. package/dist/core/tools/delegate-status.d.ts.map +1 -1
  196. package/dist/core/tools/delegate-status.js +100 -18
  197. package/dist/core/tools/delegate-status.js.map +1 -1
  198. package/dist/core/tools/delegate.d.ts +9 -1
  199. package/dist/core/tools/delegate.d.ts.map +1 -1
  200. package/dist/core/tools/delegate.js +323 -61
  201. package/dist/core/tools/delegate.js.map +1 -1
  202. package/dist/core/tools/run-process.d.ts +1 -1
  203. package/dist/core/tools/run-process.d.ts.map +1 -1
  204. package/dist/core/tools/run-process.js +69 -9
  205. package/dist/core/tools/run-process.js.map +1 -1
  206. package/dist/core/tools/shell-contract-router.d.ts.map +1 -1
  207. package/dist/core/tools/shell-contract-router.js +12 -5
  208. package/dist/core/tools/shell-contract-router.js.map +1 -1
  209. package/dist/core/util/bounded-file.d.ts +15 -0
  210. package/dist/core/util/bounded-file.d.ts.map +1 -0
  211. package/dist/core/util/bounded-file.js +120 -0
  212. package/dist/core/util/bounded-file.js.map +1 -0
  213. package/dist/core/util/bounded-jsonl.d.ts.map +1 -1
  214. package/dist/core/util/bounded-jsonl.js +119 -9
  215. package/dist/core/util/bounded-jsonl.js.map +1 -1
  216. package/dist/core/util/bounded-value.d.ts +3 -0
  217. package/dist/core/util/bounded-value.d.ts.map +1 -0
  218. package/dist/core/util/bounded-value.js +12 -0
  219. package/dist/core/util/bounded-value.js.map +1 -0
  220. package/dist/core/util/value-guards.d.ts +2 -0
  221. package/dist/core/util/value-guards.d.ts.map +1 -1
  222. package/dist/core/util/value-guards.js +5 -0
  223. package/dist/core/util/value-guards.js.map +1 -1
  224. package/dist/modes/interactive/components/session-selector.d.ts.map +1 -1
  225. package/dist/modes/interactive/components/session-selector.js +27 -44
  226. package/dist/modes/interactive/components/session-selector.js.map +1 -1
  227. package/docs/tool-repair.md +3 -0
  228. package/docs/windows.md +4 -2
  229. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  230. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  231. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  232. package/examples/extensions/sandbox/package-lock.json +2 -2
  233. package/examples/extensions/sandbox/package.json +1 -1
  234. package/examples/extensions/with-deps/package-lock.json +2 -2
  235. package/examples/extensions/with-deps/package.json +1 -1
  236. package/npm-shrinkwrap.json +12 -12
  237. package/package.json +4 -4
@@ -1,7 +1,8 @@
1
1
  import { randomUUID } from "node:crypto";
2
2
  import { isDeepStrictEqual } from "node:util";
3
3
  import { createAgentIdentity } from "./agent-resume.js";
4
- import { isHarnessCapability, ORCHESTRATION_SCHEMA_VERSION, toJsonObject, } from "./contracts.js";
4
+ import { validateAttemptUsageSnapshot } from "./attempt-usage.js";
5
+ import { isHarnessCapability, MAX_ORCHESTRATION_COLLECTION_LENGTH, MAX_ORCHESTRATION_DISPATCH_INSTRUCTIONS_LENGTH, MAX_ORCHESTRATION_IDENTIFIER_LENGTH, MAX_ORCHESTRATION_MODEL_PROVIDER_LENGTH, ORCHESTRATION_SCHEMA_VERSION, toJsonObject, } from "./contracts.js";
5
6
  import { OrchestrationSnapshotRequiredError } from "./event-store.js";
6
7
  import { validateRiskBudget } from "./risk-budget.js";
7
8
  import { parseWorkerExecutionContract } from "./worker-execution-contract.js";
@@ -79,11 +80,45 @@ function stringArray(value, label) {
79
80
  }
80
81
  return [...value];
81
82
  }
83
+ function dispatchIdentifier(value, label) {
84
+ const identifier = string(value, label);
85
+ if (identifier.length > MAX_ORCHESTRATION_IDENTIFIER_LENGTH) {
86
+ throw new DurableTaskRuntimeError(`${label} exceeds its durable size bound.`);
87
+ }
88
+ return identifier;
89
+ }
90
+ function optionalDispatchIdentifier(value, label, maxLength = MAX_ORCHESTRATION_IDENTIFIER_LENGTH) {
91
+ if (value === undefined)
92
+ return undefined;
93
+ const identifier = string(value, label);
94
+ if (identifier.length > maxLength)
95
+ throw new DurableTaskRuntimeError(`${label} exceeds its durable size bound.`);
96
+ return identifier;
97
+ }
98
+ function dispatchInstructions(value, label) {
99
+ const instructions = string(value, label);
100
+ if (instructions.length > MAX_ORCHESTRATION_DISPATCH_INSTRUCTIONS_LENGTH) {
101
+ throw new DurableTaskRuntimeError(`${label} exceeds its durable size bound.`);
102
+ }
103
+ return instructions;
104
+ }
105
+ function dispatchIdentifierArray(value, label) {
106
+ if (!Array.isArray(value) ||
107
+ value.length > MAX_ORCHESTRATION_COLLECTION_LENGTH ||
108
+ !value.every((entry) => typeof entry === "string" && entry.length > 0 && entry.length <= MAX_ORCHESTRATION_IDENTIFIER_LENGTH)) {
109
+ throw new DurableTaskRuntimeError(`${label} must be a bounded identifier array.`);
110
+ }
111
+ if (new Set(value).size !== value.length) {
112
+ throw new DurableTaskRuntimeError(`${label} contains duplicates.`);
113
+ }
114
+ return [...value];
115
+ }
82
116
  const DISPATCH_FIELDS = new Set([
83
117
  "taskId",
84
118
  "profileId",
85
119
  "instructions",
86
120
  "resourcePointerIds",
121
+ "requirementIds",
87
122
  "executionKind",
88
123
  "logicalLaneId",
89
124
  "dispatchSequence",
@@ -101,11 +136,10 @@ function dispatchFromValue(value, label) {
101
136
  if (executionKind !== undefined && executionKind !== "in-process" && executionKind !== "managed-process") {
102
137
  throw new DurableTaskRuntimeError(`${label}.executionKind is invalid.`);
103
138
  }
104
- for (const field of ["logicalLaneId", "provider", "authorizationId", "worktreeLaneKey"]) {
105
- if (dispatch[field] !== undefined && typeof dispatch[field] !== "string") {
106
- throw new DurableTaskRuntimeError(`${label}.${field} is invalid.`);
107
- }
108
- }
139
+ const logicalLaneId = optionalDispatchIdentifier(dispatch.logicalLaneId, `${label}.logicalLaneId`);
140
+ const provider = optionalDispatchIdentifier(dispatch.provider, `${label}.provider`, MAX_ORCHESTRATION_MODEL_PROVIDER_LENGTH);
141
+ const authorizationId = optionalDispatchIdentifier(dispatch.authorizationId, `${label}.authorizationId`);
142
+ const worktreeLaneKey = optionalDispatchIdentifier(dispatch.worktreeLaneKey, `${label}.worktreeLaneKey`);
109
143
  if (dispatch.dispatchSequence !== undefined &&
110
144
  (!Number.isSafeInteger(dispatch.dispatchSequence) || Number(dispatch.dispatchSequence) < 1)) {
111
145
  throw new DurableTaskRuntimeError(`${label}.dispatchSequence is invalid.`);
@@ -123,16 +157,19 @@ function dispatchFromValue(value, label) {
123
157
  throw new DurableTaskRuntimeError(`${label} cannot combine a worker execution contract with managed execution.`);
124
158
  }
125
159
  return {
126
- taskId: string(dispatch.taskId, `${label}.taskId`),
127
- profileId: string(dispatch.profileId, `${label}.profileId`),
128
- instructions: string(dispatch.instructions, `${label}.instructions`),
129
- resourcePointerIds: stringArray(dispatch.resourcePointerIds, `${label}.resourcePointerIds`),
160
+ taskId: dispatchIdentifier(dispatch.taskId, `${label}.taskId`),
161
+ profileId: dispatchIdentifier(dispatch.profileId, `${label}.profileId`),
162
+ instructions: dispatchInstructions(dispatch.instructions, `${label}.instructions`),
163
+ resourcePointerIds: dispatchIdentifierArray(dispatch.resourcePointerIds, `${label}.resourcePointerIds`),
164
+ requirementIds: dispatch.requirementIds === undefined
165
+ ? []
166
+ : dispatchIdentifierArray(dispatch.requirementIds, `${label}.requirementIds`),
130
167
  ...(executionKind ? { executionKind } : {}),
131
- ...(typeof dispatch.logicalLaneId === "string" ? { logicalLaneId: dispatch.logicalLaneId } : {}),
168
+ ...(logicalLaneId ? { logicalLaneId } : {}),
132
169
  ...(typeof dispatch.dispatchSequence === "number" ? { dispatchSequence: dispatch.dispatchSequence } : {}),
133
- ...(typeof dispatch.provider === "string" ? { provider: dispatch.provider } : {}),
134
- ...(typeof dispatch.authorizationId === "string" ? { authorizationId: dispatch.authorizationId } : {}),
135
- ...(typeof dispatch.worktreeLaneKey === "string" ? { worktreeLaneKey: dispatch.worktreeLaneKey } : {}),
170
+ ...(provider ? { provider } : {}),
171
+ ...(authorizationId ? { authorizationId } : {}),
172
+ ...(worktreeLaneKey ? { worktreeLaneKey } : {}),
136
173
  ...(executionContract ? { executionContract } : {}),
137
174
  };
138
175
  }
@@ -166,6 +203,7 @@ function leaseFromPayload(payload) {
166
203
  }
167
204
  function checkpointFromPayload(payload) {
168
205
  const checkpoint = record(payload.checkpoint, "checkpoint");
206
+ const usage = checkpoint.usage === undefined ? undefined : usageFromPayload(checkpoint.usage, "checkpoint.usage");
169
207
  return {
170
208
  checkpointId: string(checkpoint.checkpointId, "checkpoint.checkpointId"),
171
209
  attemptId: string(checkpoint.attemptId, "checkpoint.attemptId"),
@@ -173,9 +211,41 @@ function checkpointFromPayload(payload) {
173
211
  summary: string(checkpoint.summary, "checkpoint.summary"),
174
212
  artifactIds: stringArray(checkpoint.artifactIds, "checkpoint.artifactIds"),
175
213
  evidenceIds: stringArray(checkpoint.evidenceIds, "checkpoint.evidenceIds"),
214
+ ...(usage ? { usage } : {}),
176
215
  createdAt: string(checkpoint.createdAt, "checkpoint.createdAt"),
177
216
  };
178
217
  }
218
+ function usageFromPayload(value, label) {
219
+ const usage = record(value, label);
220
+ const expectedFields = [
221
+ "toolCalls",
222
+ "inputTokens",
223
+ "outputTokens",
224
+ "cacheReadTokens",
225
+ "cacheWriteTokens",
226
+ "totalTokens",
227
+ "costUsd",
228
+ "activeWallClockMs",
229
+ ];
230
+ const unexpected = Object.keys(usage).find((field) => !expectedFields.includes(field));
231
+ if (unexpected)
232
+ throw new DurableTaskRuntimeError(`${label}.${unexpected} is unsupported.`);
233
+ try {
234
+ return validateAttemptUsageSnapshot({
235
+ toolCalls: number(usage.toolCalls, `${label}.toolCalls`),
236
+ inputTokens: number(usage.inputTokens, `${label}.inputTokens`),
237
+ outputTokens: number(usage.outputTokens, `${label}.outputTokens`),
238
+ cacheReadTokens: number(usage.cacheReadTokens, `${label}.cacheReadTokens`),
239
+ cacheWriteTokens: number(usage.cacheWriteTokens, `${label}.cacheWriteTokens`),
240
+ totalTokens: number(usage.totalTokens, `${label}.totalTokens`),
241
+ costUsd: number(usage.costUsd, `${label}.costUsd`),
242
+ activeWallClockMs: number(usage.activeWallClockMs, `${label}.activeWallClockMs`),
243
+ }, label);
244
+ }
245
+ catch (error) {
246
+ throw new DurableTaskRuntimeError(error instanceof Error ? error.message : String(error));
247
+ }
248
+ }
179
249
  function resultFromPayload(payload) {
180
250
  return structuredClone(record(payload.result, "result"));
181
251
  }
@@ -552,6 +622,14 @@ export function reduceOrchestrationEvent(projection, event) {
552
622
  const attempt = attempts[attemptId];
553
623
  if (!attempt)
554
624
  throw new DurableTaskRuntimeError(`Unknown attempt '${attemptId}'.`);
625
+ const leaseId = string(event.payload.leaseId, "attempt.suspended.leaseId");
626
+ const fencingToken = number(event.payload.fencingToken, "attempt.suspended.fencingToken");
627
+ if (!attempt.lease || attempt.lease.leaseId !== leaseId || attempt.lease.fencingToken !== fencingToken) {
628
+ throw new DurableTaskRuntimeError(`Attempt '${attemptId}' lease or fencing token is stale.`);
629
+ }
630
+ if (attempt.status !== "leased" && attempt.status !== "running") {
631
+ throw new DurableTaskRuntimeError(`Attempt '${attemptId}' cannot suspend from '${attempt.status}'.`);
632
+ }
555
633
  attempts[attemptId] = {
556
634
  ...attempt,
557
635
  status: "suspended",
@@ -1111,6 +1189,7 @@ export class DurableTaskRuntime {
1111
1189
  summary: args.summary.trim(),
1112
1190
  artifactIds: [...(args.artifactIds ?? [])],
1113
1191
  evidenceIds: [...(args.evidenceIds ?? [])],
1192
+ ...(args.usage ? { usage: usageFromPayload(args.usage, "checkpoint.usage") } : {}),
1114
1193
  createdAt: this.nowIso(),
1115
1194
  };
1116
1195
  if (!checkpoint.summary)
@@ -1208,6 +1287,38 @@ export class DurableTaskRuntime {
1208
1287
  });
1209
1288
  return structuredClone(this.state.attempts[attemptId]);
1210
1289
  }
1290
+ /**
1291
+ * The only runtime suspension transition. Callers must present the exact current owner and lease
1292
+ * fence; liveness/restart policy stays outside this deterministic runtime.
1293
+ */
1294
+ suspendBoundAttempt(args) {
1295
+ this.refresh();
1296
+ const attempt = this.requireAttempt(args.attemptId);
1297
+ if (!attempt.agentId || !attempt.lease || !["leased", "running"].includes(attempt.status)) {
1298
+ throw new DurableTaskRuntimeError(`Attempt '${args.attemptId}' is not a live agent-bound attempt.`);
1299
+ }
1300
+ if (attempt.lease.ownerId !== args.ownerId) {
1301
+ throw new DurableTaskRuntimeError(`Attempt '${args.attemptId}' is not owned by '${args.ownerId}'.`);
1302
+ }
1303
+ if (attempt.lease.leaseId !== args.leaseId || attempt.lease.fencingToken !== args.fencingToken) {
1304
+ throw new DurableTaskRuntimeError(`Attempt '${args.attemptId}' lease or fencing token is stale.`);
1305
+ }
1306
+ if (!args.reasonCode.trim())
1307
+ throw new DurableTaskRuntimeError("Suspension reason is required.");
1308
+ this.commit({
1309
+ type: "attempt.suspended",
1310
+ aggregateId: args.attemptId,
1311
+ actor: "runtime",
1312
+ idempotencyKey: `attempt-suspended:${args.attemptId}:${args.leaseId}:${args.fencingToken}`,
1313
+ payload: toJsonObject({
1314
+ attemptId: args.attemptId,
1315
+ leaseId: args.leaseId,
1316
+ fencingToken: args.fencingToken,
1317
+ reasonCode: args.reasonCode.trim(),
1318
+ }),
1319
+ });
1320
+ return structuredClone(this.state.attempts[args.attemptId]);
1321
+ }
1211
1322
  failTask(taskId, reasonCode) {
1212
1323
  this.refresh();
1213
1324
  const task = this.state.tasks[taskId];
@@ -1294,7 +1405,7 @@ export class DurableTaskRuntime {
1294
1405
  });
1295
1406
  return structuredClone(this.state.agents[agentId]);
1296
1407
  }
1297
- resumeAttempt(attemptId, agentId, ttlMs) {
1408
+ resumeAttempt(attemptId, agentId, ttlMs, ownerId = agentId) {
1298
1409
  this.refresh();
1299
1410
  const attempt = this.requireAttempt(attemptId);
1300
1411
  const agent = this.state.agents[agentId];
@@ -1310,7 +1421,7 @@ export class DurableTaskRuntime {
1310
1421
  const lease = {
1311
1422
  leaseId: `lease-${this.createId()}`,
1312
1423
  attemptId,
1313
- ownerId: agentId,
1424
+ ownerId,
1314
1425
  fencingToken: (attempt.lease?.fencingToken ?? 0) + 1,
1315
1426
  issuedAt: new Date(issuedAtMs).toISOString(),
1316
1427
  expiresAt: new Date(issuedAtMs + ttlMs).toISOString(),