@qjp88995/agent-runtime 0.0.0-stage → 0.1.1

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 (477) hide show
  1. package/dist/agent-extensions.d.ts +30 -0
  2. package/dist/agent-extensions.d.ts.map +1 -0
  3. package/dist/agent-extensions.js +4 -0
  4. package/dist/agent-extensions.js.map +1 -0
  5. package/dist/builtins/ask-outcome.d.ts +49 -0
  6. package/dist/builtins/ask-outcome.d.ts.map +1 -0
  7. package/dist/builtins/ask-outcome.js +128 -0
  8. package/dist/builtins/ask-outcome.js.map +1 -0
  9. package/dist/builtins/ask-schema.d.ts +110 -0
  10. package/dist/builtins/ask-schema.d.ts.map +1 -0
  11. package/dist/builtins/ask-schema.js +124 -0
  12. package/dist/builtins/ask-schema.js.map +1 -0
  13. package/dist/builtins/ask.service.d.ts +210 -0
  14. package/dist/builtins/ask.service.d.ts.map +1 -0
  15. package/dist/builtins/ask.service.js +373 -0
  16. package/dist/builtins/ask.service.js.map +1 -0
  17. package/dist/builtins/ask.tool.d.ts +49 -0
  18. package/dist/builtins/ask.tool.d.ts.map +1 -0
  19. package/dist/builtins/ask.tool.js +109 -0
  20. package/dist/builtins/ask.tool.js.map +1 -0
  21. package/dist/builtins/index.d.ts +8 -0
  22. package/dist/builtins/index.d.ts.map +1 -0
  23. package/dist/builtins/index.js +8 -0
  24. package/dist/builtins/index.js.map +1 -0
  25. package/dist/builtins/todo-schema.d.ts +90 -0
  26. package/dist/builtins/todo-schema.d.ts.map +1 -0
  27. package/dist/builtins/todo-schema.js +97 -0
  28. package/dist/builtins/todo-schema.js.map +1 -0
  29. package/dist/builtins/todo-settle.hook.d.ts +110 -0
  30. package/dist/builtins/todo-settle.hook.d.ts.map +1 -0
  31. package/dist/builtins/todo-settle.hook.js +174 -0
  32. package/dist/builtins/todo-settle.hook.js.map +1 -0
  33. package/dist/builtins/todo.tool.d.ts +59 -0
  34. package/dist/builtins/todo.tool.d.ts.map +1 -0
  35. package/dist/builtins/todo.tool.js +107 -0
  36. package/dist/builtins/todo.tool.js.map +1 -0
  37. package/dist/context/context-budget-tracker.d.ts +185 -0
  38. package/dist/context/context-budget-tracker.d.ts.map +1 -0
  39. package/dist/context/context-budget-tracker.js +400 -0
  40. package/dist/context/context-budget-tracker.js.map +1 -0
  41. package/dist/context/context-budget.d.ts +48 -0
  42. package/dist/context/context-budget.d.ts.map +1 -0
  43. package/dist/context/context-budget.js +89 -0
  44. package/dist/context/context-budget.js.map +1 -0
  45. package/dist/context/index.d.ts +3 -0
  46. package/dist/context/index.d.ts.map +1 -0
  47. package/dist/context/index.js +3 -0
  48. package/dist/context/index.js.map +1 -0
  49. package/dist/extensions/repeat-call.hook.d.ts +32 -0
  50. package/dist/extensions/repeat-call.hook.d.ts.map +1 -0
  51. package/dist/extensions/repeat-call.hook.js +54 -0
  52. package/dist/extensions/repeat-call.hook.js.map +1 -0
  53. package/dist/hooks/index.d.ts +3 -0
  54. package/dist/hooks/index.d.ts.map +1 -0
  55. package/dist/hooks/index.js +3 -0
  56. package/dist/hooks/index.js.map +1 -0
  57. package/dist/hooks/turn-hook.registry.d.ts +51 -0
  58. package/dist/hooks/turn-hook.registry.d.ts.map +1 -0
  59. package/dist/hooks/turn-hook.registry.js +233 -0
  60. package/dist/hooks/turn-hook.registry.js.map +1 -0
  61. package/dist/hooks/turn-hook.types.d.ts +179 -0
  62. package/dist/hooks/turn-hook.types.d.ts.map +1 -0
  63. package/dist/hooks/turn-hook.types.js +48 -0
  64. package/dist/hooks/turn-hook.types.js.map +1 -0
  65. package/dist/images/byte-cache.d.ts +24 -0
  66. package/dist/images/byte-cache.d.ts.map +1 -0
  67. package/dist/images/byte-cache.js +51 -0
  68. package/dist/images/byte-cache.js.map +1 -0
  69. package/dist/images/delivery.d.ts +115 -0
  70. package/dist/images/delivery.d.ts.map +1 -0
  71. package/dist/images/delivery.js +321 -0
  72. package/dist/images/delivery.js.map +1 -0
  73. package/dist/images/index.d.ts +5 -0
  74. package/dist/images/index.d.ts.map +1 -0
  75. package/dist/images/index.js +5 -0
  76. package/dist/images/index.js.map +1 -0
  77. package/dist/images/prompt.d.ts +151 -0
  78. package/dist/images/prompt.d.ts.map +1 -0
  79. package/dist/images/prompt.js +172 -0
  80. package/dist/images/prompt.js.map +1 -0
  81. package/dist/images/vendor-files.d.ts +93 -0
  82. package/dist/images/vendor-files.d.ts.map +1 -0
  83. package/dist/images/vendor-files.js +156 -0
  84. package/dist/images/vendor-files.js.map +1 -0
  85. package/dist/in-process/conversation-store.d.ts +64 -0
  86. package/dist/in-process/conversation-store.d.ts.map +1 -0
  87. package/dist/in-process/conversation-store.js +222 -0
  88. package/dist/in-process/conversation-store.js.map +1 -0
  89. package/dist/in-process/coordination.d.ts +54 -0
  90. package/dist/in-process/coordination.d.ts.map +1 -0
  91. package/dist/in-process/coordination.js +137 -0
  92. package/dist/in-process/coordination.js.map +1 -0
  93. package/dist/in-process/image-source.d.ts +15 -0
  94. package/dist/in-process/image-source.d.ts.map +1 -0
  95. package/dist/in-process/image-source.js +27 -0
  96. package/dist/in-process/image-source.js.map +1 -0
  97. package/dist/in-process/index.d.ts +36 -0
  98. package/dist/in-process/index.d.ts.map +1 -0
  99. package/dist/in-process/index.js +37 -0
  100. package/dist/in-process/index.js.map +1 -0
  101. package/dist/in-process/question-store.d.ts +28 -0
  102. package/dist/in-process/question-store.d.ts.map +1 -0
  103. package/dist/in-process/question-store.js +122 -0
  104. package/dist/in-process/question-store.js.map +1 -0
  105. package/dist/in-process/run-store.d.ts +36 -0
  106. package/dist/in-process/run-store.d.ts.map +1 -0
  107. package/dist/in-process/run-store.js +81 -0
  108. package/dist/in-process/run-store.js.map +1 -0
  109. package/dist/in-process/session-store.d.ts +33 -0
  110. package/dist/in-process/session-store.d.ts.map +1 -0
  111. package/dist/in-process/session-store.js +93 -0
  112. package/dist/in-process/session-store.js.map +1 -0
  113. package/dist/in-process/stream-bus.d.ts +52 -0
  114. package/dist/in-process/stream-bus.d.ts.map +1 -0
  115. package/dist/in-process/stream-bus.js +200 -0
  116. package/dist/in-process/stream-bus.js.map +1 -0
  117. package/dist/in-process/vendor-file-cache.d.ts +11 -0
  118. package/dist/in-process/vendor-file-cache.d.ts.map +1 -0
  119. package/dist/in-process/vendor-file-cache.js +47 -0
  120. package/dist/in-process/vendor-file-cache.js.map +1 -0
  121. package/dist/index.d.ts +21 -0
  122. package/dist/index.d.ts.map +1 -0
  123. package/dist/index.js +21 -0
  124. package/dist/index.js.map +1 -0
  125. package/dist/loop/active-tick.registry.d.ts +31 -0
  126. package/dist/loop/active-tick.registry.d.ts.map +1 -0
  127. package/dist/loop/active-tick.registry.js +45 -0
  128. package/dist/loop/active-tick.registry.js.map +1 -0
  129. package/dist/loop/index.d.ts +6 -0
  130. package/dist/loop/index.d.ts.map +1 -0
  131. package/dist/loop/index.js +6 -0
  132. package/dist/loop/index.js.map +1 -0
  133. package/dist/loop/loop-driver.d.ts +127 -0
  134. package/dist/loop/loop-driver.d.ts.map +1 -0
  135. package/dist/loop/loop-driver.js +199 -0
  136. package/dist/loop/loop-driver.js.map +1 -0
  137. package/dist/loop/message-hub.d.ts +236 -0
  138. package/dist/loop/message-hub.d.ts.map +1 -0
  139. package/dist/loop/message-hub.js +439 -0
  140. package/dist/loop/message-hub.js.map +1 -0
  141. package/dist/loop/orphan-run.sweeper.d.ts +79 -0
  142. package/dist/loop/orphan-run.sweeper.d.ts.map +1 -0
  143. package/dist/loop/orphan-run.sweeper.js +145 -0
  144. package/dist/loop/orphan-run.sweeper.js.map +1 -0
  145. package/dist/loop/root-host.d.ts +51 -0
  146. package/dist/loop/root-host.d.ts.map +1 -0
  147. package/dist/loop/root-host.js +65 -0
  148. package/dist/loop/root-host.js.map +1 -0
  149. package/dist/ports/context-store.d.ts +69 -0
  150. package/dist/ports/context-store.d.ts.map +1 -0
  151. package/dist/ports/context-store.js +2 -0
  152. package/dist/ports/context-store.js.map +1 -0
  153. package/dist/ports/conversation-store.d.ts +144 -0
  154. package/dist/ports/conversation-store.d.ts.map +1 -0
  155. package/dist/ports/conversation-store.js +2 -0
  156. package/dist/ports/conversation-store.js.map +1 -0
  157. package/dist/ports/coordination.d.ts +76 -0
  158. package/dist/ports/coordination.d.ts.map +1 -0
  159. package/dist/ports/coordination.js +12 -0
  160. package/dist/ports/coordination.js.map +1 -0
  161. package/dist/ports/image-source.d.ts +26 -0
  162. package/dist/ports/image-source.d.ts.map +1 -0
  163. package/dist/ports/image-source.js +2 -0
  164. package/dist/ports/image-source.js.map +1 -0
  165. package/dist/ports/index.d.ts +11 -0
  166. package/dist/ports/index.d.ts.map +1 -0
  167. package/dist/ports/index.js +4 -0
  168. package/dist/ports/index.js.map +1 -0
  169. package/dist/ports/logger.d.ts +14 -0
  170. package/dist/ports/logger.d.ts.map +1 -0
  171. package/dist/ports/logger.js +23 -0
  172. package/dist/ports/logger.js.map +1 -0
  173. package/dist/ports/question-store.d.ts +91 -0
  174. package/dist/ports/question-store.d.ts.map +1 -0
  175. package/dist/ports/question-store.js +8 -0
  176. package/dist/ports/question-store.js.map +1 -0
  177. package/dist/ports/run-store.d.ts +66 -0
  178. package/dist/ports/run-store.d.ts.map +1 -0
  179. package/dist/ports/run-store.js +2 -0
  180. package/dist/ports/run-store.js.map +1 -0
  181. package/dist/ports/session-store.d.ts +72 -0
  182. package/dist/ports/session-store.d.ts.map +1 -0
  183. package/dist/ports/session-store.js +9 -0
  184. package/dist/ports/session-store.js.map +1 -0
  185. package/dist/ports/stream-bus.d.ts +52 -0
  186. package/dist/ports/stream-bus.d.ts.map +1 -0
  187. package/dist/ports/stream-bus.js +2 -0
  188. package/dist/ports/stream-bus.js.map +1 -0
  189. package/dist/ports/vendor-file-cache.d.ts +46 -0
  190. package/dist/ports/vendor-file-cache.d.ts.map +1 -0
  191. package/dist/ports/vendor-file-cache.js +2 -0
  192. package/dist/ports/vendor-file-cache.js.map +1 -0
  193. package/dist/schema/agent-event.d.ts +35 -0
  194. package/dist/schema/agent-event.d.ts.map +1 -0
  195. package/dist/schema/agent-event.js +46 -0
  196. package/dist/schema/agent-event.js.map +1 -0
  197. package/dist/schema/agent-run.d.ts +23 -0
  198. package/dist/schema/agent-run.d.ts.map +1 -0
  199. package/dist/schema/agent-run.js +37 -0
  200. package/dist/schema/agent-run.js.map +1 -0
  201. package/dist/schema/index.d.ts +4 -0
  202. package/dist/schema/index.d.ts.map +1 -0
  203. package/dist/schema/index.js +4 -0
  204. package/dist/schema/index.js.map +1 -0
  205. package/dist/schema/message-part.d.ts +73 -0
  206. package/dist/schema/message-part.d.ts.map +1 -0
  207. package/dist/schema/message-part.js +90 -0
  208. package/dist/schema/message-part.js.map +1 -0
  209. package/dist/subagent/delegate.tool.d.ts +145 -0
  210. package/dist/subagent/delegate.tool.d.ts.map +1 -0
  211. package/dist/subagent/delegate.tool.js +329 -0
  212. package/dist/subagent/delegate.tool.js.map +1 -0
  213. package/dist/subagent/index.d.ts +10 -0
  214. package/dist/subagent/index.d.ts.map +1 -0
  215. package/dist/subagent/index.js +10 -0
  216. package/dist/subagent/index.js.map +1 -0
  217. package/dist/subagent/milestone-body.d.ts +82 -0
  218. package/dist/subagent/milestone-body.d.ts.map +1 -0
  219. package/dist/subagent/milestone-body.js +112 -0
  220. package/dist/subagent/milestone-body.js.map +1 -0
  221. package/dist/subagent/output-scan.d.ts +14 -0
  222. package/dist/subagent/output-scan.d.ts.map +1 -0
  223. package/dist/subagent/output-scan.js +41 -0
  224. package/dist/subagent/output-scan.js.map +1 -0
  225. package/dist/subagent/registry-spawn-policy.d.ts +32 -0
  226. package/dist/subagent/registry-spawn-policy.d.ts.map +1 -0
  227. package/dist/subagent/registry-spawn-policy.js +48 -0
  228. package/dist/subagent/registry-spawn-policy.js.map +1 -0
  229. package/dist/subagent/roster-block.d.ts +45 -0
  230. package/dist/subagent/roster-block.d.ts.map +1 -0
  231. package/dist/subagent/roster-block.js +69 -0
  232. package/dist/subagent/roster-block.js.map +1 -0
  233. package/dist/subagent/situation-block.d.ts +16 -0
  234. package/dist/subagent/situation-block.d.ts.map +1 -0
  235. package/dist/subagent/situation-block.js +71 -0
  236. package/dist/subagent/situation-block.js.map +1 -0
  237. package/dist/subagent/spawn-guards.d.ts +32 -0
  238. package/dist/subagent/spawn-guards.d.ts.map +1 -0
  239. package/dist/subagent/spawn-guards.js +39 -0
  240. package/dist/subagent/spawn-guards.js.map +1 -0
  241. package/dist/subagent/subagent-registry.d.ts +150 -0
  242. package/dist/subagent/subagent-registry.d.ts.map +1 -0
  243. package/dist/subagent/subagent-registry.js +167 -0
  244. package/dist/subagent/subagent-registry.js.map +1 -0
  245. package/dist/subagent/subagent-sessions.d.ts +213 -0
  246. package/dist/subagent/subagent-sessions.d.ts.map +1 -0
  247. package/dist/subagent/subagent-sessions.js +295 -0
  248. package/dist/subagent/subagent-sessions.js.map +1 -0
  249. package/dist/testing/contracts.d.ts +37 -0
  250. package/dist/testing/contracts.d.ts.map +1 -0
  251. package/dist/testing/contracts.js +607 -0
  252. package/dist/testing/contracts.js.map +1 -0
  253. package/dist/testing/index.d.ts +5 -0
  254. package/dist/testing/index.d.ts.map +1 -0
  255. package/dist/testing/index.js +5 -0
  256. package/dist/testing/index.js.map +1 -0
  257. package/dist/testing/stub.d.ts +28 -0
  258. package/dist/testing/stub.d.ts.map +1 -0
  259. package/dist/testing/stub.js +3 -0
  260. package/dist/testing/stub.js.map +1 -0
  261. package/dist/tools/agent-tool.base.d.ts +186 -0
  262. package/dist/tools/agent-tool.base.d.ts.map +1 -0
  263. package/dist/tools/agent-tool.base.js +243 -0
  264. package/dist/tools/agent-tool.base.js.map +1 -0
  265. package/dist/tools/agent-tool.interface.d.ts +95 -0
  266. package/dist/tools/agent-tool.interface.d.ts.map +1 -0
  267. package/dist/tools/agent-tool.interface.js +2 -0
  268. package/dist/tools/agent-tool.interface.js.map +1 -0
  269. package/dist/tools/builtin-names.d.ts +18 -0
  270. package/dist/tools/builtin-names.d.ts.map +1 -0
  271. package/dist/tools/builtin-names.js +20 -0
  272. package/dist/tools/builtin-names.js.map +1 -0
  273. package/dist/tools/index.d.ts +9 -0
  274. package/dist/tools/index.d.ts.map +1 -0
  275. package/dist/tools/index.js +6 -0
  276. package/dist/tools/index.js.map +1 -0
  277. package/dist/tools/tool-definition.d.ts +18 -0
  278. package/dist/tools/tool-definition.d.ts.map +1 -0
  279. package/dist/tools/tool-definition.js +77 -0
  280. package/dist/tools/tool-definition.js.map +1 -0
  281. package/dist/tools/tool-meta.d.ts +55 -0
  282. package/dist/tools/tool-meta.d.ts.map +1 -0
  283. package/dist/tools/tool-meta.js +2 -0
  284. package/dist/tools/tool-meta.js.map +1 -0
  285. package/dist/tools/tool-registry.d.ts +190 -0
  286. package/dist/tools/tool-registry.d.ts.map +1 -0
  287. package/dist/tools/tool-registry.js +379 -0
  288. package/dist/tools/tool-registry.js.map +1 -0
  289. package/dist/tools/tool-result.d.ts +41 -0
  290. package/dist/tools/tool-result.d.ts.map +1 -0
  291. package/dist/tools/tool-result.js +19 -0
  292. package/dist/tools/tool-result.js.map +1 -0
  293. package/dist/tools/tool-wire.d.ts +24 -0
  294. package/dist/tools/tool-wire.d.ts.map +1 -0
  295. package/dist/tools/tool-wire.js +2 -0
  296. package/dist/tools/tool-wire.js.map +1 -0
  297. package/dist/turn/agent-runtime.d.ts +31 -0
  298. package/dist/turn/agent-runtime.d.ts.map +1 -0
  299. package/dist/turn/agent-runtime.js +30 -0
  300. package/dist/turn/agent-runtime.js.map +1 -0
  301. package/dist/turn/chunk-projection.d.ts +32 -0
  302. package/dist/turn/chunk-projection.d.ts.map +1 -0
  303. package/dist/turn/chunk-projection.js +62 -0
  304. package/dist/turn/chunk-projection.js.map +1 -0
  305. package/dist/turn/compaction.d.ts +48 -0
  306. package/dist/turn/compaction.d.ts.map +1 -0
  307. package/dist/turn/compaction.js +89 -0
  308. package/dist/turn/compaction.js.map +1 -0
  309. package/dist/turn/context-overflow.d.ts +11 -0
  310. package/dist/turn/context-overflow.d.ts.map +1 -0
  311. package/dist/turn/context-overflow.js +53 -0
  312. package/dist/turn/context-overflow.js.map +1 -0
  313. package/dist/turn/context-pressure.d.ts +100 -0
  314. package/dist/turn/context-pressure.d.ts.map +1 -0
  315. package/dist/turn/context-pressure.js +21 -0
  316. package/dist/turn/context-pressure.js.map +1 -0
  317. package/dist/turn/events-to-steps.d.ts +8 -0
  318. package/dist/turn/events-to-steps.d.ts.map +1 -0
  319. package/dist/turn/events-to-steps.js +64 -0
  320. package/dist/turn/events-to-steps.js.map +1 -0
  321. package/dist/turn/index.d.ts +17 -0
  322. package/dist/turn/index.d.ts.map +1 -0
  323. package/dist/turn/index.js +16 -0
  324. package/dist/turn/index.js.map +1 -0
  325. package/dist/turn/json-preview.d.ts +22 -0
  326. package/dist/turn/json-preview.d.ts.map +1 -0
  327. package/dist/turn/json-preview.js +34 -0
  328. package/dist/turn/json-preview.js.map +1 -0
  329. package/dist/turn/json-string-field.d.ts +30 -0
  330. package/dist/turn/json-string-field.d.ts.map +1 -0
  331. package/dist/turn/json-string-field.js +125 -0
  332. package/dist/turn/json-string-field.js.map +1 -0
  333. package/dist/turn/loop-reminder.d.ts +79 -0
  334. package/dist/turn/loop-reminder.d.ts.map +1 -0
  335. package/dist/turn/loop-reminder.js +0 -0
  336. package/dist/turn/loop-reminder.js.map +1 -0
  337. package/dist/turn/nul-safe.d.ts +21 -0
  338. package/dist/turn/nul-safe.d.ts.map +1 -0
  339. package/dist/turn/nul-safe.js +23 -0
  340. package/dist/turn/nul-safe.js.map +1 -0
  341. package/dist/turn/parts-from-events.d.ts +71 -0
  342. package/dist/turn/parts-from-events.d.ts.map +1 -0
  343. package/dist/turn/parts-from-events.js +217 -0
  344. package/dist/turn/parts-from-events.js.map +1 -0
  345. package/dist/turn/parts-to-model-messages.d.ts +158 -0
  346. package/dist/turn/parts-to-model-messages.d.ts.map +1 -0
  347. package/dist/turn/parts-to-model-messages.js +334 -0
  348. package/dist/turn/parts-to-model-messages.js.map +1 -0
  349. package/dist/turn/pending-work.d.ts +10 -0
  350. package/dist/turn/pending-work.d.ts.map +1 -0
  351. package/dist/turn/pending-work.js +14 -0
  352. package/dist/turn/pending-work.js.map +1 -0
  353. package/dist/turn/provider-error.d.ts +45 -0
  354. package/dist/turn/provider-error.d.ts.map +1 -0
  355. package/dist/turn/provider-error.js +154 -0
  356. package/dist/turn/provider-error.js.map +1 -0
  357. package/dist/turn/tool-input-preview.d.ts +94 -0
  358. package/dist/turn/tool-input-preview.d.ts.map +1 -0
  359. package/dist/turn/tool-input-preview.js +143 -0
  360. package/dist/turn/tool-input-preview.js.map +1 -0
  361. package/dist/turn/tool-input-progress.d.ts +47 -0
  362. package/dist/turn/tool-input-progress.d.ts.map +1 -0
  363. package/dist/turn/tool-input-progress.js +50 -0
  364. package/dist/turn/tool-input-progress.js.map +1 -0
  365. package/dist/turn/turn-envelope.d.ts +184 -0
  366. package/dist/turn/turn-envelope.d.ts.map +1 -0
  367. package/dist/turn/turn-envelope.js +2 -0
  368. package/dist/turn/turn-envelope.js.map +1 -0
  369. package/dist/turn/turn-journal.d.ts +49 -0
  370. package/dist/turn/turn-journal.d.ts.map +1 -0
  371. package/dist/turn/turn-journal.js +51 -0
  372. package/dist/turn/turn-journal.js.map +1 -0
  373. package/dist/turn/turn-run.d.ts +487 -0
  374. package/dist/turn/turn-run.d.ts.map +1 -0
  375. package/dist/turn/turn-run.js +1167 -0
  376. package/dist/turn/turn-run.js.map +1 -0
  377. package/dist/turn/usage.d.ts +27 -0
  378. package/dist/turn/usage.d.ts.map +1 -0
  379. package/dist/turn/usage.js +51 -0
  380. package/dist/turn/usage.js.map +1 -0
  381. package/package.json +59 -3
  382. package/src/agent-extensions.ts +33 -0
  383. package/src/builtins/ask-outcome.ts +168 -0
  384. package/src/builtins/ask-schema.ts +186 -0
  385. package/src/builtins/ask.service.ts +482 -0
  386. package/src/builtins/ask.tool.ts +138 -0
  387. package/src/builtins/index.ts +25 -0
  388. package/src/builtins/todo-schema.ts +108 -0
  389. package/src/builtins/todo-settle.hook.ts +221 -0
  390. package/src/builtins/todo.tool.ts +134 -0
  391. package/src/context/context-budget-tracker.ts +519 -0
  392. package/src/context/context-budget.ts +124 -0
  393. package/src/context/index.ts +17 -0
  394. package/src/extensions/repeat-call.hook.ts +77 -0
  395. package/src/hooks/index.ts +19 -0
  396. package/src/hooks/turn-hook.registry.ts +307 -0
  397. package/src/hooks/turn-hook.types.ts +210 -0
  398. package/src/images/byte-cache.ts +61 -0
  399. package/src/images/delivery.ts +508 -0
  400. package/src/images/index.ts +35 -0
  401. package/src/images/prompt.ts +289 -0
  402. package/src/images/vendor-files.ts +235 -0
  403. package/src/in-process/conversation-store.ts +304 -0
  404. package/src/in-process/coordination.ts +177 -0
  405. package/src/in-process/image-source.ts +29 -0
  406. package/src/in-process/index.ts +52 -0
  407. package/src/in-process/question-store.ts +155 -0
  408. package/src/in-process/run-store.ts +115 -0
  409. package/src/in-process/session-store.ts +118 -0
  410. package/src/in-process/stream-bus.ts +244 -0
  411. package/src/in-process/vendor-file-cache.ts +67 -0
  412. package/src/index.ts +28 -0
  413. package/src/loop/active-tick.registry.ts +49 -0
  414. package/src/loop/index.ts +25 -0
  415. package/src/loop/loop-driver.ts +275 -0
  416. package/src/loop/message-hub.ts +532 -0
  417. package/src/loop/orphan-run.sweeper.ts +204 -0
  418. package/src/loop/root-host.ts +119 -0
  419. package/src/ports/context-store.ts +71 -0
  420. package/src/ports/conversation-store.ts +165 -0
  421. package/src/ports/coordination.ts +81 -0
  422. package/src/ports/image-source.ts +26 -0
  423. package/src/ports/index.ts +56 -0
  424. package/src/ports/logger.ts +34 -0
  425. package/src/ports/question-store.ts +117 -0
  426. package/src/ports/run-store.ts +69 -0
  427. package/src/ports/session-store.ts +80 -0
  428. package/src/ports/stream-bus.ts +59 -0
  429. package/src/ports/vendor-file-cache.ts +54 -0
  430. package/src/schema/agent-event.ts +69 -0
  431. package/src/schema/agent-run.ts +44 -0
  432. package/src/schema/index.ts +25 -0
  433. package/src/schema/message-part.ts +100 -0
  434. package/src/subagent/delegate.tool.ts +476 -0
  435. package/src/subagent/index.ts +63 -0
  436. package/src/subagent/milestone-body.ts +144 -0
  437. package/src/subagent/output-scan.ts +56 -0
  438. package/src/subagent/registry-spawn-policy.ts +85 -0
  439. package/src/subagent/roster-block.ts +103 -0
  440. package/src/subagent/situation-block.ts +83 -0
  441. package/src/subagent/spawn-guards.ts +54 -0
  442. package/src/subagent/subagent-registry.ts +283 -0
  443. package/src/subagent/subagent-sessions.ts +496 -0
  444. package/src/testing/contracts.ts +882 -0
  445. package/src/testing/index.ts +14 -0
  446. package/src/testing/stub.ts +28 -0
  447. package/src/tools/agent-tool.base.ts +361 -0
  448. package/src/tools/agent-tool.interface.ts +101 -0
  449. package/src/tools/builtin-names.ts +26 -0
  450. package/src/tools/index.ts +39 -0
  451. package/src/tools/tool-definition.ts +93 -0
  452. package/src/tools/tool-meta.ts +60 -0
  453. package/src/tools/tool-registry.ts +513 -0
  454. package/src/tools/tool-result.ts +45 -0
  455. package/src/tools/tool-wire.ts +24 -0
  456. package/src/turn/agent-runtime.ts +43 -0
  457. package/src/turn/chunk-projection.ts +81 -0
  458. package/src/turn/compaction.ts +103 -0
  459. package/src/turn/context-overflow.ts +54 -0
  460. package/src/turn/context-pressure.ts +114 -0
  461. package/src/turn/events-to-steps.ts +73 -0
  462. package/src/turn/index.ts +71 -0
  463. package/src/turn/json-preview.ts +36 -0
  464. package/src/turn/json-string-field.ts +134 -0
  465. package/src/turn/loop-reminder.ts +0 -0
  466. package/src/turn/nul-safe.ts +22 -0
  467. package/src/turn/parts-from-events.ts +248 -0
  468. package/src/turn/parts-to-model-messages.ts +428 -0
  469. package/src/turn/pending-work.ts +14 -0
  470. package/src/turn/provider-error.ts +160 -0
  471. package/src/turn/tool-input-preview.ts +223 -0
  472. package/src/turn/tool-input-progress.ts +76 -0
  473. package/src/turn/turn-envelope.ts +185 -0
  474. package/src/turn/turn-journal.ts +102 -0
  475. package/src/turn/turn-run.ts +1479 -0
  476. package/src/turn/usage.ts +56 -0
  477. package/README.md +0 -3
@@ -0,0 +1,154 @@
1
+ import { APICallError, NoOutputGeneratedError } from 'ai';
2
+ /**
3
+ * provider 请求级错误的「取真」与「说人话」。
4
+ *
5
+ * **为什么需要取真**:`streamText` 里,provider 在 `doStream` 阶段抛出的
6
+ * `APICallError`(余额不足、鉴权失败、限流、上下文超限……)**不会**成为
7
+ * `result.steps` 的 rejection。SDK 把它转成流内的 `error` part 交给
8
+ * `onError` 回调,而 flush 时另造一个**全新的、`cause` 为 undefined 的**
9
+ * `NoOutputGeneratedError({ message: 'No output generated. Check the stream
10
+ * for errors.' })` 去 reject 那些 promise(`sdk-contract.spec.ts` 的
11
+ * 「provider 请求级错误」一节钉住)。也就是说:**不接 `onError` 就永久拿不到
12
+ * 真实错误**,catch 到的那个对象里没有状态码、没有 responseBody、没有 cause。
13
+ *
14
+ * 后果不止是「日志难看」:`isContextOverflowError` 的输入是 `APICallError`,
15
+ * 拿这个包装壳去判恒为 false —— 上下文超限的就地补救因此整条形同虚设,而它的
16
+ * 单测用裸 `APICallError` 构造夹具,永远绿。线上的症状是那个会话每一次发言都
17
+ * 以同一条错误结束(见 `context-overflow.ts` 的大注释)。
18
+ */
19
+ /** 单条错误文案进对话气泡时的长度上限——够定位,又不至于刷屏。 */
20
+ const MAX_DETAIL_CHARS = 300;
21
+ /**
22
+ * HTTP 状态码 → 「运维/成员拿了能干什么」。
23
+ *
24
+ * 只列**判据明确**的几档:这几个码在各家 provider 之间语义一致,且各自指向
25
+ * 一个具体的动作(充值 / 换 key / 等一会儿 / 改配置)。其余一律走兜底文案带上
26
+ * 原始状态码,不猜。
27
+ */
28
+ const STATUS_HINTS = {
29
+ 401: '模型服务商拒绝了鉴权,API Key 可能无效或已失效',
30
+ 403: '模型服务商拒绝访问,当前 API Key 没有调用该模型的权限',
31
+ 402: '模型服务商账户余额不足,请先充值',
32
+ 404: '模型服务商没有这个模型,请检查模型配置里的模型名',
33
+ 429: '模型服务商限流,请稍后重试',
34
+ };
35
+ /**
36
+ * 拿到这一步**真正**的失败原因。
37
+ *
38
+ * `streamError` 是调用方从 `streamText` 的 `onError` 里接住的那个错误。判据
39
+ * 刻意窄——**只有** `err` 是那个无信息的 `NoOutputGeneratedError` 壳、且这一步
40
+ * 确实记到过流内错误时才替换。abort 走的是另一条(SDK 用 `abortSignal.reason`
41
+ * reject),不会被这里误伤。
42
+ */
43
+ export function unwrapInferenceError(err, streamError) {
44
+ if (streamError === undefined)
45
+ return err;
46
+ if (!NoOutputGeneratedError.isInstance(err))
47
+ return err;
48
+ return streamError;
49
+ }
50
+ /**
51
+ * 把错误说成一句用户能看懂、运维能定位的中文。
52
+ *
53
+ * 落进 `TurnResult.error`(→ `chat_message.metadata.error` 与零产出时的占位
54
+ * 气泡)。**始终带上服务商原话**:归一化只是给前面加一句「该干什么」,把原文
55
+ * 抹掉就等于让运维去猜。
56
+ */
57
+ export function describeProviderError(err) {
58
+ const raw = err instanceof Error ? err.message : String(err);
59
+ const detail = truncate(raw);
60
+ // 传输层断连:没有状态码、原话是 undici 的一个英文单词(`terminated`)。
61
+ // 单独说清楚——它不是服务商「拒绝」了什么,是连接半路没了,重试就是答案。
62
+ if (isTransportError(err)) {
63
+ return `与模型服务商的连接在响应中途断开(${truncate(describeErrorChain(err))})`;
64
+ }
65
+ if (!APICallError.isInstance(err))
66
+ return detail;
67
+ const hint = err.statusCode ? STATUS_HINTS[err.statusCode] : undefined;
68
+ if (hint)
69
+ return `${hint}(服务商返回:${detail})`;
70
+ return err.statusCode
71
+ ? `调用模型服务失败(HTTP ${err.statusCode}):${detail}`
72
+ : `调用模型服务失败:${detail}`;
73
+ }
74
+ function truncate(text) {
75
+ const trimmed = text.trim();
76
+ return trimmed.length > MAX_DETAIL_CHARS
77
+ ? `${trimmed.slice(0, MAX_DETAIL_CHARS)}…`
78
+ : trimmed;
79
+ }
80
+ /**
81
+ * 传输层断连的判据:**响应流读到一半,连接没了**。
82
+ *
83
+ * 这一类错误不是 HTTP 错误——没有状态码,AI SDK 的请求级重试(只认
84
+ * `APICallError.isRetryable`,且只包着「发起请求」那一步)罩不到它;流式响应
85
+ * 里它经 `onError` 冒出来,原始形状是 Node 内置 HTTP 客户端 undici 的
86
+ * `TypeError: terminated`(对端关闭)或 `ECONNRESET`(连接被重置),真正的
87
+ * 原因挂在 `cause` 链上。2026-09-09 线上 deepseek 一次 555 秒的轮次就是这么
88
+ * 死的:前 5 步正常,第 6 次调模型读流中途 `terminated`,整轮 failed。
89
+ *
90
+ * **判据刻意窄**:只认「已经建立的连接中途断开」这一族(code 表 + undici 的几句
91
+ * 原话),不认连接建立阶段的失败(`fetch failed` / `ECONNREFUSED` / DNS)——
92
+ * 那些发生在请求阶段,SDK 自己已经退避重试过了,到这里的是它放弃之后的
93
+ * `RetryError`,再重试一轮只是把同一个死结多绕三圈。也**不认 abort**:用户按
94
+ * 停止走的是 `AbortError`,那是有人要它停,不是链路坏了。
95
+ *
96
+ * 顺着 `cause` 链看(最多 8 层):undici 把 `SocketError` 包在 `TypeError`
97
+ * 里,只看最外层的 message 会漏掉 `ECONNRESET` 这种只在里层出现的 code。
98
+ */
99
+ export function isTransportError(err) {
100
+ let cur = err;
101
+ for (let depth = 0; depth < 8 && cur instanceof Error; depth++) {
102
+ if (cur.name === 'AbortError')
103
+ return false;
104
+ const code = cur.code;
105
+ if (typeof code === 'string' && TRANSPORT_ERROR_CODES.has(code))
106
+ return true;
107
+ const message = cur.message;
108
+ if (TRANSPORT_ERROR_MESSAGES.some(re => re.test(message)))
109
+ return true;
110
+ cur = cur.cause;
111
+ }
112
+ return false;
113
+ }
114
+ const TRANSPORT_ERROR_CODES = new Set([
115
+ 'ECONNRESET',
116
+ 'ECONNABORTED',
117
+ 'EPIPE',
118
+ 'ETIMEDOUT',
119
+ 'UND_ERR_SOCKET',
120
+ 'UND_ERR_ABORTED',
121
+ 'UND_ERR_BODY_TIMEOUT',
122
+ ]);
123
+ const TRANSPORT_ERROR_MESSAGES = [
124
+ /^terminated$/i,
125
+ /socket hang up/i,
126
+ /other side closed/i,
127
+ ];
128
+ /**
129
+ * 把 `cause` 链摊平成一行给日志:`TypeError: terminated ← SocketError: other
130
+ * side closed [UND_ERR_SOCKET]`。`String(err)` 只有最外层那句,而对传输层错误
131
+ * 来说最外层恰恰是信息量最低的一层——线上那次日志里只剩一个 `terminated`,
132
+ * 连是对端正常关闭还是被重置都分不出来。
133
+ */
134
+ export function describeErrorChain(err) {
135
+ const parts = [];
136
+ let cur = err;
137
+ for (let depth = 0; depth < 8; depth++) {
138
+ if (!(cur instanceof Error)) {
139
+ // 链尾不是 Error(有人 `throw 'x'` 或 `cause: {code}`):原样带上,别让
140
+ // 它变成 '[object Object]'。
141
+ if (typeof cur === 'string')
142
+ parts.push(cur);
143
+ else if (cur !== undefined && cur !== null)
144
+ parts.push(JSON.stringify(cur));
145
+ break;
146
+ }
147
+ const code = cur.code;
148
+ const tag = typeof code === 'string' ? ` [${code}]` : '';
149
+ parts.push(`${cur.name}: ${cur.message}${tag}`);
150
+ cur = cur.cause;
151
+ }
152
+ return parts.join(' ← ');
153
+ }
154
+ //# sourceMappingURL=provider-error.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider-error.js","sourceRoot":"","sources":["../../src/turn/provider-error.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,94 @@
1
+ /**
2
+ * 工具入参流式构建的**内容预览器**。
3
+ *
4
+ * 与 `tool-input-progress.ts` 分工:那条 tracker 答「写了多少」(字数,
5
+ * 不看内容),这条答「写了什么」——只对白名单工具实时抽出它入参里那个正文
6
+ * 字段(`Write.content`)的累计前缀,外加解析完整了的 `path`,供对话页的稿栏
7
+ * 边写边显示文件名与正文。
8
+ *
9
+ * 两个 tracker 各管一条事件(`tool-input-progress` / `tool-input-preview`),
10
+ * 互不知道对方;`chunk-projection.ts` 在同一处 `tool-input-delta` 分支里
11
+ * 各喂一遍。
12
+ *
13
+ * ## 成本(这一条决定了下面两道闸的形状)
14
+ *
15
+ * 每次 `delta` 都得**从头**重扫一遍累计的 `raw` 才能抽出字段值
16
+ * (`extractJsonStringField` 是线性扫描,没有可续跑的状态:转义与代理对的
17
+ * 收尾判定依赖上下文)。模型吐一篇长文约 120 块入参增量,若每块都扫一遍
18
+ * 就是 O(n²) 的字符比对,且每帧还要把整段前缀再发一次。
19
+ *
20
+ * 两道闸把它压回可接受:
21
+ * 1. **扫描前先看 `raw` 涨了多少**——解码后的字符数**恒不大于**原始 JSON 的
22
+ * 字符数(转义只会更长、代理对只会更多),所以「raw 涨的还不够一个阈值」
23
+ * 是「正文涨的也不够」的**必要条件**,此时连扫都不必扫。唯一例外是 `path`
24
+ * 还没解析完整那一段:第一帧必须尽早带上路径(稿栏靠它先开栏显示文件名),
25
+ * 那几块一律照扫。
26
+ * 2. **阈值随正文长度自适应**(`previewThreshold`):短文里每 80 码点发一条
27
+ * 才看得出「在写」;长文里正文本身已经几千字,再按 80 发就是每帧重发一份
28
+ * 越来越大的全量前缀。载荷语义仍是**累计前缀**(幂等,断线重放/去重下不会
29
+ * 拼错),只是发得更疏。
30
+ *
31
+ * 零依赖纯函数式实现,同一套单测风格(本仓既有做法:`tool-input-progress.ts`)。
32
+ */
33
+ /**
34
+ * 阈值下限,也是短正文期间的实际阈值:每积累这么多字符发一条预览。
35
+ *
36
+ * 按「界面上正文多久长一截」定:模型出中文大约 100+ 字符/秒,80 约等于每秒
37
+ * 一次。再密只是徒增事件(每条都带全量前缀),再疏就开始像卡住了。
38
+ */
39
+ export declare const TOOL_INPUT_PREVIEW_CHARS = 80;
40
+ /**
41
+ * 阈值上限。一篇 8000 字的稿子按 400 发也有 20 帧,够看出它在长;再放宽就
42
+ * 变成「写了半天才蹦一大段」。
43
+ */
44
+ export declare const TOOL_INPUT_PREVIEW_CHARS_MAX = 400;
45
+ /**
46
+ * 已经发出 `chars` 个字符之后,下一条预览要等正文再涨多少。
47
+ *
48
+ * `chars / 8` 意味着「每帧最多把正文推进八分之一」——发出的总字节量随正文
49
+ * 长度线性(而不是平方)增长,界面上的推进感又与正文长度无关(短文每秒一
50
+ * 帧、长文每几秒一大段,都是「一直在长」)。
51
+ *
52
+ * @param floor 阈值下限,默认 `TOOL_INPUT_PREVIEW_CHARS`;测试用它把节流拨快。
53
+ */
54
+ export declare function previewThreshold(chars: number, floor?: number): number;
55
+ /**
56
+ * 白名单:只有登记在这里的工具才会被追踪,且只认这两个字段名。
57
+ *
58
+ * `path` 用来给稿栏定位文件;`text` 是要显示的正文字段,**为 `null` 表示这个
59
+ * 工具没有可预览的正文**——`Edit` 的入参是替换对(`old_string`/`new_string`)
60
+ * 而不是整篇,半截的替换对画不出任何东西。它仍然登记在这里,是因为稿栏需要
61
+ * 在 `Edit` 落盘之前就知道「agent 正在改哪份文件」(栏头显示「生成改动中」,
62
+ * 而不是等几十秒后才跳出一份改好的稿)。
63
+ */
64
+ export declare const TOOL_INPUT_PREVIEW_FIELDS: Record<string, {
65
+ path: string;
66
+ text: string | null;
67
+ }>;
68
+ export interface ToolInputPreviewEvent {
69
+ toolCallId: string;
70
+ toolName: string;
71
+ /** 只有 `path` 字段解析**完整**了才不是 null(首次完整立刻发一条)。 */
72
+ path: string | null;
73
+ /** 正文字段的累计前缀(可能是 `''`;无正文字段的工具恒 `''`)。 */
74
+ text: string;
75
+ /** 至此 `text` 的码点数(与 `tool-input-progress` 同一判据)。 */
76
+ chars: number;
77
+ }
78
+ export interface ToolInputPreviewTracker {
79
+ /** 模型开始吐某次调用的参数。不在白名单的工具直接忽略,不建账。 */
80
+ start(toolCallId: string, toolName: string): void;
81
+ /**
82
+ * 收到一块入参增量。返回非 null 表示「该发一条预览了」。
83
+ *
84
+ * **未 `start` 过(或起手时就不在白名单)的 toolCallId 一律返回 null**。
85
+ */
86
+ delta(toolCallId: string, text: string): ToolInputPreviewEvent | null;
87
+ /** 这次调用的参数收齐了,丢掉它的累计。 */
88
+ done(toolCallId: string): void;
89
+ }
90
+ export declare function createToolInputPreviewTracker(fields?: Record<string, {
91
+ path: string;
92
+ text: string | null;
93
+ }>, thresholdChars?: number): ToolInputPreviewTracker;
94
+ //# sourceMappingURL=tool-input-preview.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-input-preview.d.ts","sourceRoot":"","sources":["../../src/turn/tool-input-preview.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH;;;;;GAKG;AACH,eAAO,MAAM,wBAAwB,KAAK,CAAC;AAE3C;;;GAGG;AACH,eAAO,MAAM,4BAA4B,MAAM,CAAC;AAEhD;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,MAAM,EACb,KAAK,GAAE,MAAiC,GACvC,MAAM,CAKR;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,yBAAyB,EAAE,MAAM,CAC5C,MAAM,EACN;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAItC,CAAC;AAEF,MAAM,WAAW,qBAAqB;IACpC,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,gDAAgD;IAChD,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,0CAA0C;IAC1C,IAAI,EAAE,MAAM,CAAC;IACb,oDAAoD;IACpD,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,uBAAuB;IACtC,qCAAqC;IACrC,KAAK,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IAClD;;;;OAIG;IACH,KAAK,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,qBAAqB,GAAG,IAAI,CAAC;IACtE,yBAAyB;IACzB,IAAI,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAChC;AAOD,wBAAgB,6BAA6B,CAC3C,MAAM,GAAE,MAAM,CACZ,MAAM,EACN;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CACV,EAC7B,cAAc,GAAE,MAAiC,GAChD,uBAAuB,CAsGzB"}
@@ -0,0 +1,143 @@
1
+ import { extractJsonStringField } from './json-string-field.js';
2
+ /**
3
+ * 工具入参流式构建的**内容预览器**。
4
+ *
5
+ * 与 `tool-input-progress.ts` 分工:那条 tracker 答「写了多少」(字数,
6
+ * 不看内容),这条答「写了什么」——只对白名单工具实时抽出它入参里那个正文
7
+ * 字段(`Write.content`)的累计前缀,外加解析完整了的 `path`,供对话页的稿栏
8
+ * 边写边显示文件名与正文。
9
+ *
10
+ * 两个 tracker 各管一条事件(`tool-input-progress` / `tool-input-preview`),
11
+ * 互不知道对方;`chunk-projection.ts` 在同一处 `tool-input-delta` 分支里
12
+ * 各喂一遍。
13
+ *
14
+ * ## 成本(这一条决定了下面两道闸的形状)
15
+ *
16
+ * 每次 `delta` 都得**从头**重扫一遍累计的 `raw` 才能抽出字段值
17
+ * (`extractJsonStringField` 是线性扫描,没有可续跑的状态:转义与代理对的
18
+ * 收尾判定依赖上下文)。模型吐一篇长文约 120 块入参增量,若每块都扫一遍
19
+ * 就是 O(n²) 的字符比对,且每帧还要把整段前缀再发一次。
20
+ *
21
+ * 两道闸把它压回可接受:
22
+ * 1. **扫描前先看 `raw` 涨了多少**——解码后的字符数**恒不大于**原始 JSON 的
23
+ * 字符数(转义只会更长、代理对只会更多),所以「raw 涨的还不够一个阈值」
24
+ * 是「正文涨的也不够」的**必要条件**,此时连扫都不必扫。唯一例外是 `path`
25
+ * 还没解析完整那一段:第一帧必须尽早带上路径(稿栏靠它先开栏显示文件名),
26
+ * 那几块一律照扫。
27
+ * 2. **阈值随正文长度自适应**(`previewThreshold`):短文里每 80 码点发一条
28
+ * 才看得出「在写」;长文里正文本身已经几千字,再按 80 发就是每帧重发一份
29
+ * 越来越大的全量前缀。载荷语义仍是**累计前缀**(幂等,断线重放/去重下不会
30
+ * 拼错),只是发得更疏。
31
+ *
32
+ * 零依赖纯函数式实现,同一套单测风格(本仓既有做法:`tool-input-progress.ts`)。
33
+ */
34
+ /**
35
+ * 阈值下限,也是短正文期间的实际阈值:每积累这么多字符发一条预览。
36
+ *
37
+ * 按「界面上正文多久长一截」定:模型出中文大约 100+ 字符/秒,80 约等于每秒
38
+ * 一次。再密只是徒增事件(每条都带全量前缀),再疏就开始像卡住了。
39
+ */
40
+ export const TOOL_INPUT_PREVIEW_CHARS = 80;
41
+ /**
42
+ * 阈值上限。一篇 8000 字的稿子按 400 发也有 20 帧,够看出它在长;再放宽就
43
+ * 变成「写了半天才蹦一大段」。
44
+ */
45
+ export const TOOL_INPUT_PREVIEW_CHARS_MAX = 400;
46
+ /**
47
+ * 已经发出 `chars` 个字符之后,下一条预览要等正文再涨多少。
48
+ *
49
+ * `chars / 8` 意味着「每帧最多把正文推进八分之一」——发出的总字节量随正文
50
+ * 长度线性(而不是平方)增长,界面上的推进感又与正文长度无关(短文每秒一
51
+ * 帧、长文每几秒一大段,都是「一直在长」)。
52
+ *
53
+ * @param floor 阈值下限,默认 `TOOL_INPUT_PREVIEW_CHARS`;测试用它把节流拨快。
54
+ */
55
+ export function previewThreshold(chars, floor = TOOL_INPUT_PREVIEW_CHARS) {
56
+ return Math.max(floor, Math.min(Math.floor(chars / 8), TOOL_INPUT_PREVIEW_CHARS_MAX));
57
+ }
58
+ /**
59
+ * 白名单:只有登记在这里的工具才会被追踪,且只认这两个字段名。
60
+ *
61
+ * `path` 用来给稿栏定位文件;`text` 是要显示的正文字段,**为 `null` 表示这个
62
+ * 工具没有可预览的正文**——`Edit` 的入参是替换对(`old_string`/`new_string`)
63
+ * 而不是整篇,半截的替换对画不出任何东西。它仍然登记在这里,是因为稿栏需要
64
+ * 在 `Edit` 落盘之前就知道「agent 正在改哪份文件」(栏头显示「生成改动中」,
65
+ * 而不是等几十秒后才跳出一份改好的稿)。
66
+ */
67
+ export const TOOL_INPUT_PREVIEW_FIELDS = {
68
+ Write: { path: 'path', text: 'content' },
69
+ Edit: { path: 'path', text: null },
70
+ };
71
+ /** 按码点数,不是 UTF-16 code unit —— 与 tool-input-progress 同一判据。 */
72
+ function countCodePoints(text) {
73
+ return Array.from(text).length;
74
+ }
75
+ export function createToolInputPreviewTracker(fields = TOOL_INPUT_PREVIEW_FIELDS, thresholdChars = TOOL_INPUT_PREVIEW_CHARS) {
76
+ const entries = new Map();
77
+ return {
78
+ start(toolCallId, toolName) {
79
+ const field = fields[toolName];
80
+ if (field === undefined)
81
+ return; // 不在白名单,不建账——delta 恒 null
82
+ entries.set(toolCallId, {
83
+ toolName,
84
+ pathKey: field.path,
85
+ textKey: field.text,
86
+ raw: '',
87
+ rawChars: 0,
88
+ path: null,
89
+ emittedChars: 0,
90
+ emittedRawChars: 0,
91
+ });
92
+ },
93
+ delta(toolCallId, text) {
94
+ const e = entries.get(toolCallId);
95
+ if (e === undefined)
96
+ return null;
97
+ e.raw += text;
98
+ e.rawChars += countCodePoints(text);
99
+ // `path` 一旦完整就不会再变(同一个 JSON 里只有一个顶层 `path`),不必
100
+ // 重扫;而它还没完整时**每块都要扫**——第一帧要尽快把路径带出去。
101
+ if (e.path === null) {
102
+ const pathResult = extractJsonStringField(e.raw, e.pathKey);
103
+ // 路径都还没齐,正文更不可能过阈值(正文在 JSON 里排在后面)。
104
+ if (pathResult === null || !pathResult.complete)
105
+ return null;
106
+ e.path = pathResult.value;
107
+ // 「首次拿到完整 path」是独立于字数阈值的触发点——稿栏靠它在正文
108
+ // 到来之前先打开并显示文件名,晚了就是「先写了半天字才冒出标题」。
109
+ // 正文多半还是空串,但同一块里就带上了正文时也要如实发出去。
110
+ const seed = readText(e);
111
+ return emit(e, toolCallId, seed.text, seed.chars);
112
+ }
113
+ // 没有正文字段的工具(`Edit`):路径那一条发完就再没有可发的了。
114
+ if (e.textKey === null)
115
+ return null;
116
+ // 见头注释「成本」①:raw 涨得还不够一个阈值 → 正文必然也不够,不扫。
117
+ const threshold = previewThreshold(e.emittedChars, thresholdChars);
118
+ if (e.rawChars - e.emittedRawChars < threshold)
119
+ return null;
120
+ const next = readText(e);
121
+ if (next.chars - e.emittedChars < threshold)
122
+ return null;
123
+ return emit(e, toolCallId, next.text, next.chars);
124
+ },
125
+ done(toolCallId) {
126
+ entries.delete(toolCallId);
127
+ },
128
+ };
129
+ /** 当前累计的正文前缀;无正文字段的工具恒 `('', 0)`。 */
130
+ function readText(e) {
131
+ if (e.textKey === null)
132
+ return { text: '', chars: 0 };
133
+ const result = extractJsonStringField(e.raw, e.textKey);
134
+ const text = result !== null ? result.value : '';
135
+ return { text, chars: countCodePoints(text) };
136
+ }
137
+ function emit(e, toolCallId, text, chars) {
138
+ e.emittedChars = chars;
139
+ e.emittedRawChars = e.rawChars;
140
+ return { toolCallId, toolName: e.toolName, path: e.path, text, chars };
141
+ }
142
+ }
143
+ //# sourceMappingURL=tool-input-preview.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-input-preview.js","sourceRoot":"","sources":["../../src/turn/tool-input-preview.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,47 @@
1
+ /**
2
+ * 工具入参流式构建的**进度节流器**。
3
+ *
4
+ * **为什么需要它**:`emit('tool-call', …)` 发生在整个 step 的流被消费完之后
5
+ * (`runTurn` 里 `emit('text-end')` 之后那个 `for (const tc of toolCalls)`
6
+ * 循环),而模型吐这次调用参数的那段时间——写一篇长文时就是绝大部分时间——
7
+ * 界面上一片死寂:`tool-input-delta` 在 depth 0 从不投影,用户看到的是一个
8
+ * 停住的界面,只能当它卡了。
9
+ *
10
+ * **为什么不直接把 `tool-input-delta` 投出去**:那条流是**有消费方的**——
11
+ * `parts-from-events.ts` 的 abort 兜底靠累积它的原始 JSON 片段,在中断时重建
12
+ * 半截的 tool-call。它必须保持逐块、不节流、原样。而它作为 UI 信号又太碎
13
+ * (实测一次调用约 120 块),且投影层根本没有 `delta` 字段可透。
14
+ *
15
+ * 所以这里另发一条**只服务于界面**的进度事件:累积到一定字数才发一次,
16
+ * 载荷是「已经收到多少字符」而不是内容本身。
17
+ *
18
+ * 零依赖纯函数,便于单测(本仓既有做法:`running-nodes.ts`/`autosave-scheduler.ts`)。
19
+ */
20
+ /**
21
+ * 每积累这么多字符发一条进度。
22
+ *
23
+ * 按「界面上那个数字多久动一次」定:模型出中文大约 100+ 字符/秒,故 120 约等于
24
+ * 每秒一次。再密只是徒增事件,再疏就又开始像卡住了。
25
+ */
26
+ export declare const TOOL_INPUT_PROGRESS_CHARS = 120;
27
+ export interface ToolInputProgressEvent {
28
+ toolCallId: string;
29
+ toolName: string;
30
+ /** 至此累计收到的入参字符数(不是内容)。 */
31
+ chars: number;
32
+ }
33
+ export interface ToolInputProgressTracker {
34
+ /** 模型开始吐某次调用的参数。 */
35
+ start(toolCallId: string, toolName: string): void;
36
+ /**
37
+ * 收到一块入参增量。返回非 null 表示「该发一条进度了」。
38
+ *
39
+ * **未 `start` 过的 toolCallId 一律返回 null**:没有 `tool-input-start` 就
40
+ * 没有 toolName,发一条不知道是什么工具的进度,界面上无从落位。
41
+ */
42
+ delta(toolCallId: string, text: string): ToolInputProgressEvent | null;
43
+ /** 这次调用的参数收齐了,丢掉它的累计(一个 turn 可以跑很多步)。 */
44
+ done(toolCallId: string): void;
45
+ }
46
+ export declare function createToolInputProgressTracker(thresholdChars?: number): ToolInputProgressTracker;
47
+ //# sourceMappingURL=tool-input-progress.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-input-progress.d.ts","sourceRoot":"","sources":["../../src/turn/tool-input-progress.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH;;;;;GAKG;AACH,eAAO,MAAM,yBAAyB,MAAM,CAAC;AAE7C,MAAM,WAAW,sBAAsB;IACrC,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,0BAA0B;IAC1B,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,wBAAwB;IACvC,oBAAoB;IACpB,KAAK,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IAClD;;;;;OAKG;IACH,KAAK,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,sBAAsB,GAAG,IAAI,CAAC;IACvE,yCAAyC;IACzC,IAAI,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAChC;AAED,wBAAgB,8BAA8B,CAC5C,cAAc,GAAE,MAAkC,GACjD,wBAAwB,CAwB1B"}
@@ -0,0 +1,50 @@
1
+ /**
2
+ * 工具入参流式构建的**进度节流器**。
3
+ *
4
+ * **为什么需要它**:`emit('tool-call', …)` 发生在整个 step 的流被消费完之后
5
+ * (`runTurn` 里 `emit('text-end')` 之后那个 `for (const tc of toolCalls)`
6
+ * 循环),而模型吐这次调用参数的那段时间——写一篇长文时就是绝大部分时间——
7
+ * 界面上一片死寂:`tool-input-delta` 在 depth 0 从不投影,用户看到的是一个
8
+ * 停住的界面,只能当它卡了。
9
+ *
10
+ * **为什么不直接把 `tool-input-delta` 投出去**:那条流是**有消费方的**——
11
+ * `parts-from-events.ts` 的 abort 兜底靠累积它的原始 JSON 片段,在中断时重建
12
+ * 半截的 tool-call。它必须保持逐块、不节流、原样。而它作为 UI 信号又太碎
13
+ * (实测一次调用约 120 块),且投影层根本没有 `delta` 字段可透。
14
+ *
15
+ * 所以这里另发一条**只服务于界面**的进度事件:累积到一定字数才发一次,
16
+ * 载荷是「已经收到多少字符」而不是内容本身。
17
+ *
18
+ * 零依赖纯函数,便于单测(本仓既有做法:`running-nodes.ts`/`autosave-scheduler.ts`)。
19
+ */
20
+ /**
21
+ * 每积累这么多字符发一条进度。
22
+ *
23
+ * 按「界面上那个数字多久动一次」定:模型出中文大约 100+ 字符/秒,故 120 约等于
24
+ * 每秒一次。再密只是徒增事件,再疏就又开始像卡住了。
25
+ */
26
+ export const TOOL_INPUT_PROGRESS_CHARS = 120;
27
+ export function createToolInputProgressTracker(thresholdChars = TOOL_INPUT_PROGRESS_CHARS) {
28
+ const entries = new Map();
29
+ return {
30
+ start(toolCallId, toolName) {
31
+ entries.set(toolCallId, { toolName, chars: 0, emittedAt: 0 });
32
+ },
33
+ delta(toolCallId, text) {
34
+ const e = entries.get(toolCallId);
35
+ if (e === undefined)
36
+ return null;
37
+ // 按**码点**数,不是 UTF-16 code unit:中文一字一码点,而 `.length`
38
+ // 对 emoji 之类会翻倍——这个数字是给人看的「已经写了多少字」。
39
+ e.chars += Array.from(text).length;
40
+ if (e.chars - e.emittedAt < thresholdChars)
41
+ return null;
42
+ e.emittedAt = e.chars;
43
+ return { toolCallId, toolName: e.toolName, chars: e.chars };
44
+ },
45
+ done(toolCallId) {
46
+ entries.delete(toolCallId);
47
+ },
48
+ };
49
+ }
50
+ //# sourceMappingURL=tool-input-progress.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-input-progress.js","sourceRoot":"","sources":["../../src/turn/tool-input-progress.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH;;;;;GAKG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG,GAAG,CAAC;AAuB7C,MAAM,UAAU,8BAA8B,CAC5C,iBAAyB,yBAAyB;IAElD,MAAM,OAAO,GAAG,IAAI,GAAG,EAGpB,CAAC;IAEJ,OAAO;QACL,KAAK,CAAC,UAAU,EAAE,QAAQ;YACxB,OAAO,CAAC,GAAG,CAAC,UAAU,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC,CAAC;QAChE,CAAC;QACD,KAAK,CAAC,UAAU,EAAE,IAAI;YACpB,MAAM,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;YAClC,IAAI,CAAC,KAAK,SAAS;gBAAE,OAAO,IAAI,CAAC;YACjC,mDAAmD;YACnD,qCAAqC;YACrC,CAAC,CAAC,KAAK,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC;YACnC,IAAI,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,SAAS,GAAG,cAAc;gBAAE,OAAO,IAAI,CAAC;YACxD,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC;YACtB,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC;QAC9D,CAAC;QACD,IAAI,CAAC,UAAU;YACb,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QAC7B,CAAC;KACF,CAAC;AACJ,CAAC"}