@namzu/sdk 61.4.0 → 62.1.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 (338) hide show
  1. package/CHANGELOG.md +62 -0
  2. package/dist/agents/QueryAgent.d.ts.map +1 -1
  3. package/dist/agents/QueryAgent.js +2 -0
  4. package/dist/agents/QueryAgent.js.map +1 -1
  5. package/dist/bridge/a2a/mapper.d.ts.map +1 -1
  6. package/dist/bridge/a2a/mapper.js +2 -0
  7. package/dist/bridge/a2a/mapper.js.map +1 -1
  8. package/dist/bridge/acp/permission.d.ts +8 -0
  9. package/dist/bridge/acp/permission.d.ts.map +1 -1
  10. package/dist/bridge/acp/permission.js.map +1 -1
  11. package/dist/bridge/acp/server.d.ts.map +1 -1
  12. package/dist/bridge/acp/server.js +8 -1
  13. package/dist/bridge/acp/server.js.map +1 -1
  14. package/dist/bridge/sse/mapper.d.ts.map +1 -1
  15. package/dist/bridge/sse/mapper.js +13 -0
  16. package/dist/bridge/sse/mapper.js.map +1 -1
  17. package/dist/constants/tools/index.d.ts +2 -0
  18. package/dist/constants/tools/index.d.ts.map +1 -1
  19. package/dist/constants/tools/index.js +23 -0
  20. package/dist/constants/tools/index.js.map +1 -1
  21. package/dist/contracts/session/api.d.ts +1 -1
  22. package/dist/contracts/session/api.d.ts.map +1 -1
  23. package/dist/eval/harness-protection.js +1 -1
  24. package/dist/eval/harness-protection.js.map +1 -1
  25. package/dist/learning/cycle.d.ts +5 -3
  26. package/dist/learning/cycle.d.ts.map +1 -1
  27. package/dist/learning/cycle.js +11 -13
  28. package/dist/learning/cycle.js.map +1 -1
  29. package/dist/learning/guidance.d.ts +74 -0
  30. package/dist/learning/guidance.d.ts.map +1 -0
  31. package/dist/learning/guidance.js +259 -0
  32. package/dist/learning/guidance.js.map +1 -0
  33. package/dist/learning/skill.d.ts +2 -2
  34. package/dist/learning/skill.d.ts.map +1 -1
  35. package/dist/learning/skill.js +6 -6
  36. package/dist/learning/skill.js.map +1 -1
  37. package/dist/learning/store.d.ts.map +1 -1
  38. package/dist/learning/store.js +6 -6
  39. package/dist/learning/store.js.map +1 -1
  40. package/dist/pals/communication/ingress-schema.d.ts +8 -8
  41. package/dist/pals/communication/schema.d.ts +2 -2
  42. package/dist/peers/client.d.ts +2 -3
  43. package/dist/peers/client.d.ts.map +1 -1
  44. package/dist/peers/client.js +2 -3
  45. package/dist/peers/client.js.map +1 -1
  46. package/dist/peers/endpoint.d.ts +1 -2
  47. package/dist/peers/endpoint.d.ts.map +1 -1
  48. package/dist/peers/endpoint.js +1 -2
  49. package/dist/peers/endpoint.js.map +1 -1
  50. package/dist/peers/protocol.d.ts.map +1 -1
  51. package/dist/peers/protocol.js +1 -0
  52. package/dist/peers/protocol.js.map +1 -1
  53. package/dist/prompt/coding-agent-doctrine.d.ts +4 -4
  54. package/dist/prompt/coding-agent-doctrine.d.ts.map +1 -1
  55. package/dist/prompt/coding-agent-doctrine.js +5 -3
  56. package/dist/prompt/coding-agent-doctrine.js.map +1 -1
  57. package/dist/prompt/index.d.ts +0 -4
  58. package/dist/prompt/index.d.ts.map +1 -1
  59. package/dist/prompt/index.js +0 -2
  60. package/dist/prompt/index.js.map +1 -1
  61. package/dist/provider/fallback.d.ts.map +1 -1
  62. package/dist/provider/fallback.js +3 -0
  63. package/dist/provider/fallback.js.map +1 -1
  64. package/dist/provider/idle-timeout.d.ts.map +1 -1
  65. package/dist/provider/idle-timeout.js +5 -0
  66. package/dist/provider/idle-timeout.js.map +1 -1
  67. package/dist/provider/model-window-suffix.d.ts.map +1 -1
  68. package/dist/provider/model-window-suffix.js +1 -0
  69. package/dist/provider/model-window-suffix.js.map +1 -1
  70. package/dist/provider/retry.d.ts.map +1 -1
  71. package/dist/provider/retry.js +5 -0
  72. package/dist/provider/retry.js.map +1 -1
  73. package/dist/provider/step-stopped.d.ts +19 -0
  74. package/dist/provider/step-stopped.d.ts.map +1 -0
  75. package/dist/provider/step-stopped.js +25 -0
  76. package/dist/provider/step-stopped.js.map +1 -0
  77. package/dist/provider/token-budget.d.ts.map +1 -1
  78. package/dist/provider/token-budget.js +6 -1
  79. package/dist/provider/token-budget.js.map +1 -1
  80. package/dist/public-runtime.d.ts +4 -15
  81. package/dist/public-runtime.d.ts.map +1 -1
  82. package/dist/public-runtime.js +4 -15
  83. package/dist/public-runtime.js.map +1 -1
  84. package/dist/public-tools.d.ts +0 -2
  85. package/dist/public-tools.d.ts.map +1 -1
  86. package/dist/public-tools.js +0 -2
  87. package/dist/public-tools.js.map +1 -1
  88. package/dist/public-types.d.ts +4 -22
  89. package/dist/public-types.d.ts.map +1 -1
  90. package/dist/runtime/query/iteration/index.d.ts +17 -0
  91. package/dist/runtime/query/iteration/index.d.ts.map +1 -1
  92. package/dist/runtime/query/iteration/index.js +176 -6
  93. package/dist/runtime/query/iteration/index.js.map +1 -1
  94. package/dist/runtime/query/iteration/phases/per-call-review.d.ts.map +1 -1
  95. package/dist/runtime/query/iteration/phases/per-call-review.js +4 -5
  96. package/dist/runtime/query/iteration/phases/per-call-review.js.map +1 -1
  97. package/dist/runtime/query/iteration/phases/tool-review.d.ts.map +1 -1
  98. package/dist/runtime/query/iteration/phases/tool-review.js +6 -3
  99. package/dist/runtime/query/iteration/phases/tool-review.js.map +1 -1
  100. package/dist/runtime/query/iteration/recorded-context.d.ts +1 -1
  101. package/dist/runtime/query/iteration/recorded-context.d.ts.map +1 -1
  102. package/dist/runtime/query/iteration/recorded-context.js +2 -1
  103. package/dist/runtime/query/iteration/recorded-context.js.map +1 -1
  104. package/dist/runtime/query/iteration/stream-turn.d.ts +9 -1
  105. package/dist/runtime/query/iteration/stream-turn.d.ts.map +1 -1
  106. package/dist/runtime/query/iteration/stream-turn.js +48 -2
  107. package/dist/runtime/query/iteration/stream-turn.js.map +1 -1
  108. package/dist/runtime/query/resume-pending.d.ts.map +1 -1
  109. package/dist/runtime/query/resume-pending.js +7 -4
  110. package/dist/runtime/query/resume-pending.js.map +1 -1
  111. package/dist/runtime/query/review-policy.d.ts +40 -8
  112. package/dist/runtime/query/review-policy.d.ts.map +1 -1
  113. package/dist/runtime/query/review-policy.js +139 -24
  114. package/dist/runtime/query/review-policy.js.map +1 -1
  115. package/dist/runtime/query/turn/completion-audit.d.ts +32 -0
  116. package/dist/runtime/query/turn/completion-audit.d.ts.map +1 -0
  117. package/dist/runtime/query/turn/completion-audit.js +56 -0
  118. package/dist/runtime/query/turn/completion-audit.js.map +1 -0
  119. package/dist/runtime/query/turn/stall-monitor.d.ts +78 -0
  120. package/dist/runtime/query/turn/stall-monitor.d.ts.map +1 -0
  121. package/dist/runtime/query/turn/stall-monitor.js +101 -0
  122. package/dist/runtime/query/turn/stall-monitor.js.map +1 -0
  123. package/dist/session/paths.d.ts +1 -2
  124. package/dist/session/paths.d.ts.map +1 -1
  125. package/dist/session/paths.js +1 -4
  126. package/dist/session/paths.js.map +1 -1
  127. package/dist/store/index.d.ts +2 -0
  128. package/dist/store/index.d.ts.map +1 -1
  129. package/dist/store/index.js +1 -0
  130. package/dist/store/index.js.map +1 -1
  131. package/dist/tools/builtins/bash.d.ts +2 -1
  132. package/dist/tools/builtins/bash.d.ts.map +1 -1
  133. package/dist/tools/builtins/bash.js +5 -2
  134. package/dist/tools/builtins/bash.js.map +1 -1
  135. package/dist/tools/builtins/content-fingerprint.d.ts +13 -0
  136. package/dist/tools/builtins/content-fingerprint.d.ts.map +1 -1
  137. package/dist/tools/builtins/content-fingerprint.js +25 -0
  138. package/dist/tools/builtins/content-fingerprint.js.map +1 -1
  139. package/dist/tools/builtins/edit.d.ts.map +1 -1
  140. package/dist/tools/builtins/edit.js +7 -2
  141. package/dist/tools/builtins/edit.js.map +1 -1
  142. package/dist/tools/builtins/shell-read-credit.d.ts +15 -0
  143. package/dist/tools/builtins/shell-read-credit.d.ts.map +1 -0
  144. package/dist/tools/builtins/shell-read-credit.js +161 -0
  145. package/dist/tools/builtins/shell-read-credit.js.map +1 -0
  146. package/dist/tools/paths.d.ts +15 -2
  147. package/dist/tools/paths.d.ts.map +1 -1
  148. package/dist/tools/paths.js +17 -2
  149. package/dist/tools/paths.js.map +1 -1
  150. package/dist/turn/evidence-recall.d.ts +1 -1
  151. package/dist/turn/evidence-recall.d.ts.map +1 -1
  152. package/dist/turn/evidence-recall.js +5 -14
  153. package/dist/turn/evidence-recall.js.map +1 -1
  154. package/dist/turn/memory-recall.d.ts.map +1 -1
  155. package/dist/turn/memory-recall.js +18 -4
  156. package/dist/turn/memory-recall.js.map +1 -1
  157. package/dist/turn/reporter.d.ts.map +1 -1
  158. package/dist/turn/reporter.js +5 -0
  159. package/dist/turn/reporter.js.map +1 -1
  160. package/dist/types/acp/index.d.ts +6 -0
  161. package/dist/types/acp/index.d.ts.map +1 -1
  162. package/dist/types/agent/base.d.ts +4 -0
  163. package/dist/types/agent/base.d.ts.map +1 -1
  164. package/dist/types/hitl/index.d.ts +8 -0
  165. package/dist/types/hitl/index.d.ts.map +1 -1
  166. package/dist/types/hitl/index.js.map +1 -1
  167. package/dist/types/ids/index.d.ts +1 -1
  168. package/dist/types/message/index.d.ts +1 -1
  169. package/dist/types/message/index.d.ts.map +1 -1
  170. package/dist/types/message/index.js +1 -0
  171. package/dist/types/message/index.js.map +1 -1
  172. package/dist/types/provider/interface.d.ts +12 -0
  173. package/dist/types/provider/interface.d.ts.map +1 -1
  174. package/dist/types/session/config.d.ts +25 -0
  175. package/dist/types/session/config.d.ts.map +1 -1
  176. package/dist/types/session/events.d.ts +19 -0
  177. package/dist/types/session/events.d.ts.map +1 -1
  178. package/dist/types/session/events.js.map +1 -1
  179. package/dist/types/session/prepare-step.d.ts +16 -0
  180. package/dist/types/session/prepare-step.d.ts.map +1 -1
  181. package/dist/types/session/records.d.ts.map +1 -1
  182. package/dist/types/session/records.js +3 -0
  183. package/dist/types/session/records.js.map +1 -1
  184. package/dist/types/session/turn.d.ts +1 -1
  185. package/dist/types/session/turn.d.ts.map +1 -1
  186. package/dist/types/session/turn.js.map +1 -1
  187. package/package.json +1 -1
  188. package/src/agents/QueryAgent.ts +2 -0
  189. package/src/bridge/a2a/mapper.ts +2 -0
  190. package/src/bridge/acp/permission.ts +8 -0
  191. package/src/bridge/acp/server.ts +7 -1
  192. package/src/bridge/sse/mapper.ts +13 -0
  193. package/src/constants/tools/index.ts +27 -0
  194. package/src/contracts/session/api.ts +1 -0
  195. package/src/eval/harness-protection.ts +1 -1
  196. package/src/learning/cycle.ts +15 -16
  197. package/src/learning/guidance.ts +339 -0
  198. package/src/learning/skill.ts +7 -7
  199. package/src/learning/store.ts +5 -6
  200. package/src/peers/client.ts +2 -3
  201. package/src/peers/endpoint.ts +1 -2
  202. package/src/peers/protocol.ts +1 -0
  203. package/src/prompt/coding-agent-doctrine.ts +5 -3
  204. package/src/prompt/index.ts +0 -4
  205. package/src/provider/fallback.ts +7 -0
  206. package/src/provider/idle-timeout.ts +8 -0
  207. package/src/provider/model-window-suffix.ts +1 -0
  208. package/src/provider/retry.ts +8 -0
  209. package/src/provider/step-stopped.ts +27 -0
  210. package/src/provider/token-budget.ts +6 -1
  211. package/src/public-runtime.ts +7 -28
  212. package/src/public-tools.ts +0 -3
  213. package/src/public-types.ts +6 -137
  214. package/src/runtime/query/iteration/index.ts +218 -6
  215. package/src/runtime/query/iteration/phases/per-call-review.ts +7 -5
  216. package/src/runtime/query/iteration/phases/tool-review.ts +5 -3
  217. package/src/runtime/query/iteration/recorded-context.ts +2 -0
  218. package/src/runtime/query/iteration/stream-turn.ts +51 -1
  219. package/src/runtime/query/resume-pending.ts +11 -4
  220. package/src/runtime/query/review-policy.ts +157 -24
  221. package/src/runtime/query/turn/completion-audit.ts +71 -0
  222. package/src/runtime/query/turn/stall-monitor.ts +158 -0
  223. package/src/session/paths.ts +2 -6
  224. package/src/store/index.ts +2 -0
  225. package/src/tools/builtins/bash.ts +6 -2
  226. package/src/tools/builtins/content-fingerprint.ts +25 -0
  227. package/src/tools/builtins/edit.ts +11 -2
  228. package/src/tools/builtins/shell-read-credit.ts +159 -0
  229. package/src/tools/paths.ts +18 -2
  230. package/src/turn/evidence-recall.ts +7 -15
  231. package/src/turn/memory-recall.ts +26 -7
  232. package/src/turn/reporter.ts +5 -0
  233. package/src/types/acp/index.ts +6 -0
  234. package/src/types/agent/base.ts +4 -0
  235. package/src/types/hitl/index.ts +8 -0
  236. package/src/types/ids/index.ts +1 -1
  237. package/src/types/message/index.ts +1 -0
  238. package/src/types/provider/interface.ts +13 -0
  239. package/src/types/session/config.ts +27 -0
  240. package/src/types/session/events.ts +19 -0
  241. package/src/types/session/prepare-step.ts +17 -0
  242. package/src/types/session/records.ts +3 -0
  243. package/src/types/session/turn.ts +2 -1
  244. package/dist/learning/deprecated.d.ts +0 -86
  245. package/dist/learning/deprecated.d.ts.map +0 -1
  246. package/dist/learning/deprecated.js +0 -22
  247. package/dist/learning/deprecated.js.map +0 -1
  248. package/dist/manager/resident/activity.d.ts +0 -74
  249. package/dist/manager/resident/activity.d.ts.map +0 -1
  250. package/dist/manager/resident/activity.js +0 -125
  251. package/dist/manager/resident/activity.js.map +0 -1
  252. package/dist/manager/resident/agenda.d.ts +0 -167
  253. package/dist/manager/resident/agenda.d.ts.map +0 -1
  254. package/dist/manager/resident/agenda.js +0 -588
  255. package/dist/manager/resident/agenda.js.map +0 -1
  256. package/dist/manager/resident/consumption.d.ts +0 -98
  257. package/dist/manager/resident/consumption.d.ts.map +0 -1
  258. package/dist/manager/resident/consumption.js +0 -237
  259. package/dist/manager/resident/consumption.js.map +0 -1
  260. package/dist/manager/resident/delivery-window.d.ts +0 -28
  261. package/dist/manager/resident/delivery-window.d.ts.map +0 -1
  262. package/dist/manager/resident/delivery-window.js +0 -80
  263. package/dist/manager/resident/delivery-window.js.map +0 -1
  264. package/dist/manager/resident/evidence-recall.d.ts +0 -30
  265. package/dist/manager/resident/evidence-recall.d.ts.map +0 -1
  266. package/dist/manager/resident/evidence-recall.js +0 -297
  267. package/dist/manager/resident/evidence-recall.js.map +0 -1
  268. package/dist/manager/resident/history-disk.d.ts +0 -10
  269. package/dist/manager/resident/history-disk.d.ts.map +0 -1
  270. package/dist/manager/resident/history-disk.js +0 -50
  271. package/dist/manager/resident/history-disk.js.map +0 -1
  272. package/dist/manager/resident/history.d.ts +0 -115
  273. package/dist/manager/resident/history.d.ts.map +0 -1
  274. package/dist/manager/resident/history.js +0 -203
  275. package/dist/manager/resident/history.js.map +0 -1
  276. package/dist/manager/resident/host.d.ts +0 -112
  277. package/dist/manager/resident/host.d.ts.map +0 -1
  278. package/dist/manager/resident/host.js +0 -254
  279. package/dist/manager/resident/host.js.map +0 -1
  280. package/dist/manager/resident/initiative.d.ts +0 -86
  281. package/dist/manager/resident/initiative.d.ts.map +0 -1
  282. package/dist/manager/resident/initiative.js +0 -131
  283. package/dist/manager/resident/initiative.js.map +0 -1
  284. package/dist/manager/resident/loop.d.ts +0 -49
  285. package/dist/manager/resident/loop.d.ts.map +0 -1
  286. package/dist/manager/resident/loop.js +0 -75
  287. package/dist/manager/resident/loop.js.map +0 -1
  288. package/dist/manager/resident/outbox.d.ts +0 -124
  289. package/dist/manager/resident/outbox.d.ts.map +0 -1
  290. package/dist/manager/resident/outbox.js +0 -216
  291. package/dist/manager/resident/outbox.js.map +0 -1
  292. package/dist/manager/resident/proposal.d.ts +0 -65
  293. package/dist/manager/resident/proposal.d.ts.map +0 -1
  294. package/dist/manager/resident/proposal.js +0 -77
  295. package/dist/manager/resident/proposal.js.map +0 -1
  296. package/dist/manager/resident/store.d.ts +0 -108
  297. package/dist/manager/resident/store.d.ts.map +0 -1
  298. package/dist/manager/resident/store.js +0 -205
  299. package/dist/manager/resident/store.js.map +0 -1
  300. package/dist/manager/resident/tool-evidence.d.ts +0 -112
  301. package/dist/manager/resident/tool-evidence.d.ts.map +0 -1
  302. package/dist/manager/resident/tool-evidence.js +0 -289
  303. package/dist/manager/resident/tool-evidence.js.map +0 -1
  304. package/dist/prompt/resident-learning.d.ts +0 -29
  305. package/dist/prompt/resident-learning.d.ts.map +0 -1
  306. package/dist/prompt/resident-learning.js +0 -126
  307. package/dist/prompt/resident-learning.js.map +0 -1
  308. package/dist/prompt/resident-step.d.ts +0 -42
  309. package/dist/prompt/resident-step.d.ts.map +0 -1
  310. package/dist/prompt/resident-step.js +0 -137
  311. package/dist/prompt/resident-step.js.map +0 -1
  312. package/dist/tools/resident-history.d.ts +0 -12
  313. package/dist/tools/resident-history.d.ts.map +0 -1
  314. package/dist/tools/resident-history.js +0 -82
  315. package/dist/tools/resident-history.js.map +0 -1
  316. package/dist/tools/resident-tool-evidence.d.ts +0 -9
  317. package/dist/tools/resident-tool-evidence.d.ts.map +0 -1
  318. package/dist/tools/resident-tool-evidence.js +0 -61
  319. package/dist/tools/resident-tool-evidence.js.map +0 -1
  320. package/src/learning/deprecated.ts +0 -124
  321. package/src/manager/resident/activity.ts +0 -211
  322. package/src/manager/resident/agenda.ts +0 -937
  323. package/src/manager/resident/consumption.ts +0 -335
  324. package/src/manager/resident/delivery-window.ts +0 -99
  325. package/src/manager/resident/evidence-recall.ts +0 -369
  326. package/src/manager/resident/history-disk.ts +0 -63
  327. package/src/manager/resident/history.ts +0 -348
  328. package/src/manager/resident/host.ts +0 -390
  329. package/src/manager/resident/initiative.ts +0 -231
  330. package/src/manager/resident/loop.ts +0 -119
  331. package/src/manager/resident/outbox.ts +0 -341
  332. package/src/manager/resident/proposal.ts +0 -119
  333. package/src/manager/resident/store.ts +0 -279
  334. package/src/manager/resident/tool-evidence.ts +0 -455
  335. package/src/prompt/resident-learning.ts +0 -152
  336. package/src/prompt/resident-step.ts +0 -182
  337. package/src/tools/resident-history.ts +0 -88
  338. package/src/tools/resident-tool-evidence.ts +0 -72
@@ -591,6 +591,7 @@ export {
591
591
  isMemoryName,
592
592
  memoryIndexLine,
593
593
  memoryLinkNames,
594
+ memoryOrigin,
594
595
  renderMemoryIndex,
595
596
  slugifyMemoryName,
596
597
  } from './store/index.js'
@@ -1498,6 +1499,7 @@ export {
1498
1499
  isReviewExempt,
1499
1500
  isReviewMode,
1500
1501
  modeReviewsAllowedCalls,
1502
+ mustAskPerson,
1501
1503
  } from './runtime/query/review-policy.js'
1502
1504
  // The model that decides, in the `classify` review mode, what a person would
1503
1505
  // otherwise be asked. See `runtime/query/auto-review/`.
@@ -1529,8 +1531,6 @@ export {
1529
1531
  PromptContributionRegistry,
1530
1532
  SKILLS_CONTRIBUTION_ID,
1531
1533
  codingAgentDoctrineContribution,
1532
- createResidentStepContributions,
1533
- createResidentStepContext,
1534
1534
  skillsContribution,
1535
1535
  } from './prompt/index.js'
1536
1536
 
@@ -1694,23 +1694,13 @@ export {
1694
1694
  diffRequestContext,
1695
1695
  } from './runtime/query/request-context.js'
1696
1696
 
1697
- export {
1698
- DiskResidentStore,
1699
- ResidentConflictError,
1700
- } from './manager/resident/store.js'
1701
- export { runResident, stepResident } from './manager/resident/loop.js'
1702
- export { DiskResidentAgenda } from './manager/resident/agenda.js'
1703
- export { inspectResidentConsumption } from './manager/resident/consumption.js'
1704
- export { ResidentHost } from './manager/resident/host.js'
1705
-
1706
- export { createResidentSelector } from './manager/resident/initiative.js'
1707
- export { validateResidentProposal } from './manager/resident/proposal.js'
1708
-
1709
- export { deliverResidentMessage } from './manager/resident/outbox.js'
1710
- export { createResidentDeliveryWindow } from './manager/resident/delivery-window.js'
1711
-
1712
1697
  export { hashLearningSkill, projectLearning } from './learning/skill.js'
1713
1698
  export { runLearningCycle } from './learning/cycle.js'
1699
+ export {
1700
+ DiskLearningGuidance,
1701
+ LearningGuidanceConflictError,
1702
+ earlierGuidanceDirectory,
1703
+ } from './learning/guidance.js'
1714
1704
  export {
1715
1705
  LEARNING_FLOOR_COMPONENTS,
1716
1706
  LEARNING_SURFACE_KINDS,
@@ -1744,23 +1734,12 @@ export {
1744
1734
  classifyEvidenceSource,
1745
1735
  EVIDENCE_RECORD_GUIDANCE,
1746
1736
  } from './store/evidence/source-kind.js'
1747
- export { createResidentToolEvidenceSource } from './manager/resident/tool-evidence.js'
1748
-
1749
- export { createResidentEvidenceRecallStep } from './manager/resident/evidence-recall.js'
1750
1737
 
1751
1738
  export {
1752
1739
  SqliteLearningStore,
1753
1740
  runStoredLearningCycle,
1754
1741
  runStoredLearningFromObservations,
1755
1742
  } from './learning/store.js'
1756
- export {
1757
- SqliteResidentLearningStore,
1758
- hashResidentSkill,
1759
- projectResidentLearning,
1760
- runResidentLearningCycle,
1761
- runStoredResidentLearningCycle,
1762
- runStoredResidentLearningFromObservations,
1763
- } from './learning/deprecated.js'
1764
1743
 
1765
1744
  // ─── sessions, turns and the session log ─────────────────────────────────
1766
1745
  //
@@ -41,7 +41,6 @@ export type { UntrustedEnvelope, WrapUntrustedOptions } from './tools/untrusted-
41
41
  // ─── Built-in tools ──────────────────────────────────────────────────────
42
42
 
43
43
  export { getBuiltinTools } from './tools/builtins/index.js'
44
- export { buildResidentHistoryTools } from './tools/resident-history.js'
45
44
  // A host compiling operator permissions has a tool name and needs an argument
46
45
  // to attach a pattern to. Without one it can only match against the serialised
47
46
  // input, which is how an `allow` for `git status*` came to approve
@@ -270,7 +269,5 @@ export {
270
269
  seedObservationLedger,
271
270
  } from './runtime/query/file-evidence-seed.js'
272
271
 
273
- export { buildResidentToolEvidenceTools } from './tools/resident-tool-evidence.js'
274
-
275
272
  export { createPalMessagingTools } from './pals/communication/tools.js'
276
273
  export { createPalOperatorMessagingTools } from './pals/communication/operator.js'
@@ -218,6 +218,7 @@ export type {
218
218
  MemoryContentRejection,
219
219
  MemoryImportOutcome,
220
220
  RenderedMemoryIndex,
221
+ MemoryOrigin,
221
222
  Timestamped,
222
223
  } from './store/index.js'
223
224
 
@@ -457,6 +458,7 @@ export type {
457
458
  } from './runtime/query/auto-review/index.js'
458
459
 
459
460
  export type {
461
+ MustAskCall,
460
462
  ReviewExemption,
461
463
  ReviewMode,
462
464
  ReviewPolicyOptions,
@@ -471,9 +473,6 @@ export type {
471
473
  PromptContribution,
472
474
  PromptContributionContext,
473
475
  PromptPlacement,
474
- ResidentStepPromptOptions,
475
- ResidentStepContextOptions,
476
- ResidentStepContextBundle,
477
476
  } from './prompt/index.js'
478
477
 
479
478
  export type {
@@ -532,89 +531,6 @@ export type {
532
531
  RequestContextChange,
533
532
  } from './runtime/query/request-context.js'
534
533
 
535
- export type {
536
- ResidentDecision,
537
- ResidentState,
538
- ResidentStore,
539
- } from './manager/resident/store.js'
540
- export type {
541
- ResidentActivityScope,
542
- ResidentAdmission,
543
- ResidentSettlement,
544
- ResidentActivityOptions,
545
- ResidentActivityPage,
546
- ResidentActivitySource,
547
- } from './manager/resident/activity.js'
548
- export type {
549
- ResidentConsumptionReceipt,
550
- ResidentConsumptionResolver,
551
- ResidentConsumptionOptions,
552
- ResidentConsumptionAttempt,
553
- ResidentConsumptionReport,
554
- } from './manager/resident/consumption.js'
555
- export type {
556
- ResidentHistoryScope,
557
- ResidentHistoryAddress,
558
- ResidentHistoryMatch,
559
- ResidentHistorySearchOptions,
560
- ResidentHistorySearchResult,
561
- ResidentHistoryReadOptions,
562
- ResidentHistoryText,
563
- ResidentHistoryReadResult,
564
- ResidentHistorySource,
565
- } from './manager/resident/history.js'
566
- export type {
567
- ResidentStep,
568
- ResidentStepResult,
569
- ResidentLoopOptions,
570
- } from './manager/resident/loop.js'
571
- export type { ResidentExecutionStore } from './manager/resident/store.js'
572
- export type {
573
- ResidentAgendaState,
574
- ResidentAgendaStore,
575
- ResidentPursuit,
576
- } from './manager/resident/agenda.js'
577
- export type {
578
- ResidentHostResult,
579
- ResidentHostRunOptions,
580
- ResidentPursuitStep,
581
- } from './manager/resident/host.js'
582
-
583
- export type {
584
- ResidentObservation,
585
- ResidentFeedback,
586
- ResidentSelectionConfig,
587
- ResidentCandidate,
588
- ResidentSelection,
589
- ResidentSelector,
590
- } from './manager/resident/initiative.js'
591
- export type {
592
- ResidentHostOptions,
593
- ResidentObserver,
594
- } from './manager/resident/host.js'
595
- export type {
596
- ResidentProposal,
597
- ResidentProposalLimits,
598
- ResidentProposalOrigin,
599
- } from './manager/resident/proposal.js'
600
-
601
- export type { ResidentMessageFactory } from './manager/resident/host.js'
602
- export type {
603
- ResidentMessageInput,
604
- ResidentOutboxMessage,
605
- ResidentDeliveryOutcome,
606
- ResidentOutboxStore,
607
- ResidentDeliveryGate,
608
- ResidentMessageTransport,
609
- ResidentDeliveryOptions,
610
- ResidentDeliveryResult,
611
- } from './manager/resident/outbox.js'
612
- export type { ResidentDeliveryWindowConfig } from './manager/resident/delivery-window.js'
613
-
614
- export type {
615
- ResidentStepContext,
616
- ResidentContextualStep,
617
- } from './manager/resident/host.js'
618
534
  export type {
619
535
  LearningEvidence,
620
536
  LearningSkillCandidate,
@@ -639,6 +555,10 @@ export type {
639
555
  LearningCycleOptions,
640
556
  LearningCycleResult,
641
557
  } from './learning/cycle.js'
558
+ export type {
559
+ DiskLearningGuidanceOptions,
560
+ LearningGuidanceState,
561
+ } from './learning/guidance.js'
642
562
 
643
563
  export type {
644
564
  LearningModel,
@@ -669,13 +589,6 @@ export type {
669
589
  LearningLeakSubject,
670
590
  } from './learning/leak-tripwire.js'
671
591
 
672
- export type {
673
- ResidentArchiveRequest,
674
- ResidentArchiveEntry,
675
- ResidentArchivePage,
676
- ResidentArchiveListOptions,
677
- } from './manager/resident/agenda.js'
678
-
679
592
  export type {
680
593
  SessionEvidenceScope,
681
594
  SessionEvidenceSourceOptions,
@@ -692,18 +605,7 @@ export type {
692
605
  SessionTextEvidenceSource,
693
606
  } from './store/evidence/types.js'
694
607
  export type { EvidenceRecordKind } from './store/evidence/source-kind.js'
695
- export type {
696
- ResidentToolEvidenceScope,
697
- ResidentSettledInvocation,
698
- ResidentToolEvidenceOptions,
699
- ResidentToolEvidenceSearchOptions,
700
- ResidentToolEvidenceSearchResult,
701
- ResidentToolEvidenceReadOptions,
702
- ResidentToolEvidenceReadResult,
703
- ResidentToolEvidenceSource,
704
- } from './manager/resident/tool-evidence.js'
705
608
 
706
- export type { ResidentEvidenceRecallOptions } from './manager/resident/evidence-recall.js'
707
609
  export type {
708
610
  JsonClaimValue,
709
611
  JsonClaimRequirement,
@@ -871,36 +773,3 @@ export type {
871
773
  } from './pals/activity/subscription-policy.js'
872
774
  export type { PalActivitySubscriptionRunnerOptions } from './pals/activity/subscriptions.js'
873
775
  export type { PalActivityCausalityOptions } from './pals/activity/causality.js'
874
-
875
- // Deprecated resident-prefixed names, kept until the next major.
876
- export type {
877
- ResidentLearningEvidence,
878
- ResidentSkillCandidate,
879
- ResidentLearnedSkill,
880
- ResidentLearningState,
881
- ResidentProfileUpdate,
882
- ResidentSkillEvaluation,
883
- ResidentLearningProjectionOptions,
884
- ResidentLearningSource,
885
- ResidentLearningProjection,
886
- ResidentLearningStage,
887
- ResidentLearningReceipt,
888
- ResidentLearningConsumption,
889
- ResidentLearningCycleEvent,
890
- ResidentLearningCycleContext,
891
- ResidentLearningGenerationContext,
892
- ResidentLearningExplorationContext,
893
- ResidentLearningExploration,
894
- ResidentLearningEvaluationContext,
895
- ResidentLearningCycleOptions,
896
- ResidentLearningCycleResult,
897
- SqliteResidentLearningStoreOptions,
898
- ResidentLearningArtifact,
899
- ResidentLearningRecordedUsage,
900
- ResidentLearningCycleSummary,
901
- ResidentLearningDiscoveryOptions,
902
- ResidentLearningDiscoveryResult,
903
- ResidentLearningObservation,
904
- ResidentLearningObservationRecord,
905
- ResidentLearningTarget,
906
- } from './learning/deprecated.js'
@@ -42,9 +42,10 @@ import {
42
42
  createToolMessage,
43
43
  } from '../../../types/message/index.js'
44
44
  import { classifyProviderError, readOutputOverflow } from '../../../types/provider/errors.js'
45
- import type { ChatCompletionResponse } from '../../../types/provider/index.js'
45
+ import type { ChatCompletionResponse, ReasoningEffort } from '../../../types/provider/index.js'
46
46
  import type { AnswerReview, AnswerReviewContext } from '../../../types/session/answer-review.js'
47
47
  import type {
48
+ RecalledMemory,
48
49
  SessionEvent,
49
50
  StepFailure,
50
51
  StepProvenance,
@@ -75,6 +76,15 @@ import {
75
76
  } from '../request-rich-content.js'
76
77
  import { withoutVoidAssistantTurns } from '../request-void-turns.js'
77
78
  import { formatSteeringNote, isOperatorUserMessage } from '../steering.js'
79
+ import { COMPLETION_AUDIT_MESSAGE, CompletionAudit } from '../turn/completion-audit.js'
80
+ import {
81
+ FORCED_STEP_MESSAGE,
82
+ REASONING_CAPPED_MESSAGE,
83
+ REASONING_ONLY_MESSAGE,
84
+ StallMonitor,
85
+ callChangedState,
86
+ reasoningCapChars,
87
+ } from '../turn/stall-monitor.js'
78
88
  import { effortForModel } from './effort-clamp.js'
79
89
  import { parseNativeCandidate } from './native-output.js'
80
90
  import {
@@ -119,6 +129,9 @@ import {
119
129
  } from './step-shaping.js'
120
130
  import { streamProviderTurn } from './stream-turn.js'
121
131
 
132
+ /** Capped steps in a row after which the per-step cap stops applying for the turn's next step. */
133
+ const MAX_CAPPED_STREAK = 3
134
+
122
135
  type ReviewRequest = Pick<AnswerReviewContext, 'requestMessages' | 'latestUserMessage'>
123
136
 
124
137
  /** A host reviewer is not the model transport, even when its cause is an HTTP failure. */
@@ -299,6 +312,16 @@ export class IterationOrchestrator {
299
312
  private stopDeferredForOutstandingWork = false
300
313
  /** Nudges sent since the model last finished a call without hitting its output cap. */
301
314
  private outputContinuations = 0
315
+ /** Watches the turn's steps for reasoning that piles up while nothing changes. */
316
+ private readonly stallMonitor?: StallMonitor
317
+ /** Holds the turn back once when it changed files and checked nothing afterwards. */
318
+ private readonly completionAudit?: CompletionAudit
319
+ /** The next step must call a tool, at low effort: set by the stall monitor or a capped step. */
320
+ private forceActionNextStep = false
321
+ /** Steps in a row cut at the per-step reasoning cap; past a few the cap stops applying. */
322
+ private cappedStreak = 0
323
+ /** A reply that held only reasoning was already answered with one more request. */
324
+ private reasoningOnlyRetried = false
302
325
  /**
303
326
  * The model a refused request moved to. Once set it replaces the model the
304
327
  * step asked for, for the rest of the turn: the request that was refused
@@ -393,6 +416,10 @@ export class IterationOrchestrator {
393
416
  this.rememberUserMessage(createRuntimeContextMessage(text, 'steering'))
394
417
  },
395
418
  }
419
+ if (ctx.turnConfig.completionAudit === true) this.completionAudit = new CompletionAudit()
420
+ if (ctx.turnConfig.reasoning?.stall !== false) {
421
+ this.stallMonitor = new StallMonitor(ctx.turnConfig.reasoning?.stall || undefined)
422
+ }
396
423
  ctx.checkpointMgr.setLatestUserMessageSource(() => this.latestUserMessage)
397
424
  ctx.checkpointMgr.setAnswerReviewAttemptsSource?.(() => this.answerReviewAttempts)
398
425
  ctx.checkpointMgr.setStructuredReviewAttemptsSource?.(() => this.structuredReviewAttempts)
@@ -861,7 +888,16 @@ export class IterationOrchestrator {
861
888
  // history now, after its last message, so this request and every
862
889
  // later one begin with it. Nothing is inserted ahead of a message
863
890
  // that is already recorded.
864
- appendRecordedContext(recorder, step.recordedContext, this.ctx.log)
891
+ const recalled: RecalledMemory[] = []
892
+ appendRecordedContext(recorder, step.recordedContext, this.ctx.log, undefined, (item) =>
893
+ recalled.push(...(item.recalledMemories ?? [])),
894
+ )
895
+ if (recalled.length > 0)
896
+ await this.ctx.emitEvent?.({
897
+ type: 'memory_recalled',
898
+ turnId: recorder.turnId,
899
+ memories: recalled,
900
+ })
865
901
  const baseMessages = recorder.messages
866
902
 
867
903
  // Step guidance is appended to the REQUEST, never pushed onto
@@ -1063,6 +1099,11 @@ export class IterationOrchestrator {
1063
1099
  // died part-way has already emitted both `message_started` and
1064
1100
  // `message_completed` under this id, which is the trail a
1065
1101
  // reader wants most on exactly that turn.
1102
+ // A step the loop forces to act runs at low effort with a tool call
1103
+ // required, for this step only. Low is used only where the model
1104
+ // is known to offer it; effort is refused, not clamped.
1105
+ const forcedAction = this.forceActionNextStep && !forceFinalize && llmTools.length > 0
1106
+ this.forceActionNextStep = false
1066
1107
  stepMessageId = generateMessageId()
1067
1108
  const requestedMember = this.ctx.servingMember?.() ?? {
1068
1109
  index: 0,
@@ -1092,12 +1133,30 @@ export class IterationOrchestrator {
1092
1133
  })
1093
1134
  }
1094
1135
  }
1136
+ // A forced action step runs at low effort, where the model is known
1137
+ // to offer it; effort is refused, not clamped.
1138
+ const offeredEfforts = this.ctx.provider.reasoningEffortLevelsFor?.(stepModel)
1139
+ const stepEffort: ReasoningEffort | undefined =
1140
+ forcedAction && requestEffort && (offeredEfforts?.includes('low') ?? false)
1141
+ ? 'low'
1142
+ : requestEffort
1143
+ // A provider that refuses a forced tool choice (some models do, and
1144
+ // so does manual extended thinking) is not sent one: the step keeps
1145
+ // its low effort and asks in words, on this request only.
1146
+ const forcedChoiceRefused =
1147
+ forcedAction &&
1148
+ this.ctx.provider.acceptsForcedToolChoiceFor?.(stepModel, turnConfig.thinking) === false
1095
1149
  const operatorInputAtDispatch = this.latestUserMessage
1096
1150
  const latestReviewUserMessage =
1097
1151
  (this.ctx.reviewAnswer || this.ctx.structuredOutput?.review) && operatorInputAtDispatch
1098
1152
  ? structuredClone(operatorInputAtDispatch)
1099
1153
  : undefined
1100
- const { response, messageId, requestMessages } = yield* streamProviderTurn(
1154
+ const {
1155
+ response,
1156
+ messageId,
1157
+ requestMessages,
1158
+ reasoningCapped = false,
1159
+ } = yield* streamProviderTurn(
1101
1160
  this.ctx.provider,
1102
1161
  {
1103
1162
  model: stepModel,
@@ -1114,7 +1173,9 @@ export class IterationOrchestrator {
1114
1173
  }
1115
1174
  : {}),
1116
1175
  providerRoute: requestedRoute,
1117
- messages,
1176
+ messages: forcedChoiceRefused
1177
+ ? [...messages, createRuntimeContextMessage(FORCED_STEP_MESSAGE, 'progress-nudge')]
1178
+ : messages,
1118
1179
  tools: llmTools.length > 0 ? llmTools : undefined,
1119
1180
  ...(enforceToolInputSchema ? { enforceToolInputSchema } : {}),
1120
1181
  // The forced-final turn wins: a step that asked to force a
@@ -1126,14 +1187,16 @@ export class IterationOrchestrator {
1126
1187
  forceFinalize && llmTools.length > 0
1127
1188
  ? 'none'
1128
1189
  : llmTools.length > 0
1129
- ? step.toolChoice
1190
+ ? forcedAction && !forcedChoiceRefused
1191
+ ? (step.toolChoice ?? 'required')
1192
+ : step.toolChoice
1130
1193
  : undefined,
1131
1194
  temperature: step.temperature ?? turnConfig.temperature,
1132
1195
  maxTokens:
1133
1196
  outputCapOverride ?? step.maxResponseTokens ?? turnConfig.maxResponseTokens,
1134
1197
  cacheControl: { type: 'auto' },
1135
1198
  ...(turnConfig.thinking ? { thinking: turnConfig.thinking } : {}),
1136
- ...(requestEffort ? { effort: requestEffort } : {}),
1199
+ ...(stepEffort ? { effort: stepEffort } : {}),
1137
1200
  ...(!forceFinalize && turnConfig.webSearch
1138
1201
  ? { webSearch: turnConfig.webSearch }
1139
1202
  : {}),
@@ -1159,8 +1222,15 @@ export class IterationOrchestrator {
1159
1222
  this.ctx.reviewAnswer || this.ctx.structuredOutput?.review || this.ctx.advisoryCtx,
1160
1223
  ),
1161
1224
  recorder.sessionId,
1225
+ // Applies only to a step that can act. Stops after a few capped
1226
+ // steps in a row, so a model that cannot act within the allowance
1227
+ // still gets to finish.
1228
+ this.cappedStreak >= MAX_CAPPED_STREAK || forceFinalize || llmTools.length === 0
1229
+ ? undefined
1230
+ : reasoningCapChars(turnConfig.reasoning, stepEffort),
1162
1231
  )
1163
1232
  stepResponse = response
1233
+ this.cappedStreak = reasoningCapped ? this.cappedStreak + 1 : 0
1164
1234
  const reviewRequest: ReviewRequest = {
1165
1235
  ...(requestMessages ? { requestMessages } : {}),
1166
1236
  ...(latestReviewUserMessage ? { latestUserMessage: latestReviewUserMessage } : {}),
@@ -1461,6 +1531,28 @@ export class IterationOrchestrator {
1461
1531
  costBefore,
1462
1532
  })
1463
1533
 
1534
+ // The step spent its whole reasoning allowance before acting. Tell
1535
+ // the model so and make the next step an action step.
1536
+ if (reasoningCapped && !forceFinalize) {
1537
+ this.ctx.log.info('Reasoning reached the per-step cap — asking the model to act', {
1538
+ [NAMZU.TURN_ID]: recorder.turnId,
1539
+ [NAMZU.ITERATION]: iterationNum,
1540
+ })
1541
+ recorder.pushMessage(
1542
+ createRuntimeContextMessage(REASONING_CAPPED_MESSAGE, 'progress-nudge'),
1543
+ )
1544
+ this.forceActionNextStep = true
1545
+ this.observeStall(response, [])
1546
+ await this.ctx.emitEvent({
1547
+ type: 'iteration_completed',
1548
+ turnId: recorder.turnId,
1549
+ iteration: iterationNum,
1550
+ hasToolCalls: false,
1551
+ })
1552
+ yield* this.ctx.drainPending()
1553
+ continue
1554
+ }
1555
+
1464
1556
  if (this.ctx.structuredOutput?.mode === 'native') {
1465
1557
  const candidate = await parseNativeCandidate(
1466
1558
  this.ctx.structuredOutput.schema,
@@ -1745,6 +1837,28 @@ export class IterationOrchestrator {
1745
1837
  let closingStopReason: StopReason | undefined = forceFinalize
1746
1838
  ? guardResult.stopReason
1747
1839
  : undefined
1840
+ const reasoningOnly = !hasContent && (response.message.reasoning?.length ?? 0) > 0
1841
+ if (hasContent) this.reasoningOnlyRetried = false
1842
+ // A reply of reasoning alone is not an end: ask once more, plainly,
1843
+ // before the closing request below.
1844
+ if (reasoningOnly && !forceFinalize && !this.reasoningOnlyRetried) {
1845
+ this.reasoningOnlyRetried = true
1846
+ this.ctx.log.warn('Reply held reasoning only — asking once more', {
1847
+ [NAMZU.TURN_ID]: recorder.turnId,
1848
+ [NAMZU.ITERATION]: iterationNum,
1849
+ })
1850
+ recorder.pushMessage(
1851
+ createRuntimeContextMessage(REASONING_ONLY_MESSAGE, 'progress-nudge'),
1852
+ )
1853
+ await this.ctx.emitEvent({
1854
+ type: 'iteration_completed',
1855
+ turnId: recorder.turnId,
1856
+ iteration: iterationNum,
1857
+ hasToolCalls: false,
1858
+ })
1859
+ yield* this.ctx.drainPending()
1860
+ continue
1861
+ }
1748
1862
  if (!hasContent && !forceFinalize) {
1749
1863
  this.ctx.log.warn('Empty completion detected — requesting final summary', {
1750
1864
  [NAMZU.ITERATION]: iterationNum,
@@ -1755,6 +1869,23 @@ export class IterationOrchestrator {
1755
1869
  'end_turn',
1756
1870
  )
1757
1871
  yield* this.ctx.drainPending()
1872
+ // Never end silently: if even the closing request produced nothing,
1873
+ // say so in plain words and how to go on.
1874
+ if (
1875
+ reasoningOnly &&
1876
+ closingStopReason === undefined &&
1877
+ !(
1878
+ (
1879
+ [...recorder.messages].reverse().find((m) => m.role === 'assistant') as
1880
+ | { content?: string | null }
1881
+ | undefined
1882
+ )?.content ?? ''
1883
+ ).length
1884
+ ) {
1885
+ recorder.setLastError(
1886
+ 'The model stopped after thinking without giving an answer or taking an action, even when asked again. Say "continue" and it will pick the work up from here.',
1887
+ )
1888
+ }
1758
1889
  }
1759
1890
 
1760
1891
  await this.ctx.emitEvent({
@@ -1787,6 +1918,21 @@ export class IterationOrchestrator {
1787
1918
  // The model is done and has no tool calls. A `turn_end` (or
1788
1919
  // `subagent_stop`) hook may refuse to let it be: its reason goes
1789
1920
  // back to the model and the turn goes on.
1921
+ // Files were changed and nothing checked them afterwards: ask once
1922
+ // for a check before the turn is allowed to end.
1923
+ if (
1924
+ !forceFinalize &&
1925
+ closingStopReason === undefined &&
1926
+ this.completionAudit?.takeBlock()
1927
+ ) {
1928
+ this.ctx.log.info('Files changed and nothing checked them — asking for a check', {
1929
+ [NAMZU.TURN_ID]: recorder.turnId,
1930
+ })
1931
+ recorder.pushMessage(
1932
+ createRuntimeContextMessage(COMPLETION_AUDIT_MESSAGE, 'progress-nudge'),
1933
+ )
1934
+ continue
1935
+ }
1790
1936
  if (!forceFinalize && closingStopReason === undefined) {
1791
1937
  const feedback = yield* this.askStopHooks()
1792
1938
  const stoppedByHook = this.ctx.toolExecutor.takeHalt?.()
@@ -1833,6 +1979,9 @@ export class IterationOrchestrator {
1833
1979
  usageBefore,
1834
1980
  costBefore,
1835
1981
  })
1982
+ this.reasoningOnlyRetried = false
1983
+ this.observeStall(response, reviewOutcome.results)
1984
+ this.observeAudit(response, reviewOutcome.results)
1836
1985
 
1837
1986
  if (reviewOutcome.decision === 'stop') {
1838
1987
  return
@@ -3118,6 +3267,69 @@ export class IterationOrchestrator {
3118
3267
  }
3119
3268
  }
3120
3269
 
3270
+ /** Feed the completion audit the calls of one finished step. */
3271
+ private observeAudit(
3272
+ response: ChatCompletionResponse,
3273
+ results: readonly ToolCallOutcome[],
3274
+ ): void {
3275
+ const audit = this.completionAudit
3276
+ if (!audit) return
3277
+ const calls = new Map((response.message.toolCalls ?? []).map((c) => [c.id, c]))
3278
+ audit.observe(
3279
+ results.map((result) => {
3280
+ let input: unknown
3281
+ try {
3282
+ const call = calls.get(result.toolCallId)
3283
+ input = call ? JSON.parse(call.function.arguments) : undefined
3284
+ } catch {
3285
+ input = undefined
3286
+ }
3287
+ return { toolName: result.toolName, input, isError: result.isError }
3288
+ }),
3289
+ )
3290
+ }
3291
+
3292
+ /**
3293
+ * Feed the stall monitor one finished step and act on its verdict: a nudge
3294
+ * is recorded as a message, a force makes the next step an action step.
3295
+ */
3296
+ private observeStall(
3297
+ response: ChatCompletionResponse,
3298
+ results: readonly ToolCallOutcome[],
3299
+ ): void {
3300
+ const monitor = this.stallMonitor
3301
+ if (!monitor) return
3302
+ const calls = new Map((response.message.toolCalls ?? []).map((c) => [c.id, c]))
3303
+ let changedState = false
3304
+ for (const result of results) {
3305
+ const call = calls.get(result.toolCallId)
3306
+ let readOnly: boolean | undefined
3307
+ try {
3308
+ const input = call ? JSON.parse(call.function.arguments) : undefined
3309
+ readOnly = this.ctx.tools.get(result.toolName)?.isReadOnly?.(input)
3310
+ } catch {
3311
+ readOnly = undefined
3312
+ }
3313
+ if (callChangedState(result.toolName, readOnly, result.isError)) changedState = true
3314
+ }
3315
+ const reasoningChars = (response.message.reasoning ?? []).reduce(
3316
+ (n, block) => n + (block.text?.length ?? 0),
3317
+ 0,
3318
+ )
3319
+ const directive = monitor.observe({ reasoningChars, changedState })
3320
+ if (directive.kind === 'nudge') {
3321
+ this.ctx.log.info('Many steps without a change — nudging the model to act', {
3322
+ [NAMZU.TURN_ID]: this.ctx.recorder.turnId,
3323
+ })
3324
+ this.ctx.recorder.pushMessage(createRuntimeContextMessage(directive.text, 'progress-nudge'))
3325
+ } else if (directive.kind === 'force') {
3326
+ this.ctx.log.info('Still no change after the nudge — forcing an action step', {
3327
+ [NAMZU.TURN_ID]: this.ctx.recorder.turnId,
3328
+ })
3329
+ this.forceActionNextStep = true
3330
+ }
3331
+ }
3332
+
3121
3333
  private async requestFinalResponse(
3122
3334
  model: string,
3123
3335
  reason: StopReason,
@@ -573,11 +573,13 @@ export class PerCallReview implements ReviewedExecution {
573
573
  for (const call of calls) {
574
574
  const mods = decision.modifications.filter((mod) => mod.toolCallId === call.id)
575
575
  if (mods.some((mod) => mod.action === 'deny')) {
576
- verdicts.set(call.id, {
577
- run: false,
578
- reason: DECLINED_TOOL_CALL_FEEDBACK,
579
- declined: {},
580
- })
576
+ const policy = decision.policyRefusals?.[call.id]
577
+ verdicts.set(
578
+ call.id,
579
+ policy !== undefined
580
+ ? { run: false, reason: policy }
581
+ : { run: false, reason: DECLINED_TOOL_CALL_FEEDBACK, declined: {} },
582
+ )
581
583
  } else if (mods.some((mod) => mod.action === 'modify')) {
582
584
  verdicts.set(call.id, { run: false, reason: EDIT_NOT_OFFERED })
583
585
  } else if (mods.some((mod) => mod.action === 'approve')) {
@@ -1127,9 +1127,11 @@ export async function* runToolReview(
1127
1127
  }
1128
1128
  }
1129
1129
  if (mod.action === 'deny' && !denials.has(mod.toolCallId)) {
1130
- denials.set(mod.toolCallId, DECLINED_TOOL_CALL_FEEDBACK)
1131
- // A per-call deny is the person's own answer; gate denials above are not.
1132
- humanDenied.set(mod.toolCallId, {})
1130
+ const policy = reviewDecision.policyRefusals?.[mod.toolCallId]
1131
+ denials.set(mod.toolCallId, policy ?? DECLINED_TOOL_CALL_FEEDBACK)
1132
+ // A per-call deny is the person's own answer; gate denials and a
1133
+ // policy's refusal of one call are not.
1134
+ if (policy === undefined) humanDenied.set(mod.toolCallId, {})
1133
1135
  }
1134
1136
  }
1135
1137
 
@@ -26,6 +26,7 @@ export function appendRecordedContext(
26
26
  items: readonly RecordedContextItem[] | undefined,
27
27
  log: Pick<Logger, 'warn'>,
28
28
  at: Date = new Date(),
29
+ onAppended?: (item: RecordedContextItem) => void,
29
30
  ): Message[] {
30
31
  const appended: Message[] = []
31
32
  for (const item of items ?? []) {
@@ -43,6 +44,7 @@ export function appendRecordedContext(
43
44
  const entry = createTurnContextEntry(item.key, text, at, { later: earlier.length > 0 })
44
45
  recorder.pushMessage(entry)
45
46
  appended.push(entry)
47
+ onAppended?.(item)
46
48
  }
47
49
  return appended
48
50
  }