@namzu/sdk 61.3.0 → 62.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 (307) hide show
  1. package/CHANGELOG.md +61 -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/acp/permission.d.ts +8 -0
  6. package/dist/bridge/acp/permission.d.ts.map +1 -1
  7. package/dist/bridge/acp/permission.js.map +1 -1
  8. package/dist/bridge/acp/server.d.ts.map +1 -1
  9. package/dist/bridge/acp/server.js +8 -1
  10. package/dist/bridge/acp/server.js.map +1 -1
  11. package/dist/constants/tools/index.d.ts +2 -0
  12. package/dist/constants/tools/index.d.ts.map +1 -1
  13. package/dist/constants/tools/index.js +23 -0
  14. package/dist/constants/tools/index.js.map +1 -1
  15. package/dist/eval/harness-protection.js +1 -1
  16. package/dist/eval/harness-protection.js.map +1 -1
  17. package/dist/learning/cycle.d.ts +5 -3
  18. package/dist/learning/cycle.d.ts.map +1 -1
  19. package/dist/learning/cycle.js +11 -13
  20. package/dist/learning/cycle.js.map +1 -1
  21. package/dist/learning/guidance.d.ts +74 -0
  22. package/dist/learning/guidance.d.ts.map +1 -0
  23. package/dist/learning/guidance.js +259 -0
  24. package/dist/learning/guidance.js.map +1 -0
  25. package/dist/learning/skill.d.ts +2 -2
  26. package/dist/learning/skill.d.ts.map +1 -1
  27. package/dist/learning/skill.js +6 -6
  28. package/dist/learning/skill.js.map +1 -1
  29. package/dist/learning/store.d.ts.map +1 -1
  30. package/dist/learning/store.js +6 -6
  31. package/dist/learning/store.js.map +1 -1
  32. package/dist/pals/communication/ingress-schema.d.ts +8 -8
  33. package/dist/pals/communication/schema.d.ts +2 -2
  34. package/dist/peers/client.d.ts +2 -3
  35. package/dist/peers/client.d.ts.map +1 -1
  36. package/dist/peers/client.js +2 -3
  37. package/dist/peers/client.js.map +1 -1
  38. package/dist/peers/endpoint.d.ts +1 -2
  39. package/dist/peers/endpoint.d.ts.map +1 -1
  40. package/dist/peers/endpoint.js +1 -2
  41. package/dist/peers/endpoint.js.map +1 -1
  42. package/dist/peers/protocol.d.ts.map +1 -1
  43. package/dist/peers/protocol.js +1 -0
  44. package/dist/peers/protocol.js.map +1 -1
  45. package/dist/prompt/coding-agent-doctrine.d.ts +4 -4
  46. package/dist/prompt/coding-agent-doctrine.d.ts.map +1 -1
  47. package/dist/prompt/coding-agent-doctrine.js +5 -3
  48. package/dist/prompt/coding-agent-doctrine.js.map +1 -1
  49. package/dist/prompt/index.d.ts +0 -4
  50. package/dist/prompt/index.d.ts.map +1 -1
  51. package/dist/prompt/index.js +0 -2
  52. package/dist/prompt/index.js.map +1 -1
  53. package/dist/provider/fallback.d.ts.map +1 -1
  54. package/dist/provider/fallback.js +3 -0
  55. package/dist/provider/fallback.js.map +1 -1
  56. package/dist/provider/idle-timeout.d.ts.map +1 -1
  57. package/dist/provider/idle-timeout.js +5 -0
  58. package/dist/provider/idle-timeout.js.map +1 -1
  59. package/dist/provider/model-window-suffix.d.ts.map +1 -1
  60. package/dist/provider/model-window-suffix.js +1 -0
  61. package/dist/provider/model-window-suffix.js.map +1 -1
  62. package/dist/provider/retry.d.ts.map +1 -1
  63. package/dist/provider/retry.js +5 -0
  64. package/dist/provider/retry.js.map +1 -1
  65. package/dist/provider/step-stopped.d.ts +19 -0
  66. package/dist/provider/step-stopped.d.ts.map +1 -0
  67. package/dist/provider/step-stopped.js +25 -0
  68. package/dist/provider/step-stopped.js.map +1 -0
  69. package/dist/provider/token-budget.d.ts.map +1 -1
  70. package/dist/provider/token-budget.js +6 -1
  71. package/dist/provider/token-budget.js.map +1 -1
  72. package/dist/public-runtime.d.ts +4 -15
  73. package/dist/public-runtime.d.ts.map +1 -1
  74. package/dist/public-runtime.js +3 -14
  75. package/dist/public-runtime.js.map +1 -1
  76. package/dist/public-tools.d.ts +0 -2
  77. package/dist/public-tools.d.ts.map +1 -1
  78. package/dist/public-tools.js +0 -2
  79. package/dist/public-tools.js.map +1 -1
  80. package/dist/public-types.d.ts +3 -21
  81. package/dist/public-types.d.ts.map +1 -1
  82. package/dist/runtime/query/iteration/index.d.ts +17 -0
  83. package/dist/runtime/query/iteration/index.d.ts.map +1 -1
  84. package/dist/runtime/query/iteration/index.js +168 -5
  85. package/dist/runtime/query/iteration/index.js.map +1 -1
  86. package/dist/runtime/query/iteration/phases/per-call-review.d.ts.map +1 -1
  87. package/dist/runtime/query/iteration/phases/per-call-review.js +4 -5
  88. package/dist/runtime/query/iteration/phases/per-call-review.js.map +1 -1
  89. package/dist/runtime/query/iteration/phases/tool-review.d.ts.map +1 -1
  90. package/dist/runtime/query/iteration/phases/tool-review.js +6 -3
  91. package/dist/runtime/query/iteration/phases/tool-review.js.map +1 -1
  92. package/dist/runtime/query/iteration/stream-turn.d.ts +9 -1
  93. package/dist/runtime/query/iteration/stream-turn.d.ts.map +1 -1
  94. package/dist/runtime/query/iteration/stream-turn.js +48 -2
  95. package/dist/runtime/query/iteration/stream-turn.js.map +1 -1
  96. package/dist/runtime/query/resume-pending.d.ts.map +1 -1
  97. package/dist/runtime/query/resume-pending.js +7 -4
  98. package/dist/runtime/query/resume-pending.js.map +1 -1
  99. package/dist/runtime/query/review-policy.d.ts +40 -8
  100. package/dist/runtime/query/review-policy.d.ts.map +1 -1
  101. package/dist/runtime/query/review-policy.js +139 -24
  102. package/dist/runtime/query/review-policy.js.map +1 -1
  103. package/dist/runtime/query/turn/completion-audit.d.ts +32 -0
  104. package/dist/runtime/query/turn/completion-audit.d.ts.map +1 -0
  105. package/dist/runtime/query/turn/completion-audit.js +56 -0
  106. package/dist/runtime/query/turn/completion-audit.js.map +1 -0
  107. package/dist/runtime/query/turn/stall-monitor.d.ts +78 -0
  108. package/dist/runtime/query/turn/stall-monitor.d.ts.map +1 -0
  109. package/dist/runtime/query/turn/stall-monitor.js +101 -0
  110. package/dist/runtime/query/turn/stall-monitor.js.map +1 -0
  111. package/dist/session/paths.d.ts +1 -2
  112. package/dist/session/paths.d.ts.map +1 -1
  113. package/dist/session/paths.js +1 -4
  114. package/dist/session/paths.js.map +1 -1
  115. package/dist/tools/builtins/bash.d.ts +2 -1
  116. package/dist/tools/builtins/bash.d.ts.map +1 -1
  117. package/dist/tools/builtins/bash.js +5 -2
  118. package/dist/tools/builtins/bash.js.map +1 -1
  119. package/dist/tools/builtins/computer-use.d.ts +80 -0
  120. package/dist/tools/builtins/computer-use.d.ts.map +1 -1
  121. package/dist/tools/builtins/computer-use.js +172 -9
  122. package/dist/tools/builtins/computer-use.js.map +1 -1
  123. package/dist/tools/builtins/content-fingerprint.d.ts +13 -0
  124. package/dist/tools/builtins/content-fingerprint.d.ts.map +1 -1
  125. package/dist/tools/builtins/content-fingerprint.js +25 -0
  126. package/dist/tools/builtins/content-fingerprint.js.map +1 -1
  127. package/dist/tools/builtins/edit.d.ts.map +1 -1
  128. package/dist/tools/builtins/edit.js +7 -2
  129. package/dist/tools/builtins/edit.js.map +1 -1
  130. package/dist/tools/builtins/shell-read-credit.d.ts +15 -0
  131. package/dist/tools/builtins/shell-read-credit.d.ts.map +1 -0
  132. package/dist/tools/builtins/shell-read-credit.js +161 -0
  133. package/dist/tools/builtins/shell-read-credit.js.map +1 -0
  134. package/dist/tools/paths.d.ts +15 -2
  135. package/dist/tools/paths.d.ts.map +1 -1
  136. package/dist/tools/paths.js +17 -2
  137. package/dist/tools/paths.js.map +1 -1
  138. package/dist/turn/evidence-recall.d.ts +1 -1
  139. package/dist/turn/evidence-recall.d.ts.map +1 -1
  140. package/dist/turn/evidence-recall.js +5 -14
  141. package/dist/turn/evidence-recall.js.map +1 -1
  142. package/dist/types/acp/index.d.ts +6 -0
  143. package/dist/types/acp/index.d.ts.map +1 -1
  144. package/dist/types/agent/base.d.ts +4 -0
  145. package/dist/types/agent/base.d.ts.map +1 -1
  146. package/dist/types/hitl/index.d.ts +8 -0
  147. package/dist/types/hitl/index.d.ts.map +1 -1
  148. package/dist/types/hitl/index.js.map +1 -1
  149. package/dist/types/ids/index.d.ts +1 -1
  150. package/dist/types/message/index.d.ts +1 -1
  151. package/dist/types/message/index.d.ts.map +1 -1
  152. package/dist/types/message/index.js +1 -0
  153. package/dist/types/message/index.js.map +1 -1
  154. package/dist/types/provider/interface.d.ts +12 -0
  155. package/dist/types/provider/interface.d.ts.map +1 -1
  156. package/dist/types/session/config.d.ts +25 -0
  157. package/dist/types/session/config.d.ts.map +1 -1
  158. package/dist/types/session/records.d.ts.map +1 -1
  159. package/dist/types/session/records.js +2 -0
  160. package/dist/types/session/records.js.map +1 -1
  161. package/dist/types/session/turn.d.ts +1 -1
  162. package/dist/types/session/turn.d.ts.map +1 -1
  163. package/dist/types/session/turn.js.map +1 -1
  164. package/package.json +1 -1
  165. package/src/agents/QueryAgent.ts +2 -0
  166. package/src/bridge/acp/permission.ts +8 -0
  167. package/src/bridge/acp/server.ts +7 -1
  168. package/src/constants/tools/index.ts +27 -0
  169. package/src/eval/harness-protection.ts +1 -1
  170. package/src/learning/cycle.ts +15 -16
  171. package/src/learning/guidance.ts +339 -0
  172. package/src/learning/skill.ts +7 -7
  173. package/src/learning/store.ts +5 -6
  174. package/src/peers/client.ts +2 -3
  175. package/src/peers/endpoint.ts +1 -2
  176. package/src/peers/protocol.ts +1 -0
  177. package/src/prompt/coding-agent-doctrine.ts +5 -3
  178. package/src/prompt/index.ts +0 -4
  179. package/src/provider/fallback.ts +7 -0
  180. package/src/provider/idle-timeout.ts +8 -0
  181. package/src/provider/model-window-suffix.ts +1 -0
  182. package/src/provider/retry.ts +8 -0
  183. package/src/provider/step-stopped.ts +27 -0
  184. package/src/provider/token-budget.ts +6 -1
  185. package/src/public-runtime.ts +10 -28
  186. package/src/public-tools.ts +0 -3
  187. package/src/public-types.ts +5 -137
  188. package/src/runtime/query/iteration/index.ts +207 -5
  189. package/src/runtime/query/iteration/phases/per-call-review.ts +7 -5
  190. package/src/runtime/query/iteration/phases/tool-review.ts +5 -3
  191. package/src/runtime/query/iteration/stream-turn.ts +51 -1
  192. package/src/runtime/query/resume-pending.ts +11 -4
  193. package/src/runtime/query/review-policy.ts +157 -24
  194. package/src/runtime/query/turn/completion-audit.ts +71 -0
  195. package/src/runtime/query/turn/stall-monitor.ts +158 -0
  196. package/src/session/paths.ts +2 -6
  197. package/src/tools/builtins/bash.ts +6 -2
  198. package/src/tools/builtins/computer-use.ts +245 -7
  199. package/src/tools/builtins/content-fingerprint.ts +25 -0
  200. package/src/tools/builtins/edit.ts +11 -2
  201. package/src/tools/builtins/shell-read-credit.ts +159 -0
  202. package/src/tools/paths.ts +18 -2
  203. package/src/turn/evidence-recall.ts +7 -15
  204. package/src/types/acp/index.ts +6 -0
  205. package/src/types/agent/base.ts +4 -0
  206. package/src/types/hitl/index.ts +8 -0
  207. package/src/types/ids/index.ts +1 -1
  208. package/src/types/message/index.ts +1 -0
  209. package/src/types/provider/interface.ts +13 -0
  210. package/src/types/session/config.ts +27 -0
  211. package/src/types/session/records.ts +2 -0
  212. package/src/types/session/turn.ts +2 -1
  213. package/dist/learning/deprecated.d.ts +0 -86
  214. package/dist/learning/deprecated.d.ts.map +0 -1
  215. package/dist/learning/deprecated.js +0 -22
  216. package/dist/learning/deprecated.js.map +0 -1
  217. package/dist/manager/resident/activity.d.ts +0 -74
  218. package/dist/manager/resident/activity.d.ts.map +0 -1
  219. package/dist/manager/resident/activity.js +0 -125
  220. package/dist/manager/resident/activity.js.map +0 -1
  221. package/dist/manager/resident/agenda.d.ts +0 -167
  222. package/dist/manager/resident/agenda.d.ts.map +0 -1
  223. package/dist/manager/resident/agenda.js +0 -588
  224. package/dist/manager/resident/agenda.js.map +0 -1
  225. package/dist/manager/resident/consumption.d.ts +0 -98
  226. package/dist/manager/resident/consumption.d.ts.map +0 -1
  227. package/dist/manager/resident/consumption.js +0 -237
  228. package/dist/manager/resident/consumption.js.map +0 -1
  229. package/dist/manager/resident/delivery-window.d.ts +0 -28
  230. package/dist/manager/resident/delivery-window.d.ts.map +0 -1
  231. package/dist/manager/resident/delivery-window.js +0 -80
  232. package/dist/manager/resident/delivery-window.js.map +0 -1
  233. package/dist/manager/resident/evidence-recall.d.ts +0 -30
  234. package/dist/manager/resident/evidence-recall.d.ts.map +0 -1
  235. package/dist/manager/resident/evidence-recall.js +0 -297
  236. package/dist/manager/resident/evidence-recall.js.map +0 -1
  237. package/dist/manager/resident/history-disk.d.ts +0 -10
  238. package/dist/manager/resident/history-disk.d.ts.map +0 -1
  239. package/dist/manager/resident/history-disk.js +0 -50
  240. package/dist/manager/resident/history-disk.js.map +0 -1
  241. package/dist/manager/resident/history.d.ts +0 -115
  242. package/dist/manager/resident/history.d.ts.map +0 -1
  243. package/dist/manager/resident/history.js +0 -203
  244. package/dist/manager/resident/history.js.map +0 -1
  245. package/dist/manager/resident/host.d.ts +0 -112
  246. package/dist/manager/resident/host.d.ts.map +0 -1
  247. package/dist/manager/resident/host.js +0 -254
  248. package/dist/manager/resident/host.js.map +0 -1
  249. package/dist/manager/resident/initiative.d.ts +0 -86
  250. package/dist/manager/resident/initiative.d.ts.map +0 -1
  251. package/dist/manager/resident/initiative.js +0 -131
  252. package/dist/manager/resident/initiative.js.map +0 -1
  253. package/dist/manager/resident/loop.d.ts +0 -49
  254. package/dist/manager/resident/loop.d.ts.map +0 -1
  255. package/dist/manager/resident/loop.js +0 -75
  256. package/dist/manager/resident/loop.js.map +0 -1
  257. package/dist/manager/resident/outbox.d.ts +0 -124
  258. package/dist/manager/resident/outbox.d.ts.map +0 -1
  259. package/dist/manager/resident/outbox.js +0 -216
  260. package/dist/manager/resident/outbox.js.map +0 -1
  261. package/dist/manager/resident/proposal.d.ts +0 -65
  262. package/dist/manager/resident/proposal.d.ts.map +0 -1
  263. package/dist/manager/resident/proposal.js +0 -77
  264. package/dist/manager/resident/proposal.js.map +0 -1
  265. package/dist/manager/resident/store.d.ts +0 -108
  266. package/dist/manager/resident/store.d.ts.map +0 -1
  267. package/dist/manager/resident/store.js +0 -205
  268. package/dist/manager/resident/store.js.map +0 -1
  269. package/dist/manager/resident/tool-evidence.d.ts +0 -112
  270. package/dist/manager/resident/tool-evidence.d.ts.map +0 -1
  271. package/dist/manager/resident/tool-evidence.js +0 -289
  272. package/dist/manager/resident/tool-evidence.js.map +0 -1
  273. package/dist/prompt/resident-learning.d.ts +0 -29
  274. package/dist/prompt/resident-learning.d.ts.map +0 -1
  275. package/dist/prompt/resident-learning.js +0 -126
  276. package/dist/prompt/resident-learning.js.map +0 -1
  277. package/dist/prompt/resident-step.d.ts +0 -42
  278. package/dist/prompt/resident-step.d.ts.map +0 -1
  279. package/dist/prompt/resident-step.js +0 -137
  280. package/dist/prompt/resident-step.js.map +0 -1
  281. package/dist/tools/resident-history.d.ts +0 -12
  282. package/dist/tools/resident-history.d.ts.map +0 -1
  283. package/dist/tools/resident-history.js +0 -82
  284. package/dist/tools/resident-history.js.map +0 -1
  285. package/dist/tools/resident-tool-evidence.d.ts +0 -9
  286. package/dist/tools/resident-tool-evidence.d.ts.map +0 -1
  287. package/dist/tools/resident-tool-evidence.js +0 -61
  288. package/dist/tools/resident-tool-evidence.js.map +0 -1
  289. package/src/learning/deprecated.ts +0 -124
  290. package/src/manager/resident/activity.ts +0 -211
  291. package/src/manager/resident/agenda.ts +0 -937
  292. package/src/manager/resident/consumption.ts +0 -335
  293. package/src/manager/resident/delivery-window.ts +0 -99
  294. package/src/manager/resident/evidence-recall.ts +0 -369
  295. package/src/manager/resident/history-disk.ts +0 -63
  296. package/src/manager/resident/history.ts +0 -348
  297. package/src/manager/resident/host.ts +0 -390
  298. package/src/manager/resident/initiative.ts +0 -231
  299. package/src/manager/resident/loop.ts +0 -119
  300. package/src/manager/resident/outbox.ts +0 -341
  301. package/src/manager/resident/proposal.ts +0 -119
  302. package/src/manager/resident/store.ts +0 -279
  303. package/src/manager/resident/tool-evidence.ts +0 -455
  304. package/src/prompt/resident-learning.ts +0 -152
  305. package/src/prompt/resident-step.ts +0 -182
  306. package/src/tools/resident-history.ts +0 -88
  307. package/src/tools/resident-tool-evidence.ts +0 -72
@@ -1,369 +0,0 @@
1
- import { z } from 'zod'
2
- import type { SessionEvidenceScope } from '../../store/evidence/types.js'
3
- import {
4
- type EvidenceRecallRequest,
5
- type ScopedEvidenceRecallBatch,
6
- type ScopedEvidenceRecallCandidate,
7
- createScopedEvidenceRecallStep,
8
- evidenceRecallQueryTokens,
9
- refineEvidenceRecallTerms,
10
- } from '../../turn/evidence-recall.js'
11
- import type { PrepareStep } from '../../types/session/prepare-step.js'
12
- import { evidenceTokenKey } from '../../utils/evidence-tokens.js'
13
- import { type ResidentState, residentStateSchema } from './store.js'
14
- import type { ResidentToolEvidenceSource } from './tool-evidence.js'
15
-
16
- /**
17
- * @experimental Automatic original-tool recall for exactly one admitted resident turn.
18
- *
19
- * @deprecated Residents are deprecated and removed in the next major release. Learning (`runLearningCycle` and the other `Learning*` names) keeps working, but `runLearningCycle` still takes a resident agenda until learning gets its own activation target in the next major release; for long-running work use scheduled tasks (`LocalTaskScheduler`), session goals and background agents.
20
- */
21
- export interface ResidentEvidenceRecallOptions {
22
- readonly source: ResidentToolEvidenceSource
23
- /** Already admitted state; summaries supply search words, never new observations. */
24
- readonly state: ResidentState
25
- /** The current executor's turn, distinct from historical session/turn addresses. */
26
- readonly scope: SessionEvidenceScope
27
- readonly maxChars?: number
28
- readonly maxPassages?: number
29
- readonly timeoutMs?: number
30
- /** Host tool names whose successful archival copies should not occupy result slots. */
31
- readonly excludeSuccessfulTools?: readonly string[]
32
- }
33
-
34
- const ownerSchema = z.object({
35
- tenantId: z.string().uuid(),
36
- projectId: z.string().uuid(),
37
- sessionId: z.string().uuid(),
38
- turnId: z.string().uuid(),
39
- })
40
- const historicalScopeSchema = ownerSchema.omit({ sessionId: true, turnId: true }).extend({
41
- agentKey: z.string().min(1).max(200),
42
- pursuitId: z.string().uuid(),
43
- throughRevision: z.number().int().positive().safe(),
44
- })
45
-
46
- // Sample both ends without merging or manufacturing a word at the cut. The
47
- // field still contributes at most 4000 characters; its omitted middle is not
48
- // inspected. Alternating ends also gives late corrections a term slot.
49
- function residentQueryWords(text: string): string[] {
50
- const words =
51
- text.length <= 4000
52
- ? evidenceRecallQueryTokens(text)
53
- : [
54
- ...evidenceRecallQueryTokens(
55
- text
56
- .slice(0, 2000)
57
- .replace(/[\uD800-\uDBFF]$/u, '')
58
- .replace(/[\p{L}\p{N}_]+$/u, ''),
59
- ),
60
- ...evidenceRecallQueryTokens(
61
- text
62
- .slice(-2000)
63
- .replace(/^[\uDC00-\uDFFF]/u, '')
64
- .replace(/^[\p{L}\p{N}_]+/u, ''),
65
- ),
66
- ]
67
- const result: string[] = []
68
- for (let left = 0, right = words.length - 1; left <= right; left++, right--) {
69
- const first = words[left]
70
- const last = words[right]
71
- if (first) result.push(first)
72
- if (left !== right && last) result.push(last)
73
- }
74
- return result
75
- }
76
-
77
- /**
78
- * Reuses the shared bounded ranking/rendering engine while retaining the
79
- * pursuit's settlement authority. No arbitrary Session discovery, saved fact
80
- * cache, inference, workspace reread or action replay is performed here.
81
- *
82
- * @deprecated Residents are deprecated and removed in the next major release. Learning (`runLearningCycle` and the other `Learning*` names) keeps working, but `runLearningCycle` still takes a resident agenda until learning gets its own activation target in the next major release; for long-running work use scheduled tasks (`LocalTaskScheduler`), session goals and background agents.
83
- */
84
- export function createResidentEvidenceRecallStep(
85
- options: ResidentEvidenceRecallOptions,
86
- ): PrepareStep {
87
- const state = residentStateSchema.parse(options.state)
88
- const owner = Object.freeze(ownerSchema.parse(options.scope))
89
- const source = options.source
90
- const historicalScope = Object.freeze(historicalScopeSchema.parse(source.scope))
91
- if (
92
- state.phase !== 'running' ||
93
- !state.claimId ||
94
- state.tenantId !== owner.tenantId ||
95
- state.tenantId !== historicalScope.tenantId ||
96
- owner.projectId !== historicalScope.projectId ||
97
- state.agentKey !== historicalScope.agentKey ||
98
- state.pursuitId !== historicalScope.pursuitId
99
- )
100
- throw new Error('Resident recall requires one admitted pursuit and its authorized source.')
101
- const exclusions = options.excludeSuccessfulTools
102
- ? [...new Set(options.excludeSuccessfulTools)].sort()
103
- : undefined
104
- if (
105
- exclusions &&
106
- (exclusions.length > 16 ||
107
- exclusions.some((name) => typeof name !== 'string' || !name.length || name.length > 256))
108
- )
109
- throw new Error('Resident recall exclusions are invalid.')
110
- if (
111
- Buffer.byteLength(
112
- JSON.stringify({
113
- terms: ['x'],
114
- ...(exclusions?.length ? { excludeSuccessfulTools: exclusions } : {}),
115
- }),
116
- ) > 512
117
- )
118
- throw new Error('Resident recall exclusions leave no bounded search room.')
119
- const snapshot = JSON.stringify(historicalScope)
120
- function assertSource() {
121
- if (JSON.stringify(historicalScopeSchema.parse(source.scope)) !== snapshot)
122
- throw new Error('Resident recall source changed ownership or admission boundary.')
123
- }
124
-
125
- // Round-robin categories keep a long objective or derived summary from
126
- // monopolizing all search terms. Within wakes, newer accepted inputs start
127
- // first; their original committed index is retained in query metadata.
128
- const wakes = (state.wakeEvidence ?? [])
129
- .map((wake, index) => ({
130
- kind: 'accepted_wake' as const,
131
- index,
132
- words: residentQueryWords(wake.reason),
133
- }))
134
- .reverse()
135
- const wakeWords: { term: string; source: string; wakeIndex?: number }[] = []
136
- for (let word = 0; word < 256; word++)
137
- for (const wake of wakes) {
138
- const term = wake.words[word]
139
- if (term) wakeWords.push({ term, source: wake.kind, wakeIndex: wake.index })
140
- }
141
- const groups = [
142
- wakeWords,
143
- residentQueryWords(state.objective).map((term) => ({ term, source: 'objective' })),
144
- residentQueryWords(state.summary ?? '').map((term) => ({
145
- term,
146
- source: 'derived_summary',
147
- })),
148
- ]
149
- const selected: { term: string; source: string; wakeIndex?: number }[] = []
150
- const seen = new Set<string>()
151
- const offsets = [0, 0, 0]
152
- for (let round = 0; round < 16; round++) {
153
- for (const [i, group] of groups.entries()) {
154
- while ((offsets[i] ?? 0) < group.length && selected.length < 16) {
155
- const entry = group[offsets[i] ?? 0]
156
- offsets[i] = (offsets[i] ?? 0) + 1
157
- if (!entry || seen.has(evidenceTokenKey(entry.term))) continue
158
- const terms = [...selected.map((item) => item.term), entry.term]
159
- if (
160
- Buffer.byteLength(
161
- JSON.stringify({
162
- terms,
163
- ...(exclusions?.length ? { excludeSuccessfulTools: exclusions } : {}),
164
- }),
165
- ) > 512
166
- )
167
- continue
168
- selected.push(entry)
169
- seen.add(evidenceTokenKey(entry.term))
170
- break
171
- }
172
- }
173
- }
174
- const query = {
175
- terms: selected.map(({ term }) => term),
176
- metadata: {
177
- kind: 'literal_resident_state',
178
- terms: selected,
179
- throughRevision: historicalScope.throughRevision,
180
- guidance:
181
- 'Words select historical tool records only. Objective/wakes are accepted inputs; derived_summary is a prior claim, not a new observation. Selection may omit relevant words. Fields over 4000 characters contribute their first/last 2000 characters; terms alternate ends. Query/ranking do not resolve ambiguous references or establish truth, freshness or completeness. Use read_resident_tool with revision/address/byteOffset for exact retained text.',
182
- },
183
- }
184
- const addresses = new WeakMap<ScopedEvidenceRecallCandidate, Readonly<Record<string, unknown>>>()
185
- const search = source.search.bind(source)
186
- const retrieve = async (request: EvidenceRecallRequest): Promise<ScopedEvidenceRecallBatch> => {
187
- if (request.turnId !== owner.turnId)
188
- throw new Error('Resident recall called from a different turn.')
189
- assertSource()
190
- const candidates: ScopedEvidenceRecallCandidate[] = []
191
- let scannedBytes = 0
192
- let incomplete = false
193
- const scans: {
194
- terms: readonly string[]
195
- started: boolean
196
- cursor?: string
197
- refineTerms?: readonly string[]
198
- }[] = [{ terms: request.terms, started: false }]
199
- let excludedToolResults = 0
200
- for (let pageNumber = 0; pageNumber < 4; pageNumber++) {
201
- const scan = [...scans].reverse().find((entry) => !entry.started || entry.cursor)
202
- if (!scan) break
203
- request.signal.throwIfAborted()
204
- const allowance = request.maxReadBytes - scannedBytes
205
- if (allowance <= 1024 * 1024 || candidates.length >= request.maxCandidates) break
206
- const page = await search(
207
- {
208
- ...(scan.cursor
209
- ? {
210
- cursor: scan.cursor,
211
- ...(scan.refineTerms ? { refineTerms: scan.refineTerms } : {}),
212
- }
213
- : {
214
- terms: [...scan.terms],
215
- ...(exclusions?.length ? { excludeSuccessfulTools: exclusions } : {}),
216
- }),
217
- maxReadBytes: allowance,
218
- },
219
- request.signal,
220
- )
221
- request.signal.throwIfAborted()
222
- assertSource()
223
- if (
224
- JSON.stringify(historicalScopeSchema.parse(page.scope)) !== snapshot ||
225
- !Number.isSafeInteger(page.chargedBytes) ||
226
- (page.chargedBytes ?? -1) < 0 ||
227
- (page.chargedBytes ?? Number.POSITIVE_INFINITY) > allowance ||
228
- typeof page.incomplete !== 'boolean' ||
229
- !Array.isArray(page.unavailableRevisions) ||
230
- page.unavailableRevisions.some(
231
- (revision) =>
232
- !Number.isSafeInteger(revision) ||
233
- revision < 1 ||
234
- revision > historicalScope.throughRevision,
235
- ) ||
236
- (page.nextCursor !== null &&
237
- (typeof page.nextCursor !== 'string' ||
238
- !page.nextCursor.length ||
239
- page.nextCursor.length > 8192))
240
- )
241
- throw new Error('Resident recall received an invalid bounded page.')
242
- scannedBytes += page.chargedBytes ?? 0
243
- // A page with a continuation is locally incomplete even when all
244
- // records visited so far are valid. Clearing traversal later is safe;
245
- // unavailable evidence stays incomplete for this entire pass.
246
- incomplete ||=
247
- (page.incomplete && !page.nextCursor) ||
248
- page.unavailableRevisions.length > 0 ||
249
- !!page.evidence?.incomplete
250
- const evidence = page.evidence
251
- if (evidence) {
252
- const original = ownerSchema.parse(evidence.scope)
253
- if (
254
- original.tenantId !== owner.tenantId ||
255
- original.projectId !== owner.projectId ||
256
- original.turnId === owner.turnId ||
257
- !Number.isSafeInteger(page.revision) ||
258
- (page.revision ?? 0) < 1 ||
259
- (page.revision ?? Number.POSITIVE_INFINITY) > historicalScope.throughRevision ||
260
- !z.string().uuid().safeParse(page.claimId).success ||
261
- page.claimId === state.claimId ||
262
- !Array.isArray(evidence.matches) ||
263
- evidence.matches.length > 24
264
- )
265
- throw new Error('Resident recall returned an unauthorized invocation.')
266
- if (
267
- evidence.excludedToolResults !== undefined &&
268
- (!Number.isSafeInteger(evidence.excludedToolResults) || evidence.excludedToolResults < 0)
269
- )
270
- throw new Error('Resident recall returned an invalid exclusion count.')
271
- excludedToolResults += evidence.excludedToolResults ?? 0
272
- for (const match of evidence.matches) {
273
- if (
274
- typeof match.address !== 'string' ||
275
- !match.address.length ||
276
- match.address.length > 8192
277
- )
278
- throw new Error('Resident recall returned an invalid archive address.')
279
- const candidate: ScopedEvidenceRecallCandidate = {
280
- scope: original,
281
- seq: match.seq,
282
- recordedAt: match.recordedAt,
283
- source: 'tool_completed',
284
- toolName: match.toolName,
285
- isError: match.isError,
286
- retained: match.retained,
287
- excerpt: match.excerpt,
288
- excerptComplete: match.excerptComplete,
289
- byteOffset: match.byteOffset,
290
- }
291
- addresses.set(candidate, {
292
- sessionId: original.sessionId,
293
- turnId: original.turnId,
294
- seq: match.seq,
295
- pursuitId: historicalScope.pursuitId,
296
- revision: page.revision,
297
- claimId: page.claimId,
298
- address: match.address,
299
- byteOffset: match.byteOffset,
300
- })
301
- candidates.push(candidate)
302
- }
303
- }
304
- scan.started = true
305
- scan.cursor = page.nextCursor ?? undefined
306
- scan.refineTerms = undefined
307
- // One strict-subset scan spends the SAME page/byte allowance. Keep
308
- // the broad cursor: finishing a subset never exhausts the full query.
309
- if (
310
- scans.length === 1 &&
311
- scan.cursor &&
312
- pageNumber < 3 &&
313
- (evidence?.matches.length ?? 0) >= 4
314
- ) {
315
- const focused = refineEvidenceRecallTerms(
316
- scan.terms,
317
- candidates.map((candidate) => candidate.excerpt),
318
- )
319
- if (focused)
320
- scans.push({
321
- terms: focused,
322
- started: false,
323
- ...(source.supportsTermRefinement === true
324
- ? { cursor: scan.cursor, refineTerms: focused }
325
- : {}),
326
- })
327
- }
328
- }
329
- const continuations = scans.flatMap((scan) =>
330
- scan.started && scan.cursor
331
- ? [{ toolName: 'search_resident_tools', input: { cursor: scan.cursor } }]
332
- : [],
333
- )
334
- return {
335
- candidates,
336
- scannedBytes,
337
- incomplete: incomplete || scans.some((scan) => !scan.started || !!scan.cursor),
338
- excludedToolResults,
339
- continuations,
340
- }
341
- }
342
- const step = createScopedEvidenceRecallStep(
343
- {
344
- retrieve,
345
- maxChars: options.maxChars,
346
- maxPassages: options.maxPassages,
347
- timeoutMs: options.timeoutMs,
348
- },
349
- {
350
- kind: 'resident',
351
- selectQuery: () => query,
352
- validate(candidate) {
353
- assertSource()
354
- if (!addresses.has(candidate)) throw new Error('Unowned resident evidence candidate.')
355
- },
356
- address(candidate) {
357
- const address = addresses.get(candidate)
358
- if (!address) throw new Error('Missing resident evidence address.')
359
- return address
360
- },
361
- },
362
- )
363
- return async (context) => {
364
- if (context.turnId !== owner.turnId)
365
- throw new Error('Resident recall called from a different turn.')
366
- assertSource()
367
- return step(context)
368
- }
369
- }
@@ -1,63 +0,0 @@
1
- import { constants } from 'node:fs'
2
- import { lstat, open } from 'node:fs/promises'
3
- import { join, relative, resolve, sep } from 'node:path'
4
-
5
- const RECORD_BYTES = 4 * 1024 * 1024
6
-
7
- export interface ResidentHistoryReadBudget {
8
- remaining: number
9
- bytesRead: number
10
- signal?: AbortSignal
11
- }
12
-
13
- export class ResidentHistoryPageLimit extends Error {}
14
-
15
- /** Bounded read of an immutable record in a private host-owned hierarchy. */
16
- export async function readResidentHistoryRecord(
17
- root: string,
18
- path: string,
19
- budget: ResidentHistoryReadBudget,
20
- ): Promise<unknown> {
21
- budget.signal?.throwIfAborted()
22
- const base = resolve(root)
23
- const suffix = relative(base, resolve(path))
24
- if (suffix === '..' || suffix.startsWith(`..${sep}`)) throw new Error('Invalid history path.')
25
- let current = base
26
- for (const part of ['', ...suffix.split(sep).filter(Boolean)]) {
27
- current = join(current, part)
28
- if ((await lstat(current)).isSymbolicLink()) throw new Error('History symlinks are refused.')
29
- }
30
- const handle = await open(path, constants.O_RDONLY | constants.O_NOFOLLOW | constants.O_NONBLOCK)
31
- try {
32
- const before = await handle.stat()
33
- if (!before.isFile() || before.size > RECORD_BYTES)
34
- throw new Error('History record is not a bounded regular file.')
35
- if (before.size > budget.remaining) throw new ResidentHistoryPageLimit()
36
- const bytes = Buffer.alloc(before.size)
37
- let offset = 0
38
- while (offset < bytes.length) {
39
- budget.signal?.throwIfAborted()
40
- const { bytesRead } = await handle.read(
41
- bytes,
42
- offset,
43
- Math.min(64 * 1024, bytes.length - offset),
44
- offset,
45
- )
46
- budget.remaining -= bytesRead
47
- budget.bytesRead += bytesRead
48
- if (!bytesRead) throw new Error('History record shortened during read.')
49
- offset += bytesRead
50
- }
51
- budget.signal?.throwIfAborted()
52
- const after = await handle.stat()
53
- if (
54
- after.size !== before.size ||
55
- after.mtimeMs !== before.mtimeMs ||
56
- after.ctimeMs !== before.ctimeMs
57
- )
58
- throw new Error('History record changed during read.')
59
- return JSON.parse(new TextDecoder('utf-8', { fatal: true }).decode(bytes))
60
- } finally {
61
- await handle.close()
62
- }
63
- }