agentx-sdk 0.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 (318) hide show
  1. package/README.md +561 -0
  2. package/dist/agent.d.ts +105 -0
  3. package/dist/agent.d.ts.map +1 -0
  4. package/dist/agent.js +690 -0
  5. package/dist/agent.js.map +1 -0
  6. package/dist/config/config.d.ts +346 -0
  7. package/dist/config/config.d.ts.map +1 -0
  8. package/dist/config/config.js +93 -0
  9. package/dist/config/config.js.map +1 -0
  10. package/dist/contracts/entities/agent-event.d.ts +97 -0
  11. package/dist/contracts/entities/agent-event.d.ts.map +1 -0
  12. package/dist/contracts/entities/agent-event.js +2 -0
  13. package/dist/contracts/entities/agent-event.js.map +1 -0
  14. package/dist/contracts/entities/agent-skill.d.ts +59 -0
  15. package/dist/contracts/entities/agent-skill.d.ts.map +1 -0
  16. package/dist/contracts/entities/agent-skill.js +2 -0
  17. package/dist/contracts/entities/agent-skill.js.map +1 -0
  18. package/dist/contracts/entities/agent-tool.d.ts +42 -0
  19. package/dist/contracts/entities/agent-tool.d.ts.map +1 -0
  20. package/dist/contracts/entities/agent-tool.js +2 -0
  21. package/dist/contracts/entities/agent-tool.js.map +1 -0
  22. package/dist/contracts/entities/chat-message.d.ts +13 -0
  23. package/dist/contracts/entities/chat-message.d.ts.map +1 -0
  24. package/dist/contracts/entities/chat-message.js +2 -0
  25. package/dist/contracts/entities/chat-message.js.map +1 -0
  26. package/dist/contracts/entities/content-part.d.ts +16 -0
  27. package/dist/contracts/entities/content-part.d.ts.map +1 -0
  28. package/dist/contracts/entities/content-part.js +2 -0
  29. package/dist/contracts/entities/content-part.js.map +1 -0
  30. package/dist/contracts/entities/execution-context.d.ts +9 -0
  31. package/dist/contracts/entities/execution-context.d.ts.map +1 -0
  32. package/dist/contracts/entities/execution-context.js +2 -0
  33. package/dist/contracts/entities/execution-context.js.map +1 -0
  34. package/dist/contracts/entities/index.d.ts +11 -0
  35. package/dist/contracts/entities/index.d.ts.map +1 -0
  36. package/dist/contracts/entities/index.js +2 -0
  37. package/dist/contracts/entities/index.js.map +1 -0
  38. package/dist/contracts/entities/knowledge.d.ts +21 -0
  39. package/dist/contracts/entities/knowledge.d.ts.map +1 -0
  40. package/dist/contracts/entities/knowledge.js +2 -0
  41. package/dist/contracts/entities/knowledge.js.map +1 -0
  42. package/dist/contracts/entities/stores.d.ts +18 -0
  43. package/dist/contracts/entities/stores.d.ts.map +1 -0
  44. package/dist/contracts/entities/stores.js +2 -0
  45. package/dist/contracts/entities/stores.js.map +1 -0
  46. package/dist/contracts/entities/token-usage.d.ts +7 -0
  47. package/dist/contracts/entities/token-usage.d.ts.map +1 -0
  48. package/dist/contracts/entities/token-usage.js +2 -0
  49. package/dist/contracts/entities/token-usage.js.map +1 -0
  50. package/dist/contracts/entities/tool-call.d.ts +16 -0
  51. package/dist/contracts/entities/tool-call.d.ts.map +1 -0
  52. package/dist/contracts/entities/tool-call.js +2 -0
  53. package/dist/contracts/entities/tool-call.js.map +1 -0
  54. package/dist/contracts/enums/index.d.ts +21 -0
  55. package/dist/contracts/enums/index.d.ts.map +1 -0
  56. package/dist/contracts/enums/index.js +8 -0
  57. package/dist/contracts/enums/index.js.map +1 -0
  58. package/dist/contracts/index.d.ts +3 -0
  59. package/dist/contracts/index.d.ts.map +1 -0
  60. package/dist/contracts/index.js +3 -0
  61. package/dist/contracts/index.js.map +1 -0
  62. package/dist/core/compaction/autocompact.d.ts +18 -0
  63. package/dist/core/compaction/autocompact.d.ts.map +1 -0
  64. package/dist/core/compaction/autocompact.js +68 -0
  65. package/dist/core/compaction/autocompact.js.map +1 -0
  66. package/dist/core/compaction/microcompact.d.ts +20 -0
  67. package/dist/core/compaction/microcompact.d.ts.map +1 -0
  68. package/dist/core/compaction/microcompact.js +38 -0
  69. package/dist/core/compaction/microcompact.js.map +1 -0
  70. package/dist/core/compaction/snip-compact.d.ts +22 -0
  71. package/dist/core/compaction/snip-compact.d.ts.map +1 -0
  72. package/dist/core/compaction/snip-compact.js +61 -0
  73. package/dist/core/compaction/snip-compact.js.map +1 -0
  74. package/dist/core/compaction/tool-result-budget.d.ts +24 -0
  75. package/dist/core/compaction/tool-result-budget.d.ts.map +1 -0
  76. package/dist/core/compaction/tool-result-budget.js +67 -0
  77. package/dist/core/compaction/tool-result-budget.js.map +1 -0
  78. package/dist/core/context-analysis.d.ts +24 -0
  79. package/dist/core/context-analysis.d.ts.map +1 -0
  80. package/dist/core/context-analysis.js +37 -0
  81. package/dist/core/context-analysis.js.map +1 -0
  82. package/dist/core/context-builder.d.ts +25 -0
  83. package/dist/core/context-builder.d.ts.map +1 -0
  84. package/dist/core/context-builder.js +108 -0
  85. package/dist/core/context-builder.js.map +1 -0
  86. package/dist/core/conversation-manager.d.ts +19 -0
  87. package/dist/core/conversation-manager.d.ts.map +1 -0
  88. package/dist/core/conversation-manager.js +62 -0
  89. package/dist/core/conversation-manager.js.map +1 -0
  90. package/dist/core/execution-context.d.ts +6 -0
  91. package/dist/core/execution-context.d.ts.map +1 -0
  92. package/dist/core/execution-context.js +14 -0
  93. package/dist/core/execution-context.js.map +1 -0
  94. package/dist/core/loop-deps.d.ts +15 -0
  95. package/dist/core/loop-deps.d.ts.map +1 -0
  96. package/dist/core/loop-deps.js +8 -0
  97. package/dist/core/loop-deps.js.map +1 -0
  98. package/dist/core/loop-types.d.ts +34 -0
  99. package/dist/core/loop-types.d.ts.map +1 -0
  100. package/dist/core/loop-types.js +15 -0
  101. package/dist/core/loop-types.js.map +1 -0
  102. package/dist/core/message-normalize.d.ts +18 -0
  103. package/dist/core/message-normalize.d.ts.map +1 -0
  104. package/dist/core/message-normalize.js +69 -0
  105. package/dist/core/message-normalize.js.map +1 -0
  106. package/dist/core/prompt-builders.d.ts +36 -0
  107. package/dist/core/prompt-builders.d.ts.map +1 -0
  108. package/dist/core/prompt-builders.js +89 -0
  109. package/dist/core/prompt-builders.js.map +1 -0
  110. package/dist/core/prompt-cache.d.ts +25 -0
  111. package/dist/core/prompt-cache.d.ts.map +1 -0
  112. package/dist/core/prompt-cache.js +34 -0
  113. package/dist/core/prompt-cache.js.map +1 -0
  114. package/dist/core/react-loop.d.ts +43 -0
  115. package/dist/core/react-loop.d.ts.map +1 -0
  116. package/dist/core/react-loop.js +403 -0
  117. package/dist/core/react-loop.js.map +1 -0
  118. package/dist/core/stop-hooks.d.ts +18 -0
  119. package/dist/core/stop-hooks.d.ts.map +1 -0
  120. package/dist/core/stop-hooks.js +18 -0
  121. package/dist/core/stop-hooks.js.map +1 -0
  122. package/dist/core/stream-emitter.d.ts +24 -0
  123. package/dist/core/stream-emitter.d.ts.map +1 -0
  124. package/dist/core/stream-emitter.js +65 -0
  125. package/dist/core/stream-emitter.js.map +1 -0
  126. package/dist/core/streaming-tool-executor.d.ts +54 -0
  127. package/dist/core/streaming-tool-executor.d.ts.map +1 -0
  128. package/dist/core/streaming-tool-executor.js +164 -0
  129. package/dist/core/streaming-tool-executor.js.map +1 -0
  130. package/dist/core/turn-end-hooks.d.ts +39 -0
  131. package/dist/core/turn-end-hooks.d.ts.map +1 -0
  132. package/dist/core/turn-end-hooks.js +36 -0
  133. package/dist/core/turn-end-hooks.js.map +1 -0
  134. package/dist/index.d.ts +39 -0
  135. package/dist/index.d.ts.map +1 -0
  136. package/dist/index.js +45 -0
  137. package/dist/index.js.map +1 -0
  138. package/dist/knowledge/chunking.d.ts +9 -0
  139. package/dist/knowledge/chunking.d.ts.map +1 -0
  140. package/dist/knowledge/chunking.js +49 -0
  141. package/dist/knowledge/chunking.js.map +1 -0
  142. package/dist/knowledge/embedding-service.d.ts +16 -0
  143. package/dist/knowledge/embedding-service.d.ts.map +1 -0
  144. package/dist/knowledge/embedding-service.js +43 -0
  145. package/dist/knowledge/embedding-service.js.map +1 -0
  146. package/dist/knowledge/knowledge-manager.d.ts +33 -0
  147. package/dist/knowledge/knowledge-manager.d.ts.map +1 -0
  148. package/dist/knowledge/knowledge-manager.js +62 -0
  149. package/dist/knowledge/knowledge-manager.js.map +1 -0
  150. package/dist/knowledge/sqlite-vector-store.d.ts +16 -0
  151. package/dist/knowledge/sqlite-vector-store.d.ts.map +1 -0
  152. package/dist/knowledge/sqlite-vector-store.js +56 -0
  153. package/dist/knowledge/sqlite-vector-store.js.map +1 -0
  154. package/dist/knowledge/vector-store.d.ts +2 -0
  155. package/dist/knowledge/vector-store.d.ts.map +1 -0
  156. package/dist/knowledge/vector-store.js +2 -0
  157. package/dist/knowledge/vector-store.js.map +1 -0
  158. package/dist/llm/errors.d.ts +15 -0
  159. package/dist/llm/errors.d.ts.map +1 -0
  160. package/dist/llm/errors.js +39 -0
  161. package/dist/llm/errors.js.map +1 -0
  162. package/dist/llm/message-types.d.ts +80 -0
  163. package/dist/llm/message-types.d.ts.map +1 -0
  164. package/dist/llm/message-types.js +2 -0
  165. package/dist/llm/message-types.js.map +1 -0
  166. package/dist/llm/openrouter-client.d.ts +18 -0
  167. package/dist/llm/openrouter-client.d.ts.map +1 -0
  168. package/dist/llm/openrouter-client.js +215 -0
  169. package/dist/llm/openrouter-client.js.map +1 -0
  170. package/dist/llm/reasoning.d.ts +10 -0
  171. package/dist/llm/reasoning.d.ts.map +1 -0
  172. package/dist/llm/reasoning.js +18 -0
  173. package/dist/llm/reasoning.js.map +1 -0
  174. package/dist/memory/file-memory-system.d.ts +98 -0
  175. package/dist/memory/file-memory-system.d.ts.map +1 -0
  176. package/dist/memory/file-memory-system.js +310 -0
  177. package/dist/memory/file-memory-system.js.map +1 -0
  178. package/dist/memory/memory-age.d.ts +22 -0
  179. package/dist/memory/memory-age.d.ts.map +1 -0
  180. package/dist/memory/memory-age.js +44 -0
  181. package/dist/memory/memory-age.js.map +1 -0
  182. package/dist/memory/memory-extractor.d.ts +56 -0
  183. package/dist/memory/memory-extractor.d.ts.map +1 -0
  184. package/dist/memory/memory-extractor.js +91 -0
  185. package/dist/memory/memory-extractor.js.map +1 -0
  186. package/dist/memory/memory-paths.d.ts +45 -0
  187. package/dist/memory/memory-paths.d.ts.map +1 -0
  188. package/dist/memory/memory-paths.js +121 -0
  189. package/dist/memory/memory-paths.js.map +1 -0
  190. package/dist/memory/memory-prompts.d.ts +41 -0
  191. package/dist/memory/memory-prompts.d.ts.map +1 -0
  192. package/dist/memory/memory-prompts.js +279 -0
  193. package/dist/memory/memory-prompts.js.map +1 -0
  194. package/dist/memory/memory-relevance.d.ts +16 -0
  195. package/dist/memory/memory-relevance.d.ts.map +1 -0
  196. package/dist/memory/memory-relevance.js +46 -0
  197. package/dist/memory/memory-relevance.js.map +1 -0
  198. package/dist/memory/memory-scanner.d.ts +22 -0
  199. package/dist/memory/memory-scanner.d.ts.map +1 -0
  200. package/dist/memory/memory-scanner.js +99 -0
  201. package/dist/memory/memory-scanner.js.map +1 -0
  202. package/dist/memory/memory-tools.d.ts +16 -0
  203. package/dist/memory/memory-tools.d.ts.map +1 -0
  204. package/dist/memory/memory-tools.js +196 -0
  205. package/dist/memory/memory-tools.js.map +1 -0
  206. package/dist/memory/memory-types.d.ts +47 -0
  207. package/dist/memory/memory-types.d.ts.map +1 -0
  208. package/dist/memory/memory-types.js +24 -0
  209. package/dist/memory/memory-types.js.map +1 -0
  210. package/dist/skills/skill-args.d.ts +23 -0
  211. package/dist/skills/skill-args.d.ts.map +1 -0
  212. package/dist/skills/skill-args.js +77 -0
  213. package/dist/skills/skill-args.js.map +1 -0
  214. package/dist/skills/skill-glob.d.ts +24 -0
  215. package/dist/skills/skill-glob.d.ts.map +1 -0
  216. package/dist/skills/skill-glob.js +60 -0
  217. package/dist/skills/skill-glob.js.map +1 -0
  218. package/dist/skills/skill-loader.d.ts +49 -0
  219. package/dist/skills/skill-loader.d.ts.map +1 -0
  220. package/dist/skills/skill-loader.js +197 -0
  221. package/dist/skills/skill-loader.js.map +1 -0
  222. package/dist/skills/skill-manager.d.ts +83 -0
  223. package/dist/skills/skill-manager.d.ts.map +1 -0
  224. package/dist/skills/skill-manager.js +338 -0
  225. package/dist/skills/skill-manager.js.map +1 -0
  226. package/dist/storage/sqlite-conversation-store.d.ts +15 -0
  227. package/dist/storage/sqlite-conversation-store.d.ts.map +1 -0
  228. package/dist/storage/sqlite-conversation-store.js +45 -0
  229. package/dist/storage/sqlite-conversation-store.js.map +1 -0
  230. package/dist/storage/sqlite-database.d.ts +14 -0
  231. package/dist/storage/sqlite-database.d.ts.map +1 -0
  232. package/dist/storage/sqlite-database.js +95 -0
  233. package/dist/storage/sqlite-database.js.map +1 -0
  234. package/dist/tools/builtin/ask-user.d.ts +7 -0
  235. package/dist/tools/builtin/ask-user.d.ts.map +1 -0
  236. package/dist/tools/builtin/ask-user.js +23 -0
  237. package/dist/tools/builtin/ask-user.js.map +1 -0
  238. package/dist/tools/builtin/bash.d.ts +3 -0
  239. package/dist/tools/builtin/bash.d.ts.map +1 -0
  240. package/dist/tools/builtin/bash.js +54 -0
  241. package/dist/tools/builtin/bash.js.map +1 -0
  242. package/dist/tools/builtin/file-edit.d.ts +3 -0
  243. package/dist/tools/builtin/file-edit.d.ts.map +1 -0
  244. package/dist/tools/builtin/file-edit.js +50 -0
  245. package/dist/tools/builtin/file-edit.js.map +1 -0
  246. package/dist/tools/builtin/file-read.d.ts +3 -0
  247. package/dist/tools/builtin/file-read.d.ts.map +1 -0
  248. package/dist/tools/builtin/file-read.js +47 -0
  249. package/dist/tools/builtin/file-read.js.map +1 -0
  250. package/dist/tools/builtin/file-write.d.ts +3 -0
  251. package/dist/tools/builtin/file-write.d.ts.map +1 -0
  252. package/dist/tools/builtin/file-write.js +29 -0
  253. package/dist/tools/builtin/file-write.js.map +1 -0
  254. package/dist/tools/builtin/glob.d.ts +3 -0
  255. package/dist/tools/builtin/glob.d.ts.map +1 -0
  256. package/dist/tools/builtin/glob.js +67 -0
  257. package/dist/tools/builtin/glob.js.map +1 -0
  258. package/dist/tools/builtin/grep.d.ts +3 -0
  259. package/dist/tools/builtin/grep.d.ts.map +1 -0
  260. package/dist/tools/builtin/grep.js +94 -0
  261. package/dist/tools/builtin/grep.js.map +1 -0
  262. package/dist/tools/builtin/index.d.ts +49 -0
  263. package/dist/tools/builtin/index.d.ts.map +1 -0
  264. package/dist/tools/builtin/index.js +65 -0
  265. package/dist/tools/builtin/index.js.map +1 -0
  266. package/dist/tools/builtin/web-fetch.d.ts +3 -0
  267. package/dist/tools/builtin/web-fetch.d.ts.map +1 -0
  268. package/dist/tools/builtin/web-fetch.js +56 -0
  269. package/dist/tools/builtin/web-fetch.js.map +1 -0
  270. package/dist/tools/json-schema-to-zod.d.ts +30 -0
  271. package/dist/tools/json-schema-to-zod.d.ts.map +1 -0
  272. package/dist/tools/json-schema-to-zod.js +123 -0
  273. package/dist/tools/json-schema-to-zod.js.map +1 -0
  274. package/dist/tools/mcp-adapter.d.ts +80 -0
  275. package/dist/tools/mcp-adapter.d.ts.map +1 -0
  276. package/dist/tools/mcp-adapter.js +326 -0
  277. package/dist/tools/mcp-adapter.js.map +1 -0
  278. package/dist/tools/skill-tool.d.ts +41 -0
  279. package/dist/tools/skill-tool.d.ts.map +1 -0
  280. package/dist/tools/skill-tool.js +149 -0
  281. package/dist/tools/skill-tool.js.map +1 -0
  282. package/dist/tools/sql/index.d.ts +4 -0
  283. package/dist/tools/sql/index.d.ts.map +1 -0
  284. package/dist/tools/sql/index.js +2 -0
  285. package/dist/tools/sql/index.js.map +1 -0
  286. package/dist/tools/sql/sql-query-def.d.ts +22 -0
  287. package/dist/tools/sql/sql-query-def.d.ts.map +1 -0
  288. package/dist/tools/sql/sql-query-def.js +2 -0
  289. package/dist/tools/sql/sql-query-def.js.map +1 -0
  290. package/dist/tools/sql/sql-tool-factory.d.ts +28 -0
  291. package/dist/tools/sql/sql-tool-factory.d.ts.map +1 -0
  292. package/dist/tools/sql/sql-tool-factory.js +136 -0
  293. package/dist/tools/sql/sql-tool-factory.js.map +1 -0
  294. package/dist/tools/tool-executor.d.ts +67 -0
  295. package/dist/tools/tool-executor.d.ts.map +1 -0
  296. package/dist/tools/tool-executor.js +232 -0
  297. package/dist/tools/tool-executor.js.map +1 -0
  298. package/dist/utils/cache.d.ts +22 -0
  299. package/dist/utils/cache.d.ts.map +1 -0
  300. package/dist/utils/cache.js +61 -0
  301. package/dist/utils/cache.js.map +1 -0
  302. package/dist/utils/logger.d.ts +15 -0
  303. package/dist/utils/logger.d.ts.map +1 -0
  304. package/dist/utils/logger.js +46 -0
  305. package/dist/utils/logger.js.map +1 -0
  306. package/dist/utils/model-context.d.ts +14 -0
  307. package/dist/utils/model-context.d.ts.map +1 -0
  308. package/dist/utils/model-context.js +52 -0
  309. package/dist/utils/model-context.js.map +1 -0
  310. package/dist/utils/retry.d.ts +13 -0
  311. package/dist/utils/retry.d.ts.map +1 -0
  312. package/dist/utils/retry.js +41 -0
  313. package/dist/utils/retry.js.map +1 -0
  314. package/dist/utils/token-counter.d.ts +6 -0
  315. package/dist/utils/token-counter.d.ts.map +1 -0
  316. package/dist/utils/token-counter.js +19 -0
  317. package/dist/utils/token-counter.js.map +1 -0
  318. package/package.json +43 -0
@@ -0,0 +1,403 @@
1
+ import { createInitialState } from './loop-types.js';
2
+ import { StreamingToolExecutor } from './streaming-tool-executor.js';
3
+ import { microcompact } from './compaction/microcompact.js';
4
+ import { applyToolResultBudget } from './compaction/tool-result-budget.js';
5
+ import { snipCompact } from './compaction/snip-compact.js';
6
+ import { autocompact } from './compaction/autocompact.js';
7
+ import { runStopHooks } from './stop-hooks.js';
8
+ import { PromptTooLongError, OverloadedError, InsufficientCreditsError, classifyAPIError } from '../llm/errors.js';
9
+ import { SKILL_TOOL_NAME } from '../tools/skill-tool.js';
10
+ import { normalizeMessagesForAPI } from './message-normalize.js';
11
+ const MAX_OUTPUT_TOKENS_RECOVERY_LIMIT = 3;
12
+ const MAX_BUDGET_CONTINUATIONS = 4;
13
+ const MIN_DELTA_TOKENS = 50;
14
+ const DEFAULT_MAX_TOOL_RESULT_CHARS = 10_000;
15
+ const DEFAULT_COMPACTION_THRESHOLD = 0.8;
16
+ const DEFAULT_TAIL_PROTECTION = 4;
17
+ /**
18
+ * ReAct loop as AsyncGenerator.
19
+ * Yields AgentEvent, returns Terminal.
20
+ * State is immutable — replaced atomically at each continue site.
21
+ */
22
+ export async function* executeReactLoop(initialMessages, config) {
23
+ const { client, toolExecutor, maxIterations, maxConsecutiveErrors, onToolError, costPolicy, signal, maxContextTokens, compactionThreshold, fallbackModel, maxOutputTokens, escalatedMaxOutputTokens, stopHooks, deps, tokenBudget, } = config;
24
+ let currentModel = config.model;
25
+ const usage = { inputTokens: 0, outputTokens: 0, totalTokens: 0 };
26
+ const toolDefs = toolExecutor.listTools().length > 0 ? toolExecutor.getToolDefinitions() : undefined;
27
+ // DI: use injected callModel or default to client.streamChat
28
+ const callModel = deps?.callModel ?? ((params) => client.streamChat(params));
29
+ // Token budget continuation tracking
30
+ let budgetContinuationCount = 0;
31
+ let cumulativeOutputTokens = 0;
32
+ let state = createInitialState([...initialMessages]);
33
+ while (true) {
34
+ const { messages, turnCount, consecutiveErrors } = state;
35
+ // --- Check abort ---
36
+ if (signal?.aborted) {
37
+ return { reason: 'abort', usage };
38
+ }
39
+ // --- Check cost policy ---
40
+ if (costPolicy?.maxTokensPerExecution && usage.totalTokens >= costPolicy.maxTokensPerExecution) {
41
+ if (costPolicy.onLimitReached === 'stop') {
42
+ return { reason: 'cost_limit', usage };
43
+ }
44
+ yield { type: 'warning', message: 'Token limit approaching', code: 'cost_warning' };
45
+ }
46
+ // --- Check max iterations ---
47
+ if (turnCount > maxIterations) {
48
+ yield { type: 'warning', message: 'Max iterations reached', code: 'max_iterations' };
49
+ return { reason: 'max_iterations', usage };
50
+ }
51
+ // --- Compaction pipeline (before LLM call) ---
52
+ let compactedMessages = [...messages];
53
+ // 0. Tool result budget — aggregate truncation (largest first)
54
+ if (maxContextTokens) {
55
+ const budgetChars = Math.floor(maxContextTokens * 4 * 0.5); // 50% of context in chars
56
+ const budgetResult = applyToolResultBudget(compactedMessages, { maxTotalToolResultChars: budgetChars });
57
+ if (budgetResult.truncatedCount > 0) {
58
+ compactedMessages = budgetResult.messages;
59
+ }
60
+ }
61
+ // 0.5. Snip compact — remove orphaned early tool results
62
+ const snipResult = snipCompact(compactedMessages, { tailProtection: DEFAULT_TAIL_PROTECTION });
63
+ if (snipResult.snippedCount > 0) {
64
+ compactedMessages = snipResult.messages;
65
+ }
66
+ // 1. Microcompact — truncate large tool results (with per-tool overrides)
67
+ const perToolMaxChars = new Map();
68
+ for (const tool of toolExecutor.listTools()) {
69
+ if (tool.maxResultChars !== undefined) {
70
+ perToolMaxChars.set(tool.name, tool.maxResultChars);
71
+ }
72
+ }
73
+ // Build tool_call_id → tool_name map from assistant messages in history
74
+ const toolCallIdToName = new Map();
75
+ for (const msg of compactedMessages) {
76
+ if (msg.role === 'assistant' && msg.tool_calls) {
77
+ for (const tc of msg.tool_calls) {
78
+ toolCallIdToName.set(tc.id, tc.function.name);
79
+ }
80
+ }
81
+ }
82
+ const microResult = microcompact(compactedMessages, {
83
+ maxToolResultChars: DEFAULT_MAX_TOOL_RESULT_CHARS,
84
+ perToolMaxChars: perToolMaxChars.size > 0 ? perToolMaxChars : undefined,
85
+ toolCallIdToName: toolCallIdToName.size > 0 ? toolCallIdToName : undefined,
86
+ });
87
+ if (microResult.truncatedCount > 0) {
88
+ compactedMessages = microResult.messages;
89
+ yield { type: 'compaction', strategy: 'microcompact', tokensFreed: 0 };
90
+ }
91
+ // 2. Autocompact — summarize if threshold exceeded
92
+ if (maxContextTokens) {
93
+ const autoResult = await autocompact(compactedMessages, client, {
94
+ maxContextTokens,
95
+ compactionThreshold: compactionThreshold ?? DEFAULT_COMPACTION_THRESHOLD,
96
+ tailProtection: DEFAULT_TAIL_PROTECTION,
97
+ });
98
+ if (autoResult) {
99
+ compactedMessages = autoResult.messages;
100
+ yield { type: 'compaction', strategy: 'autocompact', tokensFreed: autoResult.tokensFreed };
101
+ }
102
+ }
103
+ // --- Turn start ---
104
+ yield { type: 'turn_start', iteration: turnCount - 1 };
105
+ let fullText = '';
106
+ let finishReason = '';
107
+ let turnOutputTokens = 0;
108
+ const toolCalls = [];
109
+ const earlyToolResults = []; // Tool results completed during streaming
110
+ // --- Stream from LLM ---
111
+ const streamingExecutor = new StreamingToolExecutor(toolExecutor, signal);
112
+ const effectiveMaxTokens = state.maxOutputTokensOverride ?? maxOutputTokens;
113
+ try {
114
+ // Normalize messages before API call (remove orphaned tool results/calls, empty messages)
115
+ const normalizedMessages = normalizeMessagesForAPI(compactedMessages);
116
+ for await (const chunk of callModel({
117
+ messages: normalizedMessages,
118
+ tools: toolDefs,
119
+ model: currentModel,
120
+ signal,
121
+ maxTokens: effectiveMaxTokens,
122
+ })) {
123
+ switch (chunk.type) {
124
+ case 'content':
125
+ fullText += chunk.data;
126
+ yield { type: 'text_delta', content: chunk.data };
127
+ break;
128
+ case 'tool_call':
129
+ toolCalls.push({ id: chunk.id, name: chunk.name, arguments: chunk.arguments });
130
+ yield {
131
+ type: 'tool_call_start',
132
+ toolCall: { id: chunk.id, type: 'function', function: { name: chunk.name, arguments: chunk.arguments } },
133
+ };
134
+ streamingExecutor.addTool(chunk.id, chunk.name, chunk.arguments);
135
+ break;
136
+ case 'done':
137
+ finishReason = chunk.finishReason;
138
+ if (chunk.usage) {
139
+ usage.inputTokens += chunk.usage.inputTokens;
140
+ usage.outputTokens += chunk.usage.outputTokens;
141
+ usage.totalTokens += chunk.usage.totalTokens;
142
+ turnOutputTokens = chunk.usage.outputTokens;
143
+ }
144
+ break;
145
+ }
146
+ // Yield progress events from tools executing during streaming
147
+ for (const progress of streamingExecutor.getProgressEvents()) {
148
+ yield { type: 'tool_progress', toolCallId: progress.toolCallId, toolName: progress.toolName, data: progress.data };
149
+ }
150
+ // Yield completed tool results during streaming and collect for message history
151
+ for (const completed of streamingExecutor.getCompletedResults()) {
152
+ yield { type: 'tool_call_end', toolCallId: completed.id, result: completed.result, duration: completed.duration };
153
+ earlyToolResults.push({ role: 'tool', content: completed.result.content, tool_call_id: completed.id });
154
+ if (completed.result.isError && onToolError === 'stop') {
155
+ yield { type: 'turn_end', iteration: turnCount - 1, hasToolCalls: true };
156
+ return { reason: 'error', usage };
157
+ }
158
+ }
159
+ }
160
+ // --- Build assistant message ---
161
+ const assistantMessage = { role: 'assistant', content: fullText };
162
+ if (toolCalls.length > 0) {
163
+ assistantMessage.tool_calls = toolCalls.map(tc => ({
164
+ id: tc.id,
165
+ type: 'function',
166
+ function: { name: tc.name, arguments: tc.arguments },
167
+ }));
168
+ }
169
+ // --- Max Output Tokens Recovery (two steps: escalate first, then resume) ---
170
+ if (finishReason === 'length' && toolCalls.length === 0) {
171
+ // Step 1: Escalate maxTokens (retry same request with higher limit)
172
+ if (escalatedMaxOutputTokens &&
173
+ state.maxOutputTokensOverride === undefined) {
174
+ yield { type: 'recovery', reason: 'max_output_tokens_escalate', attempt: 1 };
175
+ state = {
176
+ ...state,
177
+ maxOutputTokensOverride: escalatedMaxOutputTokens,
178
+ transition: { reason: 'max_output_tokens_escalate' },
179
+ };
180
+ continue;
181
+ }
182
+ // Step 2: Multi-turn recovery (inject resume message)
183
+ const recoveryCount = state.maxOutputTokensRecoveryCount + 1;
184
+ if (recoveryCount > MAX_OUTPUT_TOKENS_RECOVERY_LIMIT) {
185
+ if (fullText)
186
+ yield { type: 'text_done', content: fullText };
187
+ yield { type: 'turn_end', iteration: turnCount - 1, hasToolCalls: false };
188
+ return { reason: 'max_output_tokens', usage };
189
+ }
190
+ yield { type: 'recovery', reason: 'max_output_tokens_recovery', attempt: recoveryCount };
191
+ const resumeMessage = {
192
+ role: 'user',
193
+ content: '[System: Your response was truncated. Resume directly from where you stopped — no recap, no repetition.]',
194
+ };
195
+ state = {
196
+ ...state,
197
+ messages: [...messages, assistantMessage, resumeMessage],
198
+ maxOutputTokensRecoveryCount: recoveryCount,
199
+ transition: { reason: 'max_output_tokens_recovery' },
200
+ };
201
+ continue;
202
+ }
203
+ // --- No tool calls → check stop hooks + budget continuation ---
204
+ if (toolCalls.length === 0) {
205
+ // Run stop hooks (if any)
206
+ if (stopHooks && stopHooks.length > 0) {
207
+ const hookResult = await runStopHooks(stopHooks, {
208
+ messages,
209
+ assistantText: fullText,
210
+ turnCount,
211
+ });
212
+ if (hookResult.preventContinuation) {
213
+ if (fullText)
214
+ yield { type: 'text_done', content: fullText };
215
+ yield { type: 'turn_end', iteration: turnCount - 1, hasToolCalls: false };
216
+ return { reason: 'stop_hook', usage };
217
+ }
218
+ if (hookResult.blockingErrors.length > 0) {
219
+ yield { type: 'recovery', reason: 'stop_hook_blocking', attempt: 1 };
220
+ const errorMessages = hookResult.blockingErrors.map(err => ({
221
+ role: 'user',
222
+ content: `[Stop hook error: ${err}]`,
223
+ }));
224
+ state = {
225
+ ...state,
226
+ messages: [...messages, assistantMessage, ...errorMessages],
227
+ turnCount: turnCount + 1,
228
+ transition: { reason: 'stop_hook_blocking' },
229
+ };
230
+ continue;
231
+ }
232
+ }
233
+ // Token budget continuation
234
+ if (tokenBudget) {
235
+ cumulativeOutputTokens += turnOutputTokens;
236
+ const outputThreshold = tokenBudget.total * tokenBudget.outputThreshold;
237
+ const belowThreshold = cumulativeOutputTokens < outputThreshold;
238
+ const notExhausted = budgetContinuationCount < MAX_BUDGET_CONTINUATIONS;
239
+ const notDiminishing = turnOutputTokens >= MIN_DELTA_TOKENS || budgetContinuationCount === 0;
240
+ if (belowThreshold && notExhausted && notDiminishing) {
241
+ budgetContinuationCount++;
242
+ yield { type: 'recovery', reason: 'token_budget_continuation', attempt: budgetContinuationCount };
243
+ const nudgeMessage = {
244
+ role: 'user',
245
+ content: '[System: Continue working. You still have budget remaining.]',
246
+ };
247
+ state = {
248
+ ...state,
249
+ messages: [...messages, assistantMessage, nudgeMessage],
250
+ turnCount: turnCount + 1,
251
+ transition: { reason: 'token_budget_continuation' },
252
+ };
253
+ continue;
254
+ }
255
+ }
256
+ // Normal completion
257
+ if (fullText)
258
+ yield { type: 'text_done', content: fullText };
259
+ yield { type: 'turn_end', iteration: turnCount - 1, hasToolCalls: false };
260
+ return { reason: 'stop', usage };
261
+ }
262
+ // --- Collect remaining tool results (include early results from streaming phase) ---
263
+ const toolResultMessages = [...earlyToolResults];
264
+ let hasToolError = false;
265
+ const touchedFilePaths = [];
266
+ // Drain remaining progress events
267
+ for (const progress of streamingExecutor.getProgressEvents()) {
268
+ yield { type: 'tool_progress', toolCallId: progress.toolCallId, toolName: progress.toolName, data: progress.data };
269
+ }
270
+ for await (const completed of streamingExecutor.getRemainingResults()) {
271
+ yield { type: 'tool_call_end', toolCallId: completed.id, result: completed.result, duration: completed.duration };
272
+ if (completed.result.isError && onToolError === 'stop') {
273
+ toolResultMessages.push({ role: 'tool', content: completed.result.content, tool_call_id: completed.id });
274
+ yield { type: 'turn_end', iteration: turnCount - 1, hasToolCalls: true };
275
+ return { reason: 'error', usage };
276
+ }
277
+ if (completed.result.isError)
278
+ hasToolError = true;
279
+ // Pin skill tool results so they survive compaction
280
+ const toolResultMsg = { role: 'tool', content: completed.result.content, tool_call_id: completed.id };
281
+ if (completed.name === SKILL_TOOL_NAME) {
282
+ toolResultMsg._pinned = true;
283
+ }
284
+ toolResultMessages.push(toolResultMsg);
285
+ // Extract file paths for conditional skill activation
286
+ if (config.onFilePathsTouched) {
287
+ const toolDef = toolExecutor.listTools().find(t => t.name === completed.name);
288
+ if (toolDef?.getFilePath) {
289
+ const tc = toolCalls.find(c => c.id === completed.id);
290
+ if (tc) {
291
+ try {
292
+ const parsed = JSON.parse(tc.arguments);
293
+ const paths = toolDef.getFilePath(parsed);
294
+ if (paths) {
295
+ const arr = Array.isArray(paths) ? paths : [paths];
296
+ touchedFilePaths.push(...arr);
297
+ }
298
+ }
299
+ catch { /* parse error — skip */ }
300
+ }
301
+ }
302
+ // Also check metadata.filePaths
303
+ const metaPaths = completed.result.metadata?.filePaths;
304
+ if (Array.isArray(metaPaths)) {
305
+ touchedFilePaths.push(...metaPaths.filter((p) => typeof p === 'string'));
306
+ }
307
+ }
308
+ }
309
+ // --- Conditional skill activation from file operations ---
310
+ if (config.onFilePathsTouched && touchedFilePaths.length > 0) {
311
+ const activated = config.onFilePathsTouched(touchedFilePaths);
312
+ for (const skillName of activated) {
313
+ yield { type: 'skill_activated', skillName };
314
+ }
315
+ }
316
+ // --- onToolError: 'retry' — re-run LLM turn so model can correct its args ---
317
+ if (hasToolError && onToolError === 'retry' && state.toolRetryCount < 1) {
318
+ yield { type: 'recovery', reason: 'tool_retry', attempt: state.toolRetryCount + 1 };
319
+ state = {
320
+ ...state,
321
+ messages: [...messages, assistantMessage, ...toolResultMessages],
322
+ turnCount: turnCount + 1,
323
+ consecutiveErrors: 0,
324
+ toolRetryCount: state.toolRetryCount + 1,
325
+ transition: { reason: 'next_turn' },
326
+ };
327
+ continue;
328
+ }
329
+ yield { type: 'turn_end', iteration: turnCount - 1, hasToolCalls: true };
330
+ // --- Continue site: next_turn ---
331
+ state = {
332
+ ...state,
333
+ messages: [...messages, assistantMessage, ...toolResultMessages],
334
+ turnCount: turnCount + 1,
335
+ consecutiveErrors: 0,
336
+ transition: { reason: 'next_turn' },
337
+ };
338
+ continue;
339
+ }
340
+ catch (error) {
341
+ const classified = classifyAPIError(error);
342
+ // --- PTL Recovery (413) ---
343
+ if (classified instanceof PromptTooLongError && !state.hasAttemptedCompaction) {
344
+ if (maxContextTokens) {
345
+ // Use original messages from state (not compactedMessages which may already be compacted)
346
+ const compactResult = await autocompact([...messages], client, {
347
+ maxContextTokens,
348
+ compactionThreshold: 0.1, // Force compaction
349
+ tailProtection: DEFAULT_TAIL_PROTECTION,
350
+ });
351
+ if (compactResult) {
352
+ yield { type: 'recovery', reason: 'reactive_compact_retry', attempt: 1 };
353
+ yield { type: 'compaction', strategy: 'autocompact', tokensFreed: compactResult.tokensFreed };
354
+ state = {
355
+ ...state,
356
+ messages: compactResult.messages,
357
+ hasAttemptedCompaction: true,
358
+ transition: { reason: 'reactive_compact_retry' },
359
+ };
360
+ continue;
361
+ }
362
+ }
363
+ return { reason: 'prompt_too_long', usage };
364
+ }
365
+ if (classified instanceof PromptTooLongError) {
366
+ return { reason: 'prompt_too_long', usage };
367
+ }
368
+ // --- Insufficient Credits (402) — non-recoverable ---
369
+ if (classified instanceof InsufficientCreditsError) {
370
+ yield { type: 'error', error: classified, recoverable: false };
371
+ return { reason: 'error', usage, error: classified };
372
+ }
373
+ // --- Model Fallback (529/503) ---
374
+ if (classified instanceof OverloadedError && fallbackModel && currentModel !== fallbackModel) {
375
+ yield { type: 'model_fallback', from: currentModel, to: fallbackModel };
376
+ currentModel = fallbackModel;
377
+ state = {
378
+ ...state,
379
+ transition: { reason: 'model_fallback' },
380
+ };
381
+ continue;
382
+ }
383
+ // --- Generic error recovery ---
384
+ const newConsecutiveErrors = consecutiveErrors + 1;
385
+ const actualError = classified instanceof Error ? classified : new Error(String(classified));
386
+ yield {
387
+ type: 'error',
388
+ error: actualError,
389
+ recoverable: newConsecutiveErrors < maxConsecutiveErrors,
390
+ };
391
+ if (newConsecutiveErrors >= maxConsecutiveErrors) {
392
+ return { reason: 'error', usage, error: actualError };
393
+ }
394
+ state = {
395
+ ...state,
396
+ consecutiveErrors: newConsecutiveErrors,
397
+ transition: undefined,
398
+ };
399
+ continue;
400
+ }
401
+ }
402
+ }
403
+ //# sourceMappingURL=react-loop.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"react-loop.js","sourceRoot":"","sources":["../../src/core/react-loop.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import type { OpenRouterMessage } from '../llm/message-types.js';
2
+ export interface StopHookContext {
3
+ messages: readonly OpenRouterMessage[];
4
+ assistantText: string;
5
+ turnCount: number;
6
+ }
7
+ export interface StopHookResult {
8
+ blockingErrors: string[];
9
+ preventContinuation: boolean;
10
+ }
11
+ /** A hook that runs when the model produces a final response (no tool calls) */
12
+ export interface StopHook {
13
+ name: string;
14
+ execute(context: StopHookContext): Promise<StopHookResult>;
15
+ }
16
+ /** Run all stop hooks, merge results */
17
+ export declare function runStopHooks(hooks: StopHook[], context: StopHookContext): Promise<StopHookResult>;
18
+ //# sourceMappingURL=stop-hooks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stop-hooks.d.ts","sourceRoot":"","sources":["../../src/core/stop-hooks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAEjE,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,SAAS,iBAAiB,EAAE,CAAC;IACvC,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,cAAc;IAC7B,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,mBAAmB,EAAE,OAAO,CAAC;CAC9B;AAED,gFAAgF;AAChF,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;CAC5D;AAED,wCAAwC;AACxC,wBAAsB,YAAY,CAChC,KAAK,EAAE,QAAQ,EAAE,EACjB,OAAO,EAAE,eAAe,GACvB,OAAO,CAAC,cAAc,CAAC,CAezB"}
@@ -0,0 +1,18 @@
1
+ /** Run all stop hooks, merge results */
2
+ export async function runStopHooks(hooks, context) {
3
+ const allErrors = [];
4
+ let preventContinuation = false;
5
+ for (const hook of hooks) {
6
+ try {
7
+ const result = await hook.execute(context);
8
+ allErrors.push(...result.blockingErrors);
9
+ if (result.preventContinuation)
10
+ preventContinuation = true;
11
+ }
12
+ catch {
13
+ // Stop hooks should not break the loop
14
+ }
15
+ }
16
+ return { blockingErrors: allErrors, preventContinuation };
17
+ }
18
+ //# sourceMappingURL=stop-hooks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stop-hooks.js","sourceRoot":"","sources":["../../src/core/stop-hooks.ts"],"names":[],"mappings":"AAmBA,wCAAwC;AACxC,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,KAAiB,EACjB,OAAwB;IAExB,MAAM,SAAS,GAAa,EAAE,CAAC;IAC/B,IAAI,mBAAmB,GAAG,KAAK,CAAC;IAEhC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;YAC3C,SAAS,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,cAAc,CAAC,CAAC;YACzC,IAAI,MAAM,CAAC,mBAAmB;gBAAE,mBAAmB,GAAG,IAAI,CAAC;QAC7D,CAAC;QAAC,MAAM,CAAC;YACP,uCAAuC;QACzC,CAAC;IACH,CAAC;IAED,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,mBAAmB,EAAE,CAAC;AAC5D,CAAC"}
@@ -0,0 +1,24 @@
1
+ import type { AgentEvent } from '../contracts/entities/agent-event.js';
2
+ /**
3
+ * Async push/pull channel with bounded queue and backpressure for AgentEvents.
4
+ */
5
+ export declare class StreamEmitter {
6
+ private readonly queue;
7
+ private readonly maxQueueSize;
8
+ private resolve;
9
+ private done;
10
+ constructor(maxQueueSize?: number);
11
+ /**
12
+ * Push an event into the channel.
13
+ */
14
+ emit(event: AgentEvent): void;
15
+ /**
16
+ * Close the channel — no more events will be emitted.
17
+ */
18
+ close(): void;
19
+ /**
20
+ * Returns an AsyncIterableIterator for consuming events.
21
+ */
22
+ iterator(): AsyncIterableIterator<AgentEvent>;
23
+ }
24
+ //# sourceMappingURL=stream-emitter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stream-emitter.d.ts","sourceRoot":"","sources":["../../src/core/stream-emitter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sCAAsC,CAAC;AAEvE;;GAEG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAoB;IAC1C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,OAAO,CAA8D;IAC7E,OAAO,CAAC,IAAI,CAAS;gBAET,YAAY,SAAO;IAI/B;;OAEG;IACH,IAAI,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI;IAc7B;;OAEG;IACH,KAAK,IAAI,IAAI;IASb;;OAEG;IACH,QAAQ,IAAI,qBAAqB,CAAC,UAAU,CAAC;CAuB9C"}
@@ -0,0 +1,65 @@
1
+ /**
2
+ * Async push/pull channel with bounded queue and backpressure for AgentEvents.
3
+ */
4
+ export class StreamEmitter {
5
+ queue = [];
6
+ maxQueueSize;
7
+ resolve = null;
8
+ done = false;
9
+ constructor(maxQueueSize = 1000) {
10
+ this.maxQueueSize = maxQueueSize;
11
+ }
12
+ /**
13
+ * Push an event into the channel.
14
+ */
15
+ emit(event) {
16
+ if (this.done)
17
+ return;
18
+ if (this.resolve) {
19
+ // Consumer is waiting — deliver directly
20
+ const r = this.resolve;
21
+ this.resolve = null;
22
+ r({ value: event, done: false });
23
+ }
24
+ else if (this.queue.length < this.maxQueueSize) {
25
+ this.queue.push(event);
26
+ }
27
+ // If queue is full, drop event (backpressure)
28
+ }
29
+ /**
30
+ * Close the channel — no more events will be emitted.
31
+ */
32
+ close() {
33
+ this.done = true;
34
+ if (this.resolve) {
35
+ const r = this.resolve;
36
+ this.resolve = null;
37
+ r({ value: undefined, done: true });
38
+ }
39
+ }
40
+ /**
41
+ * Returns an AsyncIterableIterator for consuming events.
42
+ */
43
+ iterator() {
44
+ const self = this;
45
+ return {
46
+ next() {
47
+ // Drain queue first
48
+ if (self.queue.length > 0) {
49
+ return Promise.resolve({ value: self.queue.shift(), done: false });
50
+ }
51
+ if (self.done) {
52
+ return Promise.resolve({ value: undefined, done: true });
53
+ }
54
+ // Wait for next emit
55
+ return new Promise(resolve => {
56
+ self.resolve = resolve;
57
+ });
58
+ },
59
+ [Symbol.asyncIterator]() {
60
+ return this;
61
+ },
62
+ };
63
+ }
64
+ }
65
+ //# sourceMappingURL=stream-emitter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stream-emitter.js","sourceRoot":"","sources":["../../src/core/stream-emitter.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,OAAO,aAAa;IACP,KAAK,GAAiB,EAAE,CAAC;IACzB,YAAY,CAAS;IAC9B,OAAO,GAAyD,IAAI,CAAC;IACrE,IAAI,GAAG,KAAK,CAAC;IAErB,YAAY,YAAY,GAAG,IAAI;QAC7B,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC;IACnC,CAAC;IAED;;OAEG;IACH,IAAI,CAAC,KAAiB;QACpB,IAAI,IAAI,CAAC,IAAI;YAAE,OAAO;QAEtB,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACjB,yCAAyC;YACzC,MAAM,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC;YACvB,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;YACpB,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QACnC,CAAC;aAAM,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC;YACjD,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACzB,CAAC;QACD,8CAA8C;IAChD,CAAC;IAED;;OAEG;IACH,KAAK;QACH,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACjB,MAAM,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC;YACvB,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;YACpB,CAAC,CAAC,EAAE,KAAK,EAAE,SAAkC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;QAC/D,CAAC;IACH,CAAC;IAED;;OAEG;IACH,QAAQ;QACN,MAAM,IAAI,GAAG,IAAI,CAAC;QAClB,OAAO;YACL,IAAI;gBACF,oBAAoB;gBACpB,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBAC1B,OAAO,OAAO,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,EAAG,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;gBACtE,CAAC;gBAED,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;oBACd,OAAO,OAAO,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,SAAkC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;gBACpF,CAAC;gBAED,qBAAqB;gBACrB,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE;oBAC3B,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;gBACzB,CAAC,CAAC,CAAC;YACL,CAAC;YACD,CAAC,MAAM,CAAC,aAAa,CAAC;gBACpB,OAAO,IAAI,CAAC;YACd,CAAC;SACF,CAAC;IACJ,CAAC;CACF"}
@@ -0,0 +1,54 @@
1
+ import type { ToolExecutor } from '../tools/tool-executor.js';
2
+ import type { AgentToolResult } from '../contracts/entities/tool-call.js';
3
+ export interface ToolExecutionResult {
4
+ id: string;
5
+ name: string;
6
+ result: AgentToolResult;
7
+ duration: number;
8
+ }
9
+ export interface ToolProgressInfo {
10
+ toolCallId: string;
11
+ toolName: string;
12
+ data: Record<string, unknown>;
13
+ }
14
+ /**
15
+ * Executes tools while the LLM is still streaming.
16
+ * Respects concurrency safety: safe tools run in parallel, unsafe tools run alone.
17
+ * Results are always yielded in submission order.
18
+ * Supports progress callbacks — tools can report incremental updates.
19
+ */
20
+ export declare class StreamingToolExecutor {
21
+ private readonly tools;
22
+ private readonly executor;
23
+ private readonly signal?;
24
+ private processing;
25
+ /** Accumulated progress events from all tools (drained by getProgressEvents) */
26
+ private pendingProgress;
27
+ constructor(executor: ToolExecutor, signal?: AbortSignal);
28
+ /** Called during LLM streaming when a tool_call chunk arrives */
29
+ addTool(id: string, name: string, args: string): void;
30
+ /**
31
+ * Non-blocking: yields completed results in submission order.
32
+ * Call during streaming to drain finished tools without waiting.
33
+ */
34
+ getCompletedResults(): Generator<ToolExecutionResult>;
35
+ /**
36
+ * Non-blocking: drains accumulated progress events from all tools.
37
+ * Call during streaming alongside getCompletedResults().
38
+ */
39
+ getProgressEvents(): Generator<ToolProgressInfo>;
40
+ /**
41
+ * Blocking: waits for all remaining tools to complete, yielding in order.
42
+ * Call after streaming ends.
43
+ */
44
+ getRemainingResults(): AsyncGenerator<ToolExecutionResult>;
45
+ /**
46
+ * Process the queue respecting concurrency rules:
47
+ * - Multiple consecutive safe tools can execute in parallel
48
+ * - An unsafe tool must execute alone (waits for all prior to finish)
49
+ */
50
+ private processQueue;
51
+ private startTool;
52
+ private executeTool;
53
+ }
54
+ //# sourceMappingURL=streaming-tool-executor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"streaming-tool-executor.d.ts","sourceRoot":"","sources":["../../src/core/streaming-tool-executor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oCAAoC,CAAC;AAE1E,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,eAAe,CAAC;IACxB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,gBAAgB;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC/B;AAgBD;;;;;GAKG;AACH,qBAAa,qBAAqB;IAChC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAqB;IAC3C,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAe;IACxC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAc;IACtC,OAAO,CAAC,UAAU,CAAS;IAC3B,gFAAgF;IAChF,OAAO,CAAC,eAAe,CAA0B;gBAErC,QAAQ,EAAE,YAAY,EAAE,MAAM,CAAC,EAAE,WAAW;IAKxD,iEAAiE;IACjE,OAAO,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAgBrD;;;OAGG;IACF,mBAAmB,IAAI,SAAS,CAAC,mBAAmB,CAAC;IAgBtD;;;OAGG;IACF,iBAAiB,IAAI,SAAS,CAAC,gBAAgB,CAAC;IAMjD;;;OAGG;IACI,mBAAmB,IAAI,cAAc,CAAC,mBAAmB,CAAC;IAkBjE;;;;OAIG;YACW,YAAY;IAgC1B,OAAO,CAAC,SAAS;YAKH,WAAW;CAkC1B"}