@namzu/sdk 53.2.2 → 55.0.0

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 (278) hide show
  1. package/CHANGELOG.md +56 -0
  2. package/dist/agents/QueryAgent.d.ts.map +1 -1
  3. package/dist/agents/QueryAgent.js +1 -0
  4. package/dist/agents/QueryAgent.js.map +1 -1
  5. package/dist/compaction/context-breakdown.d.ts +85 -0
  6. package/dist/compaction/context-breakdown.d.ts.map +1 -0
  7. package/dist/compaction/context-breakdown.js +149 -0
  8. package/dist/compaction/context-breakdown.js.map +1 -0
  9. package/dist/compaction/extractor.d.ts.map +1 -1
  10. package/dist/compaction/extractor.js +5 -1
  11. package/dist/compaction/extractor.js.map +1 -1
  12. package/dist/compaction/managers/structured.d.ts.map +1 -1
  13. package/dist/compaction/managers/structured.js +5 -0
  14. package/dist/compaction/managers/structured.js.map +1 -1
  15. package/dist/compaction/manual.d.ts.map +1 -1
  16. package/dist/compaction/manual.js +6 -0
  17. package/dist/compaction/manual.js.map +1 -1
  18. package/dist/compaction/serializer.d.ts +6 -0
  19. package/dist/compaction/serializer.d.ts.map +1 -1
  20. package/dist/compaction/serializer.js +21 -3
  21. package/dist/compaction/serializer.js.map +1 -1
  22. package/dist/compaction/token-estimate.d.ts +2 -0
  23. package/dist/compaction/token-estimate.d.ts.map +1 -1
  24. package/dist/compaction/token-estimate.js +4 -0
  25. package/dist/compaction/token-estimate.js.map +1 -1
  26. package/dist/compaction/verifier.d.ts.map +1 -1
  27. package/dist/compaction/verifier.js +27 -6
  28. package/dist/compaction/verifier.js.map +1 -1
  29. package/dist/constants/compaction/index.d.ts +1 -0
  30. package/dist/constants/compaction/index.d.ts.map +1 -1
  31. package/dist/constants/compaction/index.js +1 -0
  32. package/dist/constants/compaction/index.js.map +1 -1
  33. package/dist/manager/resident/proposal.d.ts +2 -2
  34. package/dist/manager/resident/store.d.ts +4 -4
  35. package/dist/prompt/coding-agent-doctrine.d.ts +3 -3
  36. package/dist/prompt/coding-agent-doctrine.d.ts.map +1 -1
  37. package/dist/prompt/coding-agent-doctrine.js +18 -20
  38. package/dist/prompt/coding-agent-doctrine.js.map +1 -1
  39. package/dist/public-runtime.d.ts +8 -3
  40. package/dist/public-runtime.d.ts.map +1 -1
  41. package/dist/public-runtime.js +7 -2
  42. package/dist/public-runtime.js.map +1 -1
  43. package/dist/runtime/cache-clock.d.ts +39 -0
  44. package/dist/runtime/cache-clock.d.ts.map +1 -0
  45. package/dist/runtime/cache-clock.js +48 -0
  46. package/dist/runtime/cache-clock.js.map +1 -0
  47. package/dist/runtime/query/checkpoint.d.ts +12 -2
  48. package/dist/runtime/query/checkpoint.d.ts.map +1 -1
  49. package/dist/runtime/query/checkpoint.js +42 -8
  50. package/dist/runtime/query/checkpoint.js.map +1 -1
  51. package/dist/runtime/query/compact-session.d.ts +37 -2
  52. package/dist/runtime/query/compact-session.d.ts.map +1 -1
  53. package/dist/runtime/query/compact-session.js +77 -3
  54. package/dist/runtime/query/compact-session.js.map +1 -1
  55. package/dist/runtime/query/executor/tool-call-admission.d.ts.map +1 -1
  56. package/dist/runtime/query/executor/tool-call-admission.js +3 -0
  57. package/dist/runtime/query/executor/tool-call-admission.js.map +1 -1
  58. package/dist/runtime/query/executor.d.ts +39 -1
  59. package/dist/runtime/query/executor.d.ts.map +1 -1
  60. package/dist/runtime/query/executor.js +115 -7
  61. package/dist/runtime/query/executor.js.map +1 -1
  62. package/dist/runtime/query/index.d.ts +18 -0
  63. package/dist/runtime/query/index.d.ts.map +1 -1
  64. package/dist/runtime/query/index.js +20 -1
  65. package/dist/runtime/query/index.js.map +1 -1
  66. package/dist/runtime/query/iteration/index.d.ts.map +1 -1
  67. package/dist/runtime/query/iteration/index.js +25 -8
  68. package/dist/runtime/query/iteration/index.js.map +1 -1
  69. package/dist/runtime/query/iteration/phases/context.d.ts +24 -2
  70. package/dist/runtime/query/iteration/phases/context.d.ts.map +1 -1
  71. package/dist/runtime/query/iteration/phases/context.js +22 -22
  72. package/dist/runtime/query/iteration/phases/context.js.map +1 -1
  73. package/dist/runtime/query/iteration/phases/per-call-review.d.ts +78 -0
  74. package/dist/runtime/query/iteration/phases/per-call-review.d.ts.map +1 -0
  75. package/dist/runtime/query/iteration/phases/per-call-review.js +494 -0
  76. package/dist/runtime/query/iteration/phases/per-call-review.js.map +1 -0
  77. package/dist/runtime/query/iteration/phases/tool-review.d.ts.map +1 -1
  78. package/dist/runtime/query/iteration/phases/tool-review.js +129 -62
  79. package/dist/runtime/query/iteration/phases/tool-review.js.map +1 -1
  80. package/dist/runtime/query/iteration/step-context.d.ts +14 -0
  81. package/dist/runtime/query/iteration/step-context.d.ts.map +1 -1
  82. package/dist/runtime/query/iteration/step-context.js +29 -0
  83. package/dist/runtime/query/iteration/step-context.js.map +1 -1
  84. package/dist/runtime/query/iteration/step-shaping.d.ts.map +1 -1
  85. package/dist/runtime/query/iteration/step-shaping.js +6 -2
  86. package/dist/runtime/query/iteration/step-shaping.js.map +1 -1
  87. package/dist/runtime/query/prepare-turn.d.ts.map +1 -1
  88. package/dist/runtime/query/prepare-turn.js +16 -3
  89. package/dist/runtime/query/prepare-turn.js.map +1 -1
  90. package/dist/runtime/query/project-instructions.d.ts +24 -5
  91. package/dist/runtime/query/project-instructions.d.ts.map +1 -1
  92. package/dist/runtime/query/project-instructions.js +107 -35
  93. package/dist/runtime/query/project-instructions.js.map +1 -1
  94. package/dist/runtime/query/prompt.d.ts +6 -0
  95. package/dist/runtime/query/prompt.d.ts.map +1 -1
  96. package/dist/runtime/query/prompt.js +10 -49
  97. package/dist/runtime/query/prompt.js.map +1 -1
  98. package/dist/runtime/query/resume-pending.d.ts +8 -0
  99. package/dist/runtime/query/resume-pending.d.ts.map +1 -1
  100. package/dist/runtime/query/resume-pending.js +101 -0
  101. package/dist/runtime/query/resume-pending.js.map +1 -1
  102. package/dist/runtime/query/review-policy.d.ts +18 -0
  103. package/dist/runtime/query/review-policy.d.ts.map +1 -1
  104. package/dist/runtime/query/review-policy.js +10 -0
  105. package/dist/runtime/query/review-policy.js.map +1 -1
  106. package/dist/runtime/query/steering.d.ts +55 -56
  107. package/dist/runtime/query/steering.d.ts.map +1 -1
  108. package/dist/runtime/query/steering.js +78 -72
  109. package/dist/runtime/query/steering.js.map +1 -1
  110. package/dist/store/budget/disk.js +4 -1
  111. package/dist/store/budget/disk.js.map +1 -1
  112. package/dist/tools/admit-facts.d.ts.map +1 -1
  113. package/dist/tools/admit-facts.js +6 -0
  114. package/dist/tools/admit-facts.js.map +1 -1
  115. package/dist/tools/builtins/bash.d.ts +8 -0
  116. package/dist/tools/builtins/bash.d.ts.map +1 -1
  117. package/dist/tools/builtins/bash.js +36 -27
  118. package/dist/tools/builtins/bash.js.map +1 -1
  119. package/dist/tools/builtins/browser.d.ts.map +1 -1
  120. package/dist/tools/builtins/browser.js +38 -12
  121. package/dist/tools/builtins/browser.js.map +1 -1
  122. package/dist/tools/builtins/edit-apply.d.ts +7 -4
  123. package/dist/tools/builtins/edit-apply.d.ts.map +1 -1
  124. package/dist/tools/builtins/edit-apply.js +3 -0
  125. package/dist/tools/builtins/edit-apply.js.map +1 -1
  126. package/dist/tools/builtins/edit.d.ts.map +1 -1
  127. package/dist/tools/builtins/edit.js +31 -11
  128. package/dist/tools/builtins/edit.js.map +1 -1
  129. package/dist/tools/builtins/exit-semantics.d.ts +31 -0
  130. package/dist/tools/builtins/exit-semantics.d.ts.map +1 -0
  131. package/dist/tools/builtins/exit-semantics.js +198 -0
  132. package/dist/tools/builtins/exit-semantics.js.map +1 -0
  133. package/dist/tools/builtins/job.js +1 -1
  134. package/dist/tools/builtins/job.js.map +1 -1
  135. package/dist/tools/builtins/skill.js +1 -1
  136. package/dist/tools/builtins/skill.js.map +1 -1
  137. package/dist/tools/builtins/structuredOutput.js +1 -1
  138. package/dist/tools/builtins/structuredOutput.js.map +1 -1
  139. package/dist/tools/builtins/verify-outputs.js +1 -1
  140. package/dist/tools/builtins/verify-outputs.js.map +1 -1
  141. package/dist/tools/builtins/write-file.js +11 -6
  142. package/dist/tools/builtins/write-file.js.map +1 -1
  143. package/dist/tools/coordinator/ask-user-question.d.ts +6 -0
  144. package/dist/tools/coordinator/ask-user-question.d.ts.map +1 -1
  145. package/dist/tools/coordinator/ask-user-question.js +6 -1
  146. package/dist/tools/coordinator/ask-user-question.js.map +1 -1
  147. package/dist/tools/coordinator/index.d.ts.map +1 -1
  148. package/dist/tools/coordinator/index.js +10 -3
  149. package/dist/tools/coordinator/index.js.map +1 -1
  150. package/dist/tools/memory/delete.js +1 -1
  151. package/dist/tools/memory/delete.js.map +1 -1
  152. package/dist/tools/memory/read.js +1 -1
  153. package/dist/tools/memory/read.js.map +1 -1
  154. package/dist/tools/memory/save.d.ts.map +1 -1
  155. package/dist/tools/memory/save.js +4 -3
  156. package/dist/tools/memory/save.js.map +1 -1
  157. package/dist/tools/memory/search.js +1 -1
  158. package/dist/tools/memory/search.js.map +1 -1
  159. package/dist/tools/memory/update.js +1 -1
  160. package/dist/tools/memory/update.js.map +1 -1
  161. package/dist/tools/schedules/loop-tool.d.ts.map +1 -1
  162. package/dist/tools/schedules/loop-tool.js +4 -2
  163. package/dist/tools/schedules/loop-tool.js.map +1 -1
  164. package/dist/tools/schedules/schedule-tool.js +2 -2
  165. package/dist/tools/schedules/schedule-tool.js.map +1 -1
  166. package/dist/tools/task/create.js +1 -1
  167. package/dist/tools/task/create.js.map +1 -1
  168. package/dist/tools/untrusted-envelope.js +1 -1
  169. package/dist/tools/untrusted-envelope.js.map +1 -1
  170. package/dist/toolsets/manager.d.ts.map +1 -1
  171. package/dist/toolsets/manager.js +6 -1
  172. package/dist/toolsets/manager.js.map +1 -1
  173. package/dist/turn/evidence-query.d.ts.map +1 -1
  174. package/dist/turn/evidence-query.js +16 -1
  175. package/dist/turn/evidence-query.js.map +1 -1
  176. package/dist/turn/evidence-recall.js +1 -1
  177. package/dist/turn/evidence-recall.js.map +1 -1
  178. package/dist/types/agent/base.d.ts +7 -0
  179. package/dist/types/agent/base.d.ts.map +1 -1
  180. package/dist/types/common/index.d.ts +19 -0
  181. package/dist/types/common/index.d.ts.map +1 -1
  182. package/dist/types/common/index.js +9 -0
  183. package/dist/types/common/index.js.map +1 -1
  184. package/dist/types/hitl/index.d.ts +66 -0
  185. package/dist/types/hitl/index.d.ts.map +1 -1
  186. package/dist/types/hitl/index.js.map +1 -1
  187. package/dist/types/message/index.d.ts +8 -0
  188. package/dist/types/message/index.d.ts.map +1 -1
  189. package/dist/types/message/index.js +12 -2
  190. package/dist/types/message/index.js.map +1 -1
  191. package/dist/types/message/notice-frame.d.ts +41 -0
  192. package/dist/types/message/notice-frame.d.ts.map +1 -0
  193. package/dist/types/message/notice-frame.js +65 -0
  194. package/dist/types/message/notice-frame.js.map +1 -0
  195. package/dist/types/provider/chat.d.ts +8 -0
  196. package/dist/types/provider/chat.d.ts.map +1 -1
  197. package/dist/types/provider/config.d.ts +6 -0
  198. package/dist/types/provider/config.d.ts.map +1 -1
  199. package/dist/types/session/checkpoint.d.ts +52 -0
  200. package/dist/types/session/checkpoint.d.ts.map +1 -1
  201. package/dist/types/session/checkpoint.js +5 -0
  202. package/dist/types/session/checkpoint.js.map +1 -1
  203. package/dist/types/session/events.d.ts +9 -0
  204. package/dist/types/session/events.d.ts.map +1 -1
  205. package/dist/types/session/events.js.map +1 -1
  206. package/dist/types/session/records.d.ts +181 -6
  207. package/dist/types/session/records.d.ts.map +1 -1
  208. package/dist/types/session/records.js +1 -1
  209. package/dist/types/session/records.js.map +1 -1
  210. package/dist/types/tool/presentation.d.ts +17 -1
  211. package/dist/types/tool/presentation.d.ts.map +1 -1
  212. package/package.json +1 -1
  213. package/src/agents/QueryAgent.ts +1 -0
  214. package/src/compaction/context-breakdown.ts +228 -0
  215. package/src/compaction/extractor.ts +8 -1
  216. package/src/compaction/managers/structured.ts +3 -0
  217. package/src/compaction/manual.ts +5 -0
  218. package/src/compaction/serializer.ts +28 -3
  219. package/src/compaction/token-estimate.ts +5 -0
  220. package/src/compaction/verifier.ts +32 -6
  221. package/src/constants/compaction/index.ts +1 -0
  222. package/src/prompt/coding-agent-doctrine.ts +18 -20
  223. package/src/public-runtime.ts +24 -2
  224. package/src/runtime/cache-clock.ts +67 -0
  225. package/src/runtime/query/checkpoint.ts +49 -8
  226. package/src/runtime/query/compact-session.ts +101 -3
  227. package/src/runtime/query/executor/tool-call-admission.ts +3 -0
  228. package/src/runtime/query/executor.ts +165 -15
  229. package/src/runtime/query/index.ts +45 -1
  230. package/src/runtime/query/iteration/index.ts +27 -6
  231. package/src/runtime/query/iteration/phases/context.ts +37 -11
  232. package/src/runtime/query/iteration/phases/per-call-review.ts +598 -0
  233. package/src/runtime/query/iteration/phases/tool-review.ts +168 -83
  234. package/src/runtime/query/iteration/step-context.ts +29 -0
  235. package/src/runtime/query/iteration/step-shaping.ts +6 -2
  236. package/src/runtime/query/prepare-turn.ts +18 -1
  237. package/src/runtime/query/project-instructions.ts +119 -38
  238. package/src/runtime/query/prompt.ts +11 -54
  239. package/src/runtime/query/resume-pending.ts +131 -0
  240. package/src/runtime/query/review-policy.ts +28 -0
  241. package/src/runtime/query/steering.ts +100 -96
  242. package/src/store/budget/disk.ts +4 -1
  243. package/src/tools/admit-facts.ts +6 -0
  244. package/src/tools/builtins/bash.ts +38 -28
  245. package/src/tools/builtins/browser.ts +38 -12
  246. package/src/tools/builtins/edit-apply.ts +12 -2
  247. package/src/tools/builtins/edit.ts +38 -12
  248. package/src/tools/builtins/exit-semantics.ts +198 -0
  249. package/src/tools/builtins/job.ts +1 -1
  250. package/src/tools/builtins/skill.ts +1 -1
  251. package/src/tools/builtins/structuredOutput.ts +1 -1
  252. package/src/tools/builtins/verify-outputs.ts +1 -1
  253. package/src/tools/builtins/write-file.ts +11 -6
  254. package/src/tools/coordinator/ask-user-question.ts +12 -1
  255. package/src/tools/coordinator/index.ts +10 -3
  256. package/src/tools/memory/delete.ts +1 -1
  257. package/src/tools/memory/read.ts +1 -1
  258. package/src/tools/memory/save.ts +4 -3
  259. package/src/tools/memory/search.ts +1 -1
  260. package/src/tools/memory/update.ts +1 -1
  261. package/src/tools/schedules/loop-tool.ts +4 -2
  262. package/src/tools/schedules/schedule-tool.ts +2 -2
  263. package/src/tools/task/create.ts +1 -1
  264. package/src/tools/untrusted-envelope.ts +1 -1
  265. package/src/toolsets/manager.ts +6 -1
  266. package/src/turn/evidence-query.ts +19 -1
  267. package/src/turn/evidence-recall.ts +1 -1
  268. package/src/types/agent/base.ts +8 -0
  269. package/src/types/common/index.ts +27 -0
  270. package/src/types/hitl/index.ts +67 -0
  271. package/src/types/message/index.ts +20 -2
  272. package/src/types/message/notice-frame.ts +88 -0
  273. package/src/types/provider/chat.ts +8 -0
  274. package/src/types/provider/config.ts +6 -0
  275. package/src/types/session/checkpoint.ts +5 -0
  276. package/src/types/session/events.ts +6 -0
  277. package/src/types/session/records.ts +1 -1
  278. package/src/types/tool/presentation.ts +16 -0
@@ -102,6 +102,7 @@ import {
102
102
  streamWithProviderRejectedImageRecovery,
103
103
  } from './provider-rejected-image.js'
104
104
  import { type MediaRemoval, RequestRepair } from './request-repair.js'
105
+ import { placeBeforeLatestOperatorMessage } from './step-context.js'
105
106
  import {
106
107
  type StepShaping,
107
108
  appendWorkContext,
@@ -853,8 +854,8 @@ export class IterationOrchestrator {
853
854
  // there is no length check here — a second guard for the same
854
855
  // case is one more thing to keep in agreement with the first.
855
856
  const stepSkills = step.skills ? renderSkillsSection([...step.skills]) : null
856
- // A supervision change rides the same ephemeral slot, and for
857
- // the same reason: it applies to what happens next, not to the
857
+ // A supervision change is request-only context, and for the
858
+ // same reason: it applies to what happens next, not to the
858
859
  // run's history. The model plans around how closely it is being
859
860
  // watched — a turn that silently stops asking a human leaves it
860
861
  // batching destructive calls it expects to be reviewed, and one
@@ -879,7 +880,7 @@ export class IterationOrchestrator {
879
880
 
880
881
  // Request-only context: observations that need no system
881
882
  // authority and change from request to request. They ride
882
- // runtime-context messages of kind `step-context` after the
883
+ // runtime-context messages of kind `step-context`, most of them after the
883
884
  // history, which every driver keeps there and a caching driver
884
885
  // ends its breakpoint before — so a changed pin or a new turn
885
886
  // snapshot costs its own tokens, not a re-read of the history.
@@ -887,15 +888,27 @@ export class IterationOrchestrator {
887
888
  // (compaction preserves it there) and leaves the request's
888
889
  // system run here.
889
890
  const workingMemory = splitWorkingMemoryForRequest(baseMessages)
890
- const stepPreamble = [step.system, stepSkills, policyNotice, ...turnSections]
891
+ const stepPreamble = [step.system, stepSkills, ...turnSections]
891
892
  .filter(Boolean)
892
893
  .join('\n\n')
893
894
  const requestHistory = stepPreamble
894
895
  ? [...workingMemory.history, createSystemMessage(stepPreamble)]
895
896
  : [...workingMemory.history]
896
897
  if (workingMemory.context) requestHistory.push(workingMemory.context)
897
- if (contextText) requestHistory.push(stepContextMessage(contextText))
898
- if (step.context) requestHistory.push(stepContextMessage(step.context))
898
+ // The blocks of data that belong to this turn (recalled memory and
899
+ // evidence, the context contributions) sit just before the
900
+ // operator's latest message, so the request is the last thing the
901
+ // model reads. The short reminders and notices stay after it.
902
+ placeBeforeLatestOperatorMessage(
903
+ requestHistory,
904
+ [contextText, step.context]
905
+ .filter((text): text is string => Boolean(text))
906
+ .map(stepContextMessage),
907
+ )
908
+ // After the history, never ahead of it: a system message in front
909
+ // of the conversation moves the prefix every cached request shares,
910
+ // and a mode change would re-key the whole conversation.
911
+ if (policyNotice) requestHistory.push(stepContextMessage(policyNotice))
899
912
  const messages = projectRequestRichContent(
900
913
  this.projectObservations(requestHistory),
901
914
  this.ctx.turnConfig.maxRequestRichContentBytes ??
@@ -1201,6 +1214,14 @@ export class IterationOrchestrator {
1201
1214
  usage: recorder.tokenUsage,
1202
1215
  budget: recorder.budget?.summary(),
1203
1216
  cost: recorder.costInfo,
1217
+ ...(response.usage.cacheTtlMs !== undefined
1218
+ ? {
1219
+ cache: {
1220
+ ttlMs: response.usage.cacheTtlMs,
1221
+ touched: response.usage.cachedTokens + response.usage.cacheWriteTokens > 0,
1222
+ },
1223
+ }
1224
+ : {}),
1204
1225
  ...contextFigures,
1205
1226
  })
1206
1227
 
@@ -201,6 +201,8 @@ export interface IterationContext {
201
201
  readonly skillGrants?: SkillGrantSet
202
202
  /** See `QueryParams.reviewAllowedCalls`. Absent: allowed and granted batches skip review. */
203
203
  readonly reviewAllowedCalls?: () => boolean
204
+ /** See `QueryParams.perCallReview`. Absent: a batch is reviewed as a unit. */
205
+ readonly perCallReview?: import('../../../../types/hitl/index.js').PerCallReviewConfig
204
206
  /**
205
207
  * Absent when the host opted out with `repeatCallAdvisory: false`. The
206
208
  * opt-out is the ABSENCE, not a flag read at every call site, so a code
@@ -316,9 +318,10 @@ export async function awaitDecisionDurably(
316
318
  ctx: IterationContext,
317
319
  checkpoint: { readonly id: CheckpointId },
318
320
  request: Parameters<ResumeHandler>[0],
321
+ scope?: AskScope,
319
322
  ): Promise<HITLResumeDecision> {
320
323
  const delay = ctx.parkRecordDelayMs ?? PARK_RECORD_DELAY_MS
321
- const decisionPromise = awaitDecisionOrAbort(ctx, request)
324
+ const decisionPromise = awaitDecisionOrAbort(ctx, request, scope)
322
325
 
323
326
  let settled = false
324
327
  let recorded = false
@@ -423,9 +426,26 @@ export async function awaitDecisionDurably(
423
426
  * turns into `setStopReason('cancelled') + markCancelled + stop`. Fails closed:
424
427
  * a resume-handler rejection also resolves to `abort` rather than hanging.
425
428
  */
429
+ /**
430
+ * One question among several that are open at once (the per-call review).
431
+ *
432
+ * `signal` closes just this question; when it aborts and the turn itself was not
433
+ * cancelled, `closedAs` says what the question's answer is, so the park is
434
+ * recorded as what really ended it rather than as a cancelled turn.
435
+ */
436
+ export interface AskScope {
437
+ readonly signal: AbortSignal
438
+ readonly closedAs: () => HITLResumeDecision
439
+ }
440
+
426
441
  /** What a resume handler may read besides the request; see {@link ResumeContext}. */
427
- function resumeContextOf(ctx: IterationContext): ResumeContext {
428
- const signal = ctx.abortController?.signal
442
+ function resumeContextOf(ctx: IterationContext, scope?: AskScope): ResumeContext {
443
+ const turnSignal = ctx.abortController?.signal
444
+ const signal = scope
445
+ ? turnSignal
446
+ ? AbortSignal.any([turnSignal, scope.signal])
447
+ : scope.signal
448
+ : turnSignal
429
449
  return {
430
450
  transcript: () => ctx.recorder.messages,
431
451
  ...(signal ? { signal } : {}),
@@ -435,24 +455,30 @@ function resumeContextOf(ctx: IterationContext): ResumeContext {
435
455
  export async function awaitDecisionOrAbort(
436
456
  ctx: IterationContext,
437
457
  request: Parameters<ResumeHandler>[0],
458
+ scope?: AskScope,
438
459
  ): Promise<HITLResumeDecision> {
439
- const signal = ctx.abortController?.signal
460
+ const turnSignal = ctx.abortController?.signal
461
+ const signal = scope
462
+ ? turnSignal
463
+ ? AbortSignal.any([turnSignal, scope.signal])
464
+ : scope.signal
465
+ : turnSignal
440
466
  // No abort signal wired (e.g. a minimal test harness) → behave exactly as a
441
467
  // direct resumeHandler await, no race. In production TurnContextFactory always
442
468
  // provides the controller, so the race below is live.
443
- const resumeContext = resumeContextOf(ctx)
469
+ const resumeContext = resumeContextOf(ctx, scope)
444
470
  if (!signal) return ctx.resumeHandler(request, resumeContext)
445
- const abortDecision: HITLResumeDecision = {
446
- action: 'abort',
447
- reason: 'run aborted while parked for HITL',
448
- }
449
- if (signal.aborted) return abortDecision
471
+ const abortedDecision = (): HITLResumeDecision =>
472
+ scope && !turnSignal?.aborted
473
+ ? scope.closedAs()
474
+ : { action: 'abort', reason: 'run aborted while parked for HITL' }
475
+ if (signal.aborted) return abortedDecision()
450
476
  return new Promise<HITLResumeDecision>((resolve) => {
451
477
  let settled = false
452
478
  const onAbort = (): void => {
453
479
  if (settled) return
454
480
  settled = true
455
- resolve(abortDecision)
481
+ resolve(abortedDecision())
456
482
  }
457
483
  signal.addEventListener('abort', onAbort, { once: true })
458
484
  Promise.resolve(ctx.resumeHandler(request, resumeContext)).then(