@autonome-research/thread-phase 3.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 (263) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +226 -0
  3. package/dist/agent/index.d.ts +28 -0
  4. package/dist/agent/index.d.ts.map +1 -0
  5. package/dist/agent/index.js +28 -0
  6. package/dist/agent/index.js.map +1 -0
  7. package/dist/agent/openai-adapter.d.ts +15 -0
  8. package/dist/agent/openai-adapter.d.ts.map +1 -0
  9. package/dist/agent/openai-adapter.js +57 -0
  10. package/dist/agent/openai-adapter.js.map +1 -0
  11. package/dist/agent/parse-json.d.ts +12 -0
  12. package/dist/agent/parse-json.d.ts.map +1 -0
  13. package/dist/agent/parse-json.js +31 -0
  14. package/dist/agent/parse-json.js.map +1 -0
  15. package/dist/agent/retry.d.ts +15 -0
  16. package/dist/agent/retry.d.ts.map +1 -0
  17. package/dist/agent/retry.js +35 -0
  18. package/dist/agent/retry.js.map +1 -0
  19. package/dist/agent/runner.d.ts +25 -0
  20. package/dist/agent/runner.d.ts.map +1 -0
  21. package/dist/agent/runner.js +270 -0
  22. package/dist/agent/runner.js.map +1 -0
  23. package/dist/agent/stream-consumer.d.ts +57 -0
  24. package/dist/agent/stream-consumer.d.ts.map +1 -0
  25. package/dist/agent/stream-consumer.js +126 -0
  26. package/dist/agent/stream-consumer.js.map +1 -0
  27. package/dist/agent/types.d.ts +135 -0
  28. package/dist/agent/types.d.ts.map +1 -0
  29. package/dist/agent/types.js +9 -0
  30. package/dist/agent/types.js.map +1 -0
  31. package/dist/agent-runner.d.ts +10 -0
  32. package/dist/agent-runner.d.ts.map +1 -0
  33. package/dist/agent-runner.js +10 -0
  34. package/dist/agent-runner.js.map +1 -0
  35. package/dist/agents/capability.d.ts +36 -0
  36. package/dist/agents/capability.d.ts.map +1 -0
  37. package/dist/agents/capability.js +51 -0
  38. package/dist/agents/capability.js.map +1 -0
  39. package/dist/agents/event-bus.d.ts +20 -0
  40. package/dist/agents/event-bus.d.ts.map +1 -0
  41. package/dist/agents/event-bus.js +40 -0
  42. package/dist/agents/event-bus.js.map +1 -0
  43. package/dist/agents/index.d.ts +23 -0
  44. package/dist/agents/index.d.ts.map +1 -0
  45. package/dist/agents/index.js +33 -0
  46. package/dist/agents/index.js.map +1 -0
  47. package/dist/agents/inference-adapter.d.ts +52 -0
  48. package/dist/agents/inference-adapter.d.ts.map +1 -0
  49. package/dist/agents/inference-adapter.js +209 -0
  50. package/dist/agents/inference-adapter.js.map +1 -0
  51. package/dist/agents/job-store-bridge.d.ts +44 -0
  52. package/dist/agents/job-store-bridge.d.ts.map +1 -0
  53. package/dist/agents/job-store-bridge.js +58 -0
  54. package/dist/agents/job-store-bridge.js.map +1 -0
  55. package/dist/agents/memory.d.ts +40 -0
  56. package/dist/agents/memory.d.ts.map +1 -0
  57. package/dist/agents/memory.js +14 -0
  58. package/dist/agents/memory.js.map +1 -0
  59. package/dist/agents/protocol.d.ts +302 -0
  60. package/dist/agents/protocol.d.ts.map +1 -0
  61. package/dist/agents/protocol.js +36 -0
  62. package/dist/agents/protocol.js.map +1 -0
  63. package/dist/agents/run-helpers.d.ts +70 -0
  64. package/dist/agents/run-helpers.d.ts.map +1 -0
  65. package/dist/agents/run-helpers.js +131 -0
  66. package/dist/agents/run-helpers.js.map +1 -0
  67. package/dist/agents/serialize-error.d.ts +18 -0
  68. package/dist/agents/serialize-error.d.ts.map +1 -0
  69. package/dist/agents/serialize-error.js +27 -0
  70. package/dist/agents/serialize-error.js.map +1 -0
  71. package/dist/agents/structured-output.d.ts +90 -0
  72. package/dist/agents/structured-output.d.ts.map +1 -0
  73. package/dist/agents/structured-output.js +101 -0
  74. package/dist/agents/structured-output.js.map +1 -0
  75. package/dist/agents/test-utils/conformance.d.ts +59 -0
  76. package/dist/agents/test-utils/conformance.d.ts.map +1 -0
  77. package/dist/agents/test-utils/conformance.js +207 -0
  78. package/dist/agents/test-utils/conformance.js.map +1 -0
  79. package/dist/agents/test-utils/index.d.ts +12 -0
  80. package/dist/agents/test-utils/index.d.ts.map +1 -0
  81. package/dist/agents/test-utils/index.js +12 -0
  82. package/dist/agents/test-utils/index.js.map +1 -0
  83. package/dist/agents/test-utils/mock-agent.d.ts +66 -0
  84. package/dist/agents/test-utils/mock-agent.d.ts.map +1 -0
  85. package/dist/agents/test-utils/mock-agent.js +244 -0
  86. package/dist/agents/test-utils/mock-agent.js.map +1 -0
  87. package/dist/agents/thread.d.ts +57 -0
  88. package/dist/agents/thread.d.ts.map +1 -0
  89. package/dist/agents/thread.js +128 -0
  90. package/dist/agents/thread.js.map +1 -0
  91. package/dist/agents/turn-accumulator.d.ts +94 -0
  92. package/dist/agents/turn-accumulator.d.ts.map +1 -0
  93. package/dist/agents/turn-accumulator.js +150 -0
  94. package/dist/agents/turn-accumulator.js.map +1 -0
  95. package/dist/agents/with-memory.d.ts +55 -0
  96. package/dist/agents/with-memory.d.ts.map +1 -0
  97. package/dist/agents/with-memory.js +155 -0
  98. package/dist/agents/with-memory.js.map +1 -0
  99. package/dist/agents/with-thread.d.ts +45 -0
  100. package/dist/agents/with-thread.d.ts.map +1 -0
  101. package/dist/agents/with-thread.js +70 -0
  102. package/dist/agents/with-thread.js.map +1 -0
  103. package/dist/cache.d.ts +47 -0
  104. package/dist/cache.d.ts.map +1 -0
  105. package/dist/cache.js +81 -0
  106. package/dist/cache.js.map +1 -0
  107. package/dist/context/compressor.d.ts +36 -0
  108. package/dist/context/compressor.d.ts.map +1 -0
  109. package/dist/context/compressor.js +158 -0
  110. package/dist/context/compressor.js.map +1 -0
  111. package/dist/context/index.d.ts +4 -0
  112. package/dist/context/index.d.ts.map +1 -0
  113. package/dist/context/index.js +4 -0
  114. package/dist/context/index.js.map +1 -0
  115. package/dist/context/result-capper.d.ts +32 -0
  116. package/dist/context/result-capper.d.ts.map +1 -0
  117. package/dist/context/result-capper.js +50 -0
  118. package/dist/context/result-capper.js.map +1 -0
  119. package/dist/context/token-budget.d.ts +81 -0
  120. package/dist/context/token-budget.d.ts.map +1 -0
  121. package/dist/context/token-budget.js +99 -0
  122. package/dist/context/token-budget.js.map +1 -0
  123. package/dist/helpers/caller.d.ts +18 -0
  124. package/dist/helpers/caller.d.ts.map +1 -0
  125. package/dist/helpers/caller.js +40 -0
  126. package/dist/helpers/caller.js.map +1 -0
  127. package/dist/helpers/hook.d.ts +73 -0
  128. package/dist/helpers/hook.d.ts.map +1 -0
  129. package/dist/helpers/hook.js +244 -0
  130. package/dist/helpers/hook.js.map +1 -0
  131. package/dist/helpers/index.d.ts +12 -0
  132. package/dist/helpers/index.d.ts.map +1 -0
  133. package/dist/helpers/index.js +11 -0
  134. package/dist/helpers/index.js.map +1 -0
  135. package/dist/helpers/one-shot.d.ts +27 -0
  136. package/dist/helpers/one-shot.d.ts.map +1 -0
  137. package/dist/helpers/one-shot.js +43 -0
  138. package/dist/helpers/one-shot.js.map +1 -0
  139. package/dist/helpers/schedule.d.ts +59 -0
  140. package/dist/helpers/schedule.d.ts.map +1 -0
  141. package/dist/helpers/schedule.js +118 -0
  142. package/dist/helpers/schedule.js.map +1 -0
  143. package/dist/helpers/types.d.ts +34 -0
  144. package/dist/helpers/types.d.ts.map +1 -0
  145. package/dist/helpers/types.js +11 -0
  146. package/dist/helpers/types.js.map +1 -0
  147. package/dist/index.d.ts +26 -0
  148. package/dist/index.d.ts.map +1 -0
  149. package/dist/index.js +37 -0
  150. package/dist/index.js.map +1 -0
  151. package/dist/inference.d.ts +27 -0
  152. package/dist/inference.d.ts.map +1 -0
  153. package/dist/inference.js +34 -0
  154. package/dist/inference.js.map +1 -0
  155. package/dist/messages.d.ts +64 -0
  156. package/dist/messages.d.ts.map +1 -0
  157. package/dist/messages.js +17 -0
  158. package/dist/messages.js.map +1 -0
  159. package/dist/orchestrator.d.ts +56 -0
  160. package/dist/orchestrator.d.ts.map +1 -0
  161. package/dist/orchestrator.js +62 -0
  162. package/dist/orchestrator.js.map +1 -0
  163. package/dist/patterns/bounded-fanout-of.d.ts +61 -0
  164. package/dist/patterns/bounded-fanout-of.d.ts.map +1 -0
  165. package/dist/patterns/bounded-fanout-of.js +142 -0
  166. package/dist/patterns/bounded-fanout-of.js.map +1 -0
  167. package/dist/patterns/bounded-fanout.d.ts +111 -0
  168. package/dist/patterns/bounded-fanout.d.ts.map +1 -0
  169. package/dist/patterns/bounded-fanout.js +151 -0
  170. package/dist/patterns/bounded-fanout.js.map +1 -0
  171. package/dist/patterns/index.d.ts +14 -0
  172. package/dist/patterns/index.d.ts.map +1 -0
  173. package/dist/patterns/index.js +13 -0
  174. package/dist/patterns/index.js.map +1 -0
  175. package/dist/patterns/intent-gate.d.ts +27 -0
  176. package/dist/patterns/intent-gate.d.ts.map +1 -0
  177. package/dist/patterns/intent-gate.js +32 -0
  178. package/dist/patterns/intent-gate.js.map +1 -0
  179. package/dist/patterns/match.d.ts +30 -0
  180. package/dist/patterns/match.d.ts.map +1 -0
  181. package/dist/patterns/match.js +58 -0
  182. package/dist/patterns/match.js.map +1 -0
  183. package/dist/patterns/parallel-fanout.d.ts +28 -0
  184. package/dist/patterns/parallel-fanout.d.ts.map +1 -0
  185. package/dist/patterns/parallel-fanout.js +24 -0
  186. package/dist/patterns/parallel-fanout.js.map +1 -0
  187. package/dist/patterns/parallel-phases.d.ts +27 -0
  188. package/dist/patterns/parallel-phases.d.ts.map +1 -0
  189. package/dist/patterns/parallel-phases.js +77 -0
  190. package/dist/patterns/parallel-phases.js.map +1 -0
  191. package/dist/patterns/preflight-confidence.d.ts +20 -0
  192. package/dist/patterns/preflight-confidence.d.ts.map +1 -0
  193. package/dist/patterns/preflight-confidence.js +38 -0
  194. package/dist/patterns/preflight-confidence.js.map +1 -0
  195. package/dist/patterns/spot-check.d.ts +19 -0
  196. package/dist/patterns/spot-check.d.ts.map +1 -0
  197. package/dist/patterns/spot-check.js +33 -0
  198. package/dist/patterns/spot-check.js.map +1 -0
  199. package/dist/patterns/sub-pipeline.d.ts +84 -0
  200. package/dist/patterns/sub-pipeline.d.ts.map +1 -0
  201. package/dist/patterns/sub-pipeline.js +90 -0
  202. package/dist/patterns/sub-pipeline.js.map +1 -0
  203. package/dist/patterns/synthesize-with-followup.d.ts +35 -0
  204. package/dist/patterns/synthesize-with-followup.d.ts.map +1 -0
  205. package/dist/patterns/synthesize-with-followup.js +45 -0
  206. package/dist/patterns/synthesize-with-followup.js.map +1 -0
  207. package/dist/patterns/while-condition.d.ts +31 -0
  208. package/dist/patterns/while-condition.d.ts.map +1 -0
  209. package/dist/patterns/while-condition.js +59 -0
  210. package/dist/patterns/while-condition.js.map +1 -0
  211. package/dist/patterns/with-retry.d.ts +37 -0
  212. package/dist/patterns/with-retry.d.ts.map +1 -0
  213. package/dist/patterns/with-retry.js +73 -0
  214. package/dist/patterns/with-retry.js.map +1 -0
  215. package/dist/phase.d.ts +78 -0
  216. package/dist/phase.d.ts.map +1 -0
  217. package/dist/phase.js +36 -0
  218. package/dist/phase.js.map +1 -0
  219. package/dist/session/index.d.ts +5 -0
  220. package/dist/session/index.d.ts.map +1 -0
  221. package/dist/session/index.js +4 -0
  222. package/dist/session/index.js.map +1 -0
  223. package/dist/session/job-runner.d.ts +67 -0
  224. package/dist/session/job-runner.d.ts.map +1 -0
  225. package/dist/session/job-runner.js +131 -0
  226. package/dist/session/job-runner.js.map +1 -0
  227. package/dist/session/job-store.d.ts +98 -0
  228. package/dist/session/job-store.d.ts.map +1 -0
  229. package/dist/session/job-store.js +37 -0
  230. package/dist/session/job-store.js.map +1 -0
  231. package/dist/session/sqlite-job-store.d.ts +40 -0
  232. package/dist/session/sqlite-job-store.d.ts.map +1 -0
  233. package/dist/session/sqlite-job-store.js +200 -0
  234. package/dist/session/sqlite-job-store.js.map +1 -0
  235. package/dist/session/sse.d.ts +60 -0
  236. package/dist/session/sse.d.ts.map +1 -0
  237. package/dist/session/sse.js +97 -0
  238. package/dist/session/sse.js.map +1 -0
  239. package/dist/tools/index.d.ts +2 -0
  240. package/dist/tools/index.d.ts.map +1 -0
  241. package/dist/tools/index.js +2 -0
  242. package/dist/tools/index.js.map +1 -0
  243. package/dist/tools/registry.d.ts +44 -0
  244. package/dist/tools/registry.d.ts.map +1 -0
  245. package/dist/tools/registry.js +74 -0
  246. package/dist/tools/registry.js.map +1 -0
  247. package/dist/triggers/index.d.ts +15 -0
  248. package/dist/triggers/index.d.ts.map +1 -0
  249. package/dist/triggers/index.js +14 -0
  250. package/dist/triggers/index.js.map +1 -0
  251. package/dist/triggers/run-trigger.d.ts +86 -0
  252. package/dist/triggers/run-trigger.d.ts.map +1 -0
  253. package/dist/triggers/run-trigger.js +146 -0
  254. package/dist/triggers/run-trigger.js.map +1 -0
  255. package/dist/triggers/timer-trigger.d.ts +46 -0
  256. package/dist/triggers/timer-trigger.d.ts.map +1 -0
  257. package/dist/triggers/timer-trigger.js +74 -0
  258. package/dist/triggers/timer-trigger.js.map +1 -0
  259. package/dist/triggers/types.d.ts +61 -0
  260. package/dist/triggers/types.d.ts.map +1 -0
  261. package/dist/triggers/types.js +23 -0
  262. package/dist/triggers/types.js.map +1 -0
  263. package/package.json +64 -0
@@ -0,0 +1,270 @@
1
+ /**
2
+ * Agent runner — the tool-use loop primitive.
3
+ *
4
+ * Given an agent config (system prompt, tools, model tier), a starting
5
+ * conversation, and an executor for the tools, runs an iterated tool-use
6
+ * loop against an OpenAI-compatible inference endpoint until the agent
7
+ * produces final text or hits its round budget.
8
+ *
9
+ * Composed from focused helpers in this directory:
10
+ * - `./types.ts` — public surface
11
+ * - `./openai-adapter.ts` — Message↔OpenAI wire-format translation
12
+ * - `./stream-consumer.ts` — folds streaming chunks into one round's state
13
+ * - `./retry.ts` — error classification (retryable, abort)
14
+ *
15
+ * What the loop owns:
16
+ * - Round budgeting and the compress / hard-stop transitions
17
+ * - Streaming the request, dispatching tools, collecting results
18
+ * - Cumulative usage / executedToolCalls accounting across rounds
19
+ * - Cancellation observation (AbortSignal in options)
20
+ * - The verifyResult hook, the parser-mismatch warning, the retry loop
21
+ */
22
+ import { TokenBudgetTracker, BudgetStatus, } from '../context/token-budget.js';
23
+ import { TruncateAndCacheResultCapper } from '../context/result-capper.js';
24
+ import { DeterministicCompressor, AggressiveCompressor, sanitizeToolPairs, } from '../context/compressor.js';
25
+ import { toOpenAIMessages, toOpenAITools } from './openai-adapter.js';
26
+ import { consumeStream, looksLikeToolCallText } from './stream-consumer.js';
27
+ import { isRetryableError, isAbortError } from './retry.js';
28
+ export async function runAgentWithTools(config, initialMessages, options, agentLabel) {
29
+ const label = agentLabel ?? config.name;
30
+ const activity = [];
31
+ const executedToolCalls = [];
32
+ const cumulativeUsage = { promptTokens: 0, completionTokens: 0, totalTokens: 0 };
33
+ const cache = options.cache ?? null;
34
+ const maxRetries = options.maxRetries ?? 1;
35
+ const signal = options.signal;
36
+ const emit = options.onStreamEvent;
37
+ const budgetTracker = options.budgetTracker ?? new TokenBudgetTracker();
38
+ const cap = budgetTracker.getResultCap();
39
+ const protect = budgetTracker.getProtectCounts();
40
+ const resultCapper = options.resultCapper ?? new TruncateAndCacheResultCapper(cap.maxChars, cap.previewChars);
41
+ const compressor = options.compressor ?? new DeterministicCompressor();
42
+ const aggressiveCompressor = options.aggressiveCompressor ?? new AggressiveCompressor();
43
+ // Helper: compose the final result, run the verifyResult hook (if any),
44
+ // and surface a clean error result if the hook rejects.
45
+ const finalize = async (text, finishReason) => {
46
+ let result = {
47
+ text,
48
+ activity,
49
+ finishReason,
50
+ usage: cumulativeUsage,
51
+ executedToolCalls,
52
+ };
53
+ if (options.verifyResult) {
54
+ try {
55
+ const verified = await options.verifyResult(result);
56
+ if (verified)
57
+ result = verified;
58
+ }
59
+ catch (err) {
60
+ const e = err;
61
+ activity.push({
62
+ agent: label,
63
+ action: 'verify_failed',
64
+ detail: e.message?.slice(0, 200),
65
+ });
66
+ return {
67
+ ...result,
68
+ text: JSON.stringify({ _error: true, message: e.message ?? 'verifyResult threw' }),
69
+ finishReason: 'error',
70
+ };
71
+ }
72
+ }
73
+ return result;
74
+ };
75
+ // Surface a clear cancellation result when the caller aborts before the
76
+ // first round.
77
+ if (signal?.aborted) {
78
+ activity.push({ agent: label, action: 'aborted', detail: 'signal aborted before first round' });
79
+ return finalize('', 'error');
80
+ }
81
+ for (let attempt = 0; attempt <= maxRetries; attempt++) {
82
+ try {
83
+ let localMessages = [...initialMessages];
84
+ let forceOutput = false;
85
+ for (let round = 0; round < config.maxToolRounds; round++) {
86
+ if (signal?.aborted) {
87
+ activity.push({ agent: label, action: 'aborted', detail: `aborted before round ${round}` });
88
+ return finalize([...localMessages]
89
+ .reverse()
90
+ .find((m) => m.role === 'assistant')?.content ?? '', 'error');
91
+ }
92
+ // --- Layer 2: budget check (compress / hard-stop) ---
93
+ const budget = budgetTracker.check(config.systemPrompt, localMessages, forceOutput ? [] : config.tools);
94
+ if (budget.status === BudgetStatus.HARD_STOP && !forceOutput) {
95
+ activity.push({
96
+ agent: label,
97
+ action: 'budget_hard_stop',
98
+ detail: `${budget.estimatedTokens} tokens (${(budget.budgetUsed * 100).toFixed(0)}%) — aggressive compression`,
99
+ });
100
+ localMessages = aggressiveCompressor.compress(localMessages, {
101
+ protectFirst: protect.protectFirst,
102
+ protectLast: protect.protectLastAggressive,
103
+ activityLog: activity,
104
+ });
105
+ localMessages = sanitizeToolPairs(localMessages);
106
+ forceOutput = true;
107
+ }
108
+ else if (budget.status === BudgetStatus.COMPRESS) {
109
+ activity.push({
110
+ agent: label,
111
+ action: 'budget_compress',
112
+ detail: `${budget.estimatedTokens} tokens (${(budget.budgetUsed * 100).toFixed(0)}%) — compressing old results`,
113
+ });
114
+ localMessages = compressor.compress(localMessages, {
115
+ protectFirst: protect.protectFirst,
116
+ protectLast: protect.protectLast,
117
+ activityLog: activity,
118
+ });
119
+ localMessages = sanitizeToolPairs(localMessages);
120
+ }
121
+ const isLastRound = round === config.maxToolRounds - 1 || forceOutput;
122
+ // The nudge only makes sense when the agent has tools; injecting it
123
+ // for a no-tools agent confuses the model into returning empty content.
124
+ const shouldNudge = isLastRound && config.tools.length > 0;
125
+ const messagesForRequest = shouldNudge
126
+ ? [
127
+ ...localMessages,
128
+ {
129
+ role: 'user',
130
+ content: 'You are running out of tool rounds. Please produce your final output now based on what you have found so far.',
131
+ },
132
+ ]
133
+ : localMessages;
134
+ const openAiMessages = toOpenAIMessages(config.systemPrompt, messagesForRequest);
135
+ // The openai SDK serializes `tools: undefined` as `"tools": null` in
136
+ // the JSON body, which trips up vLLM/Qwen into a reasoning-only loop.
137
+ // Only set the field when we actually want tools available.
138
+ const sendTools = !isLastRound && config.tools.length > 0;
139
+ // extraBody first so anything the runner sets explicitly wins on key collision.
140
+ const requestBody = {
141
+ ...config.extraBody,
142
+ model: config.model,
143
+ max_tokens: config.maxTokens,
144
+ messages: openAiMessages,
145
+ stream: true,
146
+ // Ask backends that support it to include usage in the terminal
147
+ // chunk. Backends that don't support it ignore the field.
148
+ stream_options: { include_usage: true },
149
+ };
150
+ if (sendTools) {
151
+ requestBody.tools = toOpenAITools(config.tools);
152
+ }
153
+ const stream = await options.client.chat.completions.create(requestBody, {
154
+ signal,
155
+ });
156
+ const round_ = await consumeStream(stream, (delta) => {
157
+ emit?.({ type: 'content_delta', agent: label, delta });
158
+ });
159
+ // Roll usage forward across rounds.
160
+ cumulativeUsage.promptTokens += round_.usage.promptTokens;
161
+ cumulativeUsage.completionTokens += round_.usage.completionTokens;
162
+ cumulativeUsage.totalTokens += round_.usage.totalTokens;
163
+ // Inference-provider parser-mismatch warning: tools[] was sent but
164
+ // the model returned plain content shaped like a tool call. Likely
165
+ // a missing or wrong --tool-call-parser on the backend.
166
+ if (sendTools &&
167
+ round_.toolCalls.length === 0 &&
168
+ looksLikeToolCallText(round_.content)) {
169
+ const hint = 'tools[] was sent but model returned tool-call-shaped content as plain text. ' +
170
+ 'Likely a missing or wrong --tool-call-parser on the inference backend.';
171
+ activity.push({ agent: label, action: 'parser_mismatch_warning', detail: hint });
172
+ // eslint-disable-next-line no-console
173
+ console.warn(`[${label}] ${hint} Preview: ${round_.content.slice(0, 160)}`);
174
+ }
175
+ const assistantMsg = {
176
+ role: 'assistant',
177
+ content: round_.content,
178
+ toolCalls: round_.toolCalls,
179
+ };
180
+ localMessages.push(assistantMsg);
181
+ if (assistantMsg.content.trim() && assistantMsg.toolCalls.length > 0) {
182
+ activity.push({
183
+ agent: label,
184
+ action: 'reasoning',
185
+ detail: assistantMsg.content.trim().slice(0, 200),
186
+ });
187
+ }
188
+ emit?.({
189
+ type: 'round_complete',
190
+ agent: label,
191
+ round,
192
+ finishReason: round_.finishReason,
193
+ });
194
+ // No tool calls → final output, return.
195
+ if (assistantMsg.toolCalls.length === 0) {
196
+ return finalize(assistantMsg.content, round_.finishReason);
197
+ }
198
+ // Log tool calls + emit lifecycle events.
199
+ for (const tc of assistantMsg.toolCalls) {
200
+ const summary = Object.entries(tc.input)
201
+ .map(([k, v]) => `${k}=${JSON.stringify(v)}`.slice(0, 60))
202
+ .join(', ');
203
+ activity.push({
204
+ agent: label,
205
+ action: `tool:${tc.name}`,
206
+ detail: summary.slice(0, 120),
207
+ });
208
+ emit?.({ type: 'tool_call_started', agent: label, toolCall: tc });
209
+ }
210
+ // Execute tools in parallel.
211
+ const results = await Promise.all(assistantMsg.toolCalls.map((tc) => options.toolExecutor.execute(tc.name, tc.id, tc.input)));
212
+ // --- Layer 1: cap each tool result ---
213
+ for (let i = 0; i < results.length; i++) {
214
+ const r = results[i];
215
+ const tc = assistantMsg.toolCalls[i];
216
+ r.content = resultCapper.cap(r.content, tc.name, tc.id, cache);
217
+ activity.push({
218
+ agent: label,
219
+ action: `result:${tc.name}`,
220
+ detail: `${r.content.length} chars — ${r.content.slice(0, 80).replace(/\n/g, ' ')}`,
221
+ });
222
+ executedToolCalls.push(tc);
223
+ emit?.({ type: 'tool_call_complete', agent: label, toolCall: tc, result: r });
224
+ }
225
+ // Append tool-result messages.
226
+ for (const r of results) {
227
+ localMessages.push({
228
+ role: 'tool',
229
+ toolCallId: r.toolCallId,
230
+ content: r.content,
231
+ });
232
+ }
233
+ }
234
+ // Round budget exhausted with no final text output.
235
+ activity.push({ agent: label, action: 'max_rounds_reached' });
236
+ const lastAssistant = [...localMessages]
237
+ .reverse()
238
+ .find((m) => m.role === 'assistant');
239
+ // We ran out of rounds while the model still wanted to call tools.
240
+ // Surface that as 'length'-adjacent: incomplete from the model's
241
+ // perspective, even if the wire-level reason was 'tool_calls'.
242
+ return finalize(lastAssistant?.content ?? '{}', 'length');
243
+ }
244
+ catch (err) {
245
+ const e = err;
246
+ if (isAbortError(err)) {
247
+ activity.push({ agent: label, action: 'aborted', detail: e.message?.slice(0, 120) });
248
+ return finalize('', 'error');
249
+ }
250
+ activity.push({ agent: label, action: 'error', detail: e.message?.slice(0, 120) });
251
+ if (attempt < maxRetries && isRetryableError(err)) {
252
+ const delay = 2000 + Math.random() * 3000;
253
+ activity.push({
254
+ agent: label,
255
+ action: 'retry',
256
+ detail: `Retrying after ${e.message?.slice(0, 60)}`,
257
+ });
258
+ // eslint-disable-next-line no-console
259
+ console.warn(`[${label}] retryable error, waiting ${Math.round(delay)}ms: ${e.message?.slice(0, 100)}`);
260
+ await new Promise((r) => setTimeout(r, delay));
261
+ continue;
262
+ }
263
+ // eslint-disable-next-line no-console
264
+ console.error(`[${label}] agent failed (attempt ${attempt + 1}):`, e.message);
265
+ return finalize(JSON.stringify({ _error: true, message: e.message }), 'error');
266
+ }
267
+ }
268
+ return finalize('{}', 'error');
269
+ }
270
+ //# sourceMappingURL=runner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runner.js","sourceRoot":"","sources":["../../src/agent/runner.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Stream consumer — folds an OpenAI streaming chat-completion response into
3
+ * a single round's accumulated state (content, tool_calls, finish_reason,
4
+ * usage). Tool calls arrive as per-index deltas; we buffer by index and
5
+ * JSON-parse the args at the end.
6
+ *
7
+ * Pure data transform: takes an AsyncIterable of chunks, calls the supplied
8
+ * callback for each content delta, returns the assembled AccumulatedRound.
9
+ * No I/O, no logging, no agent state — keeps the consumer testable in
10
+ * isolation.
11
+ */
12
+ import type { ChatCompletionChunk } from 'openai/resources/chat/completions.js';
13
+ import type { ToolCall } from '../messages.js';
14
+ import type { FinishReason, UsageInfo } from './types.js';
15
+ /**
16
+ * @internal
17
+ *
18
+ * Internal accumulator shape — not part of the public API. May change
19
+ * between minor versions.
20
+ */
21
+ export interface AccumulatedRound {
22
+ content: string;
23
+ toolCalls: ToolCall[];
24
+ finishReason: FinishReason;
25
+ usage: UsageInfo;
26
+ }
27
+ /**
28
+ * @internal
29
+ *
30
+ * Normalize OpenAI's finish_reason string into a `FinishReason` union.
31
+ * Exported for advanced callers (e.g. building a custom streaming consumer)
32
+ * but not part of the v1 stable surface.
33
+ */
34
+ export declare function normalizeFinishReason(raw: string | null | undefined): FinishReason;
35
+ /**
36
+ * @internal
37
+ *
38
+ * Heuristic: does this content look like a tool call that leaked through
39
+ * as plain text? Used by the agent loop to flag a missing/wrong
40
+ * inference-side `--tool-call-parser` configuration. Exported for callers
41
+ * that want to apply the same heuristic; not part of the v1 stable surface.
42
+ */
43
+ export declare function looksLikeToolCallText(text: string): boolean;
44
+ /**
45
+ * @internal
46
+ *
47
+ * Consume one streaming chat-completion response.
48
+ *
49
+ * Calls `onContentDelta` synchronously for each chunk's content fragment so
50
+ * the caller can surface them upstream as they arrive. Returns the assembled
51
+ * round once the stream ends.
52
+ *
53
+ * Exported for advanced callers (e.g. building a non-loop agent that just
54
+ * streams once and returns); not part of the v1 stable surface.
55
+ */
56
+ export declare function consumeStream(stream: AsyncIterable<ChatCompletionChunk>, onContentDelta: (delta: string) => void): Promise<AccumulatedRound>;
57
+ //# sourceMappingURL=stream-consumer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stream-consumer.d.ts","sourceRoot":"","sources":["../../src/agent/stream-consumer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,sCAAsC,CAAC;AAChF,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE1D;;;;;GAKG;AACH,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,QAAQ,EAAE,CAAC;IACtB,YAAY,EAAE,YAAY,CAAC;IAC3B,KAAK,EAAE,SAAS,CAAC;CAClB;AAQD;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,YAAY,CAWlF;AAED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAS3D;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,aAAa,CACjC,MAAM,EAAE,aAAa,CAAC,mBAAmB,CAAC,EAC1C,cAAc,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,GACtC,OAAO,CAAC,gBAAgB,CAAC,CA6E3B"}
@@ -0,0 +1,126 @@
1
+ /**
2
+ * Stream consumer — folds an OpenAI streaming chat-completion response into
3
+ * a single round's accumulated state (content, tool_calls, finish_reason,
4
+ * usage). Tool calls arrive as per-index deltas; we buffer by index and
5
+ * JSON-parse the args at the end.
6
+ *
7
+ * Pure data transform: takes an AsyncIterable of chunks, calls the supplied
8
+ * callback for each content delta, returns the assembled AccumulatedRound.
9
+ * No I/O, no logging, no agent state — keeps the consumer testable in
10
+ * isolation.
11
+ */
12
+ /**
13
+ * @internal
14
+ *
15
+ * Normalize OpenAI's finish_reason string into a `FinishReason` union.
16
+ * Exported for advanced callers (e.g. building a custom streaming consumer)
17
+ * but not part of the v1 stable surface.
18
+ */
19
+ export function normalizeFinishReason(raw) {
20
+ switch (raw) {
21
+ case 'stop':
22
+ case 'length':
23
+ case 'tool_calls':
24
+ case 'content_filter':
25
+ case 'function_call':
26
+ return raw;
27
+ default:
28
+ return 'unknown';
29
+ }
30
+ }
31
+ /**
32
+ * @internal
33
+ *
34
+ * Heuristic: does this content look like a tool call that leaked through
35
+ * as plain text? Used by the agent loop to flag a missing/wrong
36
+ * inference-side `--tool-call-parser` configuration. Exported for callers
37
+ * that want to apply the same heuristic; not part of the v1 stable surface.
38
+ */
39
+ export function looksLikeToolCallText(text) {
40
+ const trimmed = text.trim();
41
+ if (!trimmed)
42
+ return false;
43
+ return (/^<tool_call\b/i.test(trimmed) ||
44
+ /^<function_call\b/i.test(trimmed) ||
45
+ /^\{\s*"name"\s*:/i.test(trimmed) ||
46
+ /^\{\s*"function"\s*:/i.test(trimmed));
47
+ }
48
+ /**
49
+ * @internal
50
+ *
51
+ * Consume one streaming chat-completion response.
52
+ *
53
+ * Calls `onContentDelta` synchronously for each chunk's content fragment so
54
+ * the caller can surface them upstream as they arrive. Returns the assembled
55
+ * round once the stream ends.
56
+ *
57
+ * Exported for advanced callers (e.g. building a non-loop agent that just
58
+ * streams once and returns); not part of the v1 stable surface.
59
+ */
60
+ export async function consumeStream(stream, onContentDelta) {
61
+ const out = {
62
+ content: '',
63
+ toolCalls: [],
64
+ finishReason: 'unknown',
65
+ usage: { promptTokens: 0, completionTokens: 0, totalTokens: 0 },
66
+ };
67
+ // Tool calls stream as deltas keyed by index. Build them up by index, then
68
+ // flatten to ToolCall[] at the end.
69
+ const toolBuffers = new Map();
70
+ for await (const chunk of stream) {
71
+ // Some backends emit an extra terminal chunk with usage and no choices.
72
+ if (chunk.usage) {
73
+ out.usage = {
74
+ promptTokens: chunk.usage.prompt_tokens ?? 0,
75
+ completionTokens: chunk.usage.completion_tokens ?? 0,
76
+ totalTokens: chunk.usage.total_tokens ?? 0,
77
+ };
78
+ }
79
+ const choice = chunk.choices?.[0];
80
+ if (!choice)
81
+ continue;
82
+ const delta = choice.delta;
83
+ if (delta?.content) {
84
+ out.content += delta.content;
85
+ onContentDelta(delta.content);
86
+ }
87
+ if (delta?.tool_calls) {
88
+ for (const tcDelta of delta.tool_calls) {
89
+ const idx = tcDelta.index;
90
+ let buf = toolBuffers.get(idx);
91
+ if (!buf) {
92
+ buf = { id: '', name: '', argsBuffer: '' };
93
+ toolBuffers.set(idx, buf);
94
+ }
95
+ if (tcDelta.id)
96
+ buf.id = tcDelta.id;
97
+ if (tcDelta.function?.name)
98
+ buf.name = tcDelta.function.name;
99
+ if (tcDelta.function?.arguments)
100
+ buf.argsBuffer += tcDelta.function.arguments;
101
+ }
102
+ }
103
+ if (choice.finish_reason) {
104
+ out.finishReason = normalizeFinishReason(choice.finish_reason);
105
+ }
106
+ }
107
+ // Flatten tool buffers in index order.
108
+ const indices = [...toolBuffers.keys()].sort((a, b) => a - b);
109
+ for (const idx of indices) {
110
+ const buf = toolBuffers.get(idx);
111
+ if (!buf.id || !buf.name) {
112
+ // Malformed tool call delta — skip rather than corrupt the loop.
113
+ continue;
114
+ }
115
+ let input = {};
116
+ try {
117
+ input = buf.argsBuffer ? JSON.parse(buf.argsBuffer) : {};
118
+ }
119
+ catch {
120
+ input = { _raw: buf.argsBuffer };
121
+ }
122
+ out.toolCalls.push({ id: buf.id, name: buf.name, input });
123
+ }
124
+ return out;
125
+ }
126
+ //# sourceMappingURL=stream-consumer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stream-consumer.js","sourceRoot":"","sources":["../../src/agent/stream-consumer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,135 @@
1
+ /**
2
+ * Public types for the agent runner.
3
+ *
4
+ * Kept separate from the loop so callers can import the surface without
5
+ * pulling in the streaming machinery, and so the type surface is easy to
6
+ * audit at a glance.
7
+ */
8
+ import type OpenAI from 'openai';
9
+ import type { ToolCall, ToolDefinition, ToolExecutor, ToolResult } from '../messages.js';
10
+ import type { TokenBudgetTracker } from '../context/token-budget.js';
11
+ import type { ResultCapper } from '../context/result-capper.js';
12
+ import type { CompressorStrategy } from '../context/compressor.js';
13
+ import type { PipelineCache } from '../cache.js';
14
+ export interface AgentConfig {
15
+ /** Identifier surfaced in activity logs. */
16
+ name: string;
17
+ systemPrompt: string;
18
+ /** Model name passed to the inference endpoint. Empty string → caller-default. */
19
+ model: string;
20
+ tools: ToolDefinition[];
21
+ /** Max rounds of tool use before forcing a final response. */
22
+ maxToolRounds: number;
23
+ /** Max tokens for the model's response. */
24
+ maxTokens: number;
25
+ /**
26
+ * Extra fields merged into the chat-completions request body. Use for
27
+ * provider-specific extensions that aren't in the OpenAI spec — e.g. vLLM's
28
+ * `chat_template_kwargs: { enable_thinking: false }` to disable Qwen3 reasoning,
29
+ * or `top_k`, `repetition_penalty`, etc.
30
+ *
31
+ * Merged via spread; if a key collides with one the runner sets explicitly
32
+ * (model, max_tokens, messages, tools, stream), the runner's value wins.
33
+ */
34
+ extraBody?: Record<string, unknown>;
35
+ }
36
+ export interface ActivityEntry {
37
+ agent: string;
38
+ action: string;
39
+ detail?: string;
40
+ }
41
+ /**
42
+ * `finishReason` mirrors OpenAI's `choices[0].finish_reason`. Callers that
43
+ * need to detect truncation should branch on `'length'` (= max_tokens hit,
44
+ * output cut off mid-stream). `'unknown'` is used when the backend never
45
+ * surfaced a reason (e.g. a stream that errored mid-flight).
46
+ */
47
+ export type FinishReason = 'stop' | 'length' | 'tool_calls' | 'content_filter' | 'function_call' | 'error' | 'unknown';
48
+ export interface UsageInfo {
49
+ promptTokens: number;
50
+ completionTokens: number;
51
+ totalTokens: number;
52
+ }
53
+ export interface AgentRunResult {
54
+ /** Final text output from the agent. May be JSON; caller can parseJSON it. */
55
+ text: string;
56
+ activity: ActivityEntry[];
57
+ /**
58
+ * Reason the agent stopped. `'stop'` = clean finish, `'length'` = truncated
59
+ * (max_tokens hit), `'tool_calls'` = stopped to call tools (rare at the top
60
+ * level since the loop continues), `'error'` = surfaced from a thrown error
61
+ * inside the loop, `'unknown'` = backend never reported one.
62
+ */
63
+ finishReason: FinishReason;
64
+ /** Token usage summed across every inference round in this run. */
65
+ usage: UsageInfo;
66
+ /**
67
+ * Every tool call the agent actually executed during this run, in order.
68
+ * Use this rather than parsing `activity[]` to verify what the agent did
69
+ * vs. what it claimed in its text/JSON output.
70
+ */
71
+ executedToolCalls: ToolCall[];
72
+ }
73
+ /**
74
+ * Streaming events fed to `AgentRunnerOptions.onStreamEvent`.
75
+ *
76
+ * - `content_delta`: chunk of model content as it streams.
77
+ * - `tool_call_started`: assistant emitted a tool call (post-decode).
78
+ * - `tool_call_complete`: tool executed, result capped, content available.
79
+ * - `round_complete`: one tool-use round just finished.
80
+ */
81
+ export type AgentStreamEvent = {
82
+ type: 'content_delta';
83
+ agent: string;
84
+ delta: string;
85
+ } | {
86
+ type: 'tool_call_started';
87
+ agent: string;
88
+ toolCall: ToolCall;
89
+ } | {
90
+ type: 'tool_call_complete';
91
+ agent: string;
92
+ toolCall: ToolCall;
93
+ result: ToolResult;
94
+ } | {
95
+ type: 'round_complete';
96
+ agent: string;
97
+ round: number;
98
+ finishReason: FinishReason;
99
+ };
100
+ export interface AgentRunnerOptions {
101
+ client: OpenAI;
102
+ toolExecutor: ToolExecutor;
103
+ /** Per-pipeline cache shared with the result capper for full-result retrieval. */
104
+ cache?: PipelineCache | null;
105
+ budgetTracker?: TokenBudgetTracker;
106
+ resultCapper?: ResultCapper;
107
+ compressor?: CompressorStrategy;
108
+ aggressiveCompressor?: CompressorStrategy;
109
+ /** Number of full retry attempts on retryable errors (default 1 = retry once). */
110
+ maxRetries?: number;
111
+ /**
112
+ * Cancellation signal. When aborted: the in-flight stream is cancelled
113
+ * (passed through to `client.chat.completions.create({ signal })`), the
114
+ * loop stops between rounds, and the runner returns whatever it has so far
115
+ * with `finishReason: 'error'`.
116
+ */
117
+ signal?: AbortSignal;
118
+ /**
119
+ * Optional streaming sink. Receives content deltas as they arrive plus
120
+ * tool-call lifecycle events. Synchronous callbacks only — don't await
121
+ * inside; if you need async work, schedule it.
122
+ */
123
+ onStreamEvent?: (event: AgentStreamEvent) => void;
124
+ /**
125
+ * Defensive validation hook called once per run, just before returning.
126
+ * Receives the assembled `AgentRunResult` (with `executedToolCalls` already
127
+ * populated) and may either return a transformed result or throw to mark
128
+ * the run as failed. Use this to verify the agent's claimed output against
129
+ * what was actually executed — the canonical way to catch silent
130
+ * confabulation where a small model says "I created file X" without ever
131
+ * calling the write tool.
132
+ */
133
+ verifyResult?: (result: AgentRunResult) => Promise<AgentRunResult> | AgentRunResult;
134
+ }
135
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/agent/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Public types for the agent runner.
3
+ *
4
+ * Kept separate from the loop so callers can import the surface without
5
+ * pulling in the streaming machinery, and so the type surface is easy to
6
+ * audit at a glance.
7
+ */
8
+ export {};
9
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/agent/types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Backward-compat shim — the agent runner was split into focused modules
3
+ * under `./agent/`. This file re-exports the same public surface so existing
4
+ * imports continue to work.
5
+ *
6
+ * For new code, import from `thread-phase` (or directly from `./agent/*`)
7
+ * rather than this path.
8
+ */
9
+ export { runAgentWithTools, parseJSON, type AgentConfig, type ActivityEntry, type AgentRunResult, type AgentRunnerOptions, type AgentStreamEvent, type FinishReason, type UsageInfo, } from './agent/index.js';
10
+ //# sourceMappingURL=agent-runner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-runner.d.ts","sourceRoot":"","sources":["../src/agent-runner.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EACL,iBAAiB,EACjB,SAAS,EACT,KAAK,WAAW,EAChB,KAAK,aAAa,EAClB,KAAK,cAAc,EACnB,KAAK,kBAAkB,EACvB,KAAK,gBAAgB,EACrB,KAAK,YAAY,EACjB,KAAK,SAAS,GACf,MAAM,kBAAkB,CAAC"}