@studio-foundation/runner 0.3.0-beta.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 (268) hide show
  1. package/ARCHITECTURE.md +53 -0
  2. package/LICENSE +663 -0
  3. package/README.md +125 -0
  4. package/configs/agents/analyst.agent.yaml +31 -0
  5. package/configs/agents/code-generator.agent.yaml +31 -0
  6. package/configs/agents/generic.agent.yaml +23 -0
  7. package/dist/__tests__/script-executor.test.d.ts +2 -0
  8. package/dist/__tests__/script-executor.test.d.ts.map +1 -0
  9. package/dist/__tests__/script-executor.test.js +173 -0
  10. package/dist/__tests__/script-executor.test.js.map +1 -0
  11. package/dist/index.d.ts +38 -0
  12. package/dist/index.d.ts.map +1 -0
  13. package/dist/index.js +76 -0
  14. package/dist/index.js.map +1 -0
  15. package/dist/integrations/integration-loader.d.ts +20 -0
  16. package/dist/integrations/integration-loader.d.ts.map +1 -0
  17. package/dist/integrations/integration-loader.js +71 -0
  18. package/dist/integrations/integration-loader.js.map +1 -0
  19. package/dist/integrations/integration-loader.test.d.ts +2 -0
  20. package/dist/integrations/integration-loader.test.d.ts.map +1 -0
  21. package/dist/integrations/integration-loader.test.js +77 -0
  22. package/dist/integrations/integration-loader.test.js.map +1 -0
  23. package/dist/middleware/anonymization.d.ts +22 -0
  24. package/dist/middleware/anonymization.d.ts.map +1 -0
  25. package/dist/middleware/anonymization.js +37 -0
  26. package/dist/middleware/anonymization.js.map +1 -0
  27. package/dist/plugins/index.d.ts +5 -0
  28. package/dist/plugins/index.d.ts.map +1 -0
  29. package/dist/plugins/index.js +10 -0
  30. package/dist/plugins/index.js.map +1 -0
  31. package/dist/plugins/mcp-client.d.ts +19 -0
  32. package/dist/plugins/mcp-client.d.ts.map +1 -0
  33. package/dist/plugins/mcp-client.js +126 -0
  34. package/dist/plugins/mcp-client.js.map +1 -0
  35. package/dist/plugins/mcp-client.test.d.ts +2 -0
  36. package/dist/plugins/mcp-client.test.d.ts.map +1 -0
  37. package/dist/plugins/mcp-client.test.js +160 -0
  38. package/dist/plugins/mcp-client.test.js.map +1 -0
  39. package/dist/plugins/oauth-provider.d.ts +27 -0
  40. package/dist/plugins/oauth-provider.d.ts.map +1 -0
  41. package/dist/plugins/oauth-provider.js +140 -0
  42. package/dist/plugins/oauth-provider.js.map +1 -0
  43. package/dist/plugins/oauth-provider.test.d.ts +2 -0
  44. package/dist/plugins/oauth-provider.test.d.ts.map +1 -0
  45. package/dist/plugins/oauth-provider.test.js +144 -0
  46. package/dist/plugins/oauth-provider.test.js.map +1 -0
  47. package/dist/plugins/plugin-loader.d.ts +29 -0
  48. package/dist/plugins/plugin-loader.d.ts.map +1 -0
  49. package/dist/plugins/plugin-loader.js +71 -0
  50. package/dist/plugins/plugin-loader.js.map +1 -0
  51. package/dist/plugins/plugin-loader.test.d.ts +2 -0
  52. package/dist/plugins/plugin-loader.test.d.ts.map +1 -0
  53. package/dist/plugins/plugin-loader.test.js +87 -0
  54. package/dist/plugins/plugin-loader.test.js.map +1 -0
  55. package/dist/prompt-builder.d.ts +47 -0
  56. package/dist/prompt-builder.d.ts.map +1 -0
  57. package/dist/prompt-builder.js +263 -0
  58. package/dist/prompt-builder.js.map +1 -0
  59. package/dist/prompt-builder.test.d.ts +2 -0
  60. package/dist/prompt-builder.test.d.ts.map +1 -0
  61. package/dist/prompt-builder.test.js +154 -0
  62. package/dist/prompt-builder.test.js.map +1 -0
  63. package/dist/providers/anthropic.d.ts +14 -0
  64. package/dist/providers/anthropic.d.ts.map +1 -0
  65. package/dist/providers/anthropic.js +118 -0
  66. package/dist/providers/anthropic.js.map +1 -0
  67. package/dist/providers/anthropic.test.d.ts +2 -0
  68. package/dist/providers/anthropic.test.d.ts.map +1 -0
  69. package/dist/providers/anthropic.test.js +76 -0
  70. package/dist/providers/anthropic.test.js.map +1 -0
  71. package/dist/providers/mock.d.ts +17 -0
  72. package/dist/providers/mock.d.ts.map +1 -0
  73. package/dist/providers/mock.js +39 -0
  74. package/dist/providers/mock.js.map +1 -0
  75. package/dist/providers/ollama.d.ts +18 -0
  76. package/dist/providers/ollama.d.ts.map +1 -0
  77. package/dist/providers/ollama.js +155 -0
  78. package/dist/providers/ollama.js.map +1 -0
  79. package/dist/providers/ollama.test.d.ts +2 -0
  80. package/dist/providers/ollama.test.d.ts.map +1 -0
  81. package/dist/providers/ollama.test.js +123 -0
  82. package/dist/providers/ollama.test.js.map +1 -0
  83. package/dist/providers/openai-responses.d.ts +18 -0
  84. package/dist/providers/openai-responses.d.ts.map +1 -0
  85. package/dist/providers/openai-responses.js +175 -0
  86. package/dist/providers/openai-responses.js.map +1 -0
  87. package/dist/providers/openai.d.ts +16 -0
  88. package/dist/providers/openai.d.ts.map +1 -0
  89. package/dist/providers/openai.js +132 -0
  90. package/dist/providers/openai.js.map +1 -0
  91. package/dist/providers/openai.test.d.ts +2 -0
  92. package/dist/providers/openai.test.d.ts.map +1 -0
  93. package/dist/providers/openai.test.js +51 -0
  94. package/dist/providers/openai.test.js.map +1 -0
  95. package/dist/providers/provider.d.ts +42 -0
  96. package/dist/providers/provider.d.ts.map +1 -0
  97. package/dist/providers/provider.js +10 -0
  98. package/dist/providers/provider.js.map +1 -0
  99. package/dist/providers/registry.d.ts +42 -0
  100. package/dist/providers/registry.d.ts.map +1 -0
  101. package/dist/providers/registry.js +65 -0
  102. package/dist/providers/registry.js.map +1 -0
  103. package/dist/runner.d.ts +46 -0
  104. package/dist/runner.d.ts.map +1 -0
  105. package/dist/runner.js +324 -0
  106. package/dist/runner.js.map +1 -0
  107. package/dist/runner.test.d.ts +2 -0
  108. package/dist/runner.test.d.ts.map +1 -0
  109. package/dist/runner.test.js +280 -0
  110. package/dist/runner.test.js.map +1 -0
  111. package/dist/script-executor.d.ts +11 -0
  112. package/dist/script-executor.d.ts.map +1 -0
  113. package/dist/script-executor.js +85 -0
  114. package/dist/script-executor.js.map +1 -0
  115. package/dist/tools/builtin/git.d.ts +6 -0
  116. package/dist/tools/builtin/git.d.ts.map +1 -0
  117. package/dist/tools/builtin/git.js +294 -0
  118. package/dist/tools/builtin/git.js.map +1 -0
  119. package/dist/tools/builtin/patch.d.ts +6 -0
  120. package/dist/tools/builtin/patch.d.ts.map +1 -0
  121. package/dist/tools/builtin/patch.js +238 -0
  122. package/dist/tools/builtin/patch.js.map +1 -0
  123. package/dist/tools/builtin/repo-manager.d.ts +6 -0
  124. package/dist/tools/builtin/repo-manager.d.ts.map +1 -0
  125. package/dist/tools/builtin/repo-manager.js +171 -0
  126. package/dist/tools/builtin/repo-manager.js.map +1 -0
  127. package/dist/tools/builtin/search.d.ts +6 -0
  128. package/dist/tools/builtin/search.d.ts.map +1 -0
  129. package/dist/tools/builtin/search.js +104 -0
  130. package/dist/tools/builtin/search.js.map +1 -0
  131. package/dist/tools/builtin/shell.d.ts +6 -0
  132. package/dist/tools/builtin/shell.d.ts.map +1 -0
  133. package/dist/tools/builtin/shell.js +78 -0
  134. package/dist/tools/builtin/shell.js.map +1 -0
  135. package/dist/tools/builtin/studio-run.d.ts +12 -0
  136. package/dist/tools/builtin/studio-run.d.ts.map +1 -0
  137. package/dist/tools/builtin/studio-run.js +61 -0
  138. package/dist/tools/builtin/studio-run.js.map +1 -0
  139. package/dist/tools/builtin/web-search.d.ts +7 -0
  140. package/dist/tools/builtin/web-search.d.ts.map +1 -0
  141. package/dist/tools/builtin/web-search.js +94 -0
  142. package/dist/tools/builtin/web-search.js.map +1 -0
  143. package/dist/tools/builtin/web-search.test.d.ts +5 -0
  144. package/dist/tools/builtin/web-search.test.d.ts.map +1 -0
  145. package/dist/tools/builtin/web-search.test.js +90 -0
  146. package/dist/tools/builtin/web-search.test.js.map +1 -0
  147. package/dist/tools/errors.d.ts +4 -0
  148. package/dist/tools/errors.d.ts.map +1 -0
  149. package/dist/tools/errors.js +11 -0
  150. package/dist/tools/errors.js.map +1 -0
  151. package/dist/tools/errors.test.d.ts +2 -0
  152. package/dist/tools/errors.test.d.ts.map +1 -0
  153. package/dist/tools/errors.test.js +14 -0
  154. package/dist/tools/errors.test.js.map +1 -0
  155. package/dist/tools/plugin-loader.d.ts +31 -0
  156. package/dist/tools/plugin-loader.d.ts.map +1 -0
  157. package/dist/tools/plugin-loader.js +183 -0
  158. package/dist/tools/plugin-loader.js.map +1 -0
  159. package/dist/tools/plugin-loader.test.d.ts +2 -0
  160. package/dist/tools/plugin-loader.test.d.ts.map +1 -0
  161. package/dist/tools/plugin-loader.test.js +116 -0
  162. package/dist/tools/plugin-loader.test.js.map +1 -0
  163. package/dist/tools/skills/skill-loader.d.ts +23 -0
  164. package/dist/tools/skills/skill-loader.d.ts.map +1 -0
  165. package/dist/tools/skills/skill-loader.js +58 -0
  166. package/dist/tools/skills/skill-loader.js.map +1 -0
  167. package/dist/tools/skills/skill-loader.test.d.ts +2 -0
  168. package/dist/tools/skills/skill-loader.test.d.ts.map +1 -0
  169. package/dist/tools/skills/skill-loader.test.js +92 -0
  170. package/dist/tools/skills/skill-loader.test.js.map +1 -0
  171. package/dist/tools/tool-executor.d.ts +12 -0
  172. package/dist/tools/tool-executor.d.ts.map +1 -0
  173. package/dist/tools/tool-executor.js +76 -0
  174. package/dist/tools/tool-executor.js.map +1 -0
  175. package/dist/tools/tool-executor.test.d.ts +2 -0
  176. package/dist/tools/tool-executor.test.d.ts.map +1 -0
  177. package/dist/tools/tool-executor.test.js +83 -0
  178. package/dist/tools/tool-executor.test.js.map +1 -0
  179. package/dist/tools/tool-registry.d.ts +65 -0
  180. package/dist/tools/tool-registry.d.ts.map +1 -0
  181. package/dist/tools/tool-registry.js +112 -0
  182. package/dist/tools/tool-registry.js.map +1 -0
  183. package/dist/tools/yaml-executor.d.ts +22 -0
  184. package/dist/tools/yaml-executor.d.ts.map +1 -0
  185. package/dist/tools/yaml-executor.js +80 -0
  186. package/dist/tools/yaml-executor.js.map +1 -0
  187. package/dist/utils/race-signal.d.ts +6 -0
  188. package/dist/utils/race-signal.d.ts.map +1 -0
  189. package/dist/utils/race-signal.js +21 -0
  190. package/dist/utils/race-signal.js.map +1 -0
  191. package/dist/utils/race-signal.test.d.ts +2 -0
  192. package/dist/utils/race-signal.test.d.ts.map +1 -0
  193. package/dist/utils/race-signal.test.js +48 -0
  194. package/dist/utils/race-signal.test.js.map +1 -0
  195. package/package.json +36 -0
  196. package/src/__tests__/script-executor.test.ts +180 -0
  197. package/src/index.ts +68 -0
  198. package/src/integrations/integration-loader.test.ts +88 -0
  199. package/src/integrations/integration-loader.ts +68 -0
  200. package/src/middleware/anonymization.ts +38 -0
  201. package/src/plugins/index.ts +4 -0
  202. package/src/plugins/mcp-client.test.ts +148 -0
  203. package/src/plugins/mcp-client.ts +128 -0
  204. package/src/plugins/oauth-provider.test.ts +167 -0
  205. package/src/plugins/oauth-provider.ts +175 -0
  206. package/src/plugins/plugin-loader.test.ts +114 -0
  207. package/src/plugins/plugin-loader.ts +90 -0
  208. package/src/prompt-builder.test.ts +167 -0
  209. package/src/prompt-builder.ts +332 -0
  210. package/src/providers/anthropic.test.ts +101 -0
  211. package/src/providers/anthropic.ts +135 -0
  212. package/src/providers/mock.ts +57 -0
  213. package/src/providers/ollama.test.ts +166 -0
  214. package/src/providers/ollama.ts +152 -0
  215. package/src/providers/openai-responses.ts +212 -0
  216. package/src/providers/openai.test.ts +67 -0
  217. package/src/providers/openai.ts +139 -0
  218. package/src/providers/provider.ts +54 -0
  219. package/src/providers/registry.ts +77 -0
  220. package/src/runner.test.ts +343 -0
  221. package/src/runner.ts +396 -0
  222. package/src/script-executor.ts +107 -0
  223. package/src/tools/builtin/git.ts +311 -0
  224. package/src/tools/builtin/patch.ts +257 -0
  225. package/src/tools/builtin/repo-manager.ts +142 -0
  226. package/src/tools/builtin/search.ts +108 -0
  227. package/src/tools/builtin/shell.ts +82 -0
  228. package/src/tools/builtin/studio-run.ts +73 -0
  229. package/src/tools/builtin/web-search.test.ts +122 -0
  230. package/src/tools/builtin/web-search.ts +101 -0
  231. package/src/tools/errors.test.ts +12 -0
  232. package/src/tools/errors.ts +6 -0
  233. package/src/tools/plugin-loader.test.ts +130 -0
  234. package/src/tools/plugin-loader.ts +203 -0
  235. package/src/tools/skills/README.md +49 -0
  236. package/src/tools/skills/skill-loader.test.ts +106 -0
  237. package/src/tools/skills/skill-loader.ts +62 -0
  238. package/src/tools/tool-executor.test.ts +88 -0
  239. package/src/tools/tool-executor.ts +84 -0
  240. package/src/tools/tool-registry.ts +130 -0
  241. package/src/tools/yaml-executor.ts +120 -0
  242. package/src/utils/race-signal.test.ts +50 -0
  243. package/src/utils/race-signal.ts +17 -0
  244. package/templates/integrations/linear.integration.yaml +35 -0
  245. package/templates/integrations/slack.integration.yaml +22 -0
  246. package/templates/integrations/webhook.integration.yaml +17 -0
  247. package/templates/tools/git.tool.yaml +80 -0
  248. package/templates/tools/repo-manager.tool.yaml +64 -0
  249. package/templates/tools/search.tool.yaml +22 -0
  250. package/templates/tools/shell.tool.yaml +19 -0
  251. package/templates/tools/web-search.tool.yaml +24 -0
  252. package/tests/anonymization-middleware.test.ts +61 -0
  253. package/tests/anthropic.test.ts +87 -0
  254. package/tests/apply-patch.test.ts +355 -0
  255. package/tests/fixtures/tools/test-builtin.tool.yaml +14 -0
  256. package/tests/fixtures/tools/test-shell.tool.yaml +19 -0
  257. package/tests/mock-provider.test.ts +104 -0
  258. package/tests/openai.test.ts +72 -0
  259. package/tests/plugin-loader.test.ts +54 -0
  260. package/tests/prompt-builder.test.ts +468 -0
  261. package/tests/runner-anonymization.test.ts +89 -0
  262. package/tests/runner.test.ts +885 -0
  263. package/tests/studio-run.test.ts +94 -0
  264. package/tests/tool-executor.test.ts +115 -0
  265. package/tests/tool-registry.test.ts +84 -0
  266. package/tests/yaml-executor.test.ts +76 -0
  267. package/tsconfig.json +20 -0
  268. package/vitest.config.ts +7 -0
@@ -0,0 +1,175 @@
1
+ "use strict";
2
+ /**
3
+ * OpenAI Responses API provider — supports models only available on /v1/responses
4
+ * (e.g. gpt-5.1-codex-mini).
5
+ *
6
+ * Implements AgentLoopProvider to own the multi-turn tool-calling loop,
7
+ * because the Responses API uses typed function_call / function_call_output
8
+ * items that cannot be expressed as plain text messages.
9
+ */
10
+ var __importDefault = (this && this.__importDefault) || function (mod) {
11
+ return (mod && mod.__esModule) ? mod : { "default": mod };
12
+ };
13
+ Object.defineProperty(exports, "__esModule", { value: true });
14
+ exports.OpenAIResponsesProvider = void 0;
15
+ const openai_1 = __importDefault(require("openai"));
16
+ class OpenAIResponsesProvider {
17
+ name = 'openai-responses';
18
+ client;
19
+ constructor(apiKey) {
20
+ this.client = new openai_1.default({ apiKey: apiKey || process.env.OPENAI_API_KEY });
21
+ }
22
+ // Satisfy Provider interface for simple (no-tool) calls
23
+ async call(request, _onToken, signal) {
24
+ const input = messagesToInput(request.messages);
25
+ const response = await this.client.responses.create({
26
+ model: request.model,
27
+ input,
28
+ temperature: request.temperature,
29
+ max_output_tokens: request.max_tokens ?? undefined,
30
+ }, { signal });
31
+ // NOTE: call() is for tool-free requests only.
32
+ // Tool calls in the response are intentionally discarded.
33
+ // For agentic tool-calling, use runAgentLoop() instead.
34
+ return {
35
+ content: response.output_text ?? '',
36
+ tool_calls: [],
37
+ finish_reason: 'stop',
38
+ usage: response.usage
39
+ ? {
40
+ prompt_tokens: response.usage.input_tokens,
41
+ completion_tokens: response.usage.output_tokens,
42
+ total_tokens: response.usage.total_tokens,
43
+ }
44
+ : undefined,
45
+ };
46
+ }
47
+ async runAgentLoop(request, executeTool, onToken, signal) {
48
+ const tools = (request.tools ?? []).map(t => ({
49
+ type: 'function',
50
+ name: t.name,
51
+ description: t.description ?? null,
52
+ parameters: t.parameters,
53
+ strict: null,
54
+ }));
55
+ let input = messagesToInput(request.messages);
56
+ const allToolCalls = [];
57
+ const tokenAccumulator = { prompt_tokens: 0, completion_tokens: 0, total_tokens: 0 };
58
+ const MAX_ITERATIONS = 20;
59
+ for (let i = 0; i < MAX_ITERATIONS; i++) {
60
+ if (signal?.aborted) {
61
+ throw new DOMException('The operation was aborted', 'AbortError');
62
+ }
63
+ let outputItems;
64
+ let responseText = '';
65
+ if (onToken) {
66
+ // Streaming path — emit text deltas as they arrive, then get the completed response
67
+ const stream = this.client.responses.stream({
68
+ model: request.model,
69
+ input,
70
+ tools: tools.length > 0 ? tools : undefined,
71
+ temperature: request.temperature,
72
+ max_output_tokens: request.max_tokens ?? undefined,
73
+ });
74
+ for await (const event of stream) {
75
+ if (event.type === 'response.output_text.delta') {
76
+ onToken(event.delta);
77
+ responseText += event.delta;
78
+ }
79
+ }
80
+ const finalResponse = await stream.finalResponse();
81
+ if (finalResponse.usage) {
82
+ tokenAccumulator.prompt_tokens += finalResponse.usage.input_tokens;
83
+ tokenAccumulator.completion_tokens += finalResponse.usage.output_tokens;
84
+ tokenAccumulator.total_tokens += finalResponse.usage.total_tokens;
85
+ }
86
+ outputItems = finalResponse.output;
87
+ // Find all function calls in the output
88
+ const functionCalls = outputItems.filter((item) => item.type === 'function_call');
89
+ if (functionCalls.length === 0) {
90
+ // No tool calls — done
91
+ return {
92
+ content: responseText,
93
+ tool_calls: allToolCalls,
94
+ finish_reason: 'stop',
95
+ usage: tokenAccumulator.total_tokens > 0 ? tokenAccumulator : undefined,
96
+ };
97
+ }
98
+ // Execute all tool calls
99
+ const toolOutputs = [];
100
+ for (const fc of functionCalls) {
101
+ const args = JSON.parse(fc.arguments);
102
+ const outcome = await executeTool(fc.name, args, fc.call_id);
103
+ allToolCalls.push({ id: fc.call_id, name: fc.name, arguments: args, ...outcome });
104
+ toolOutputs.push({
105
+ type: 'function_call_output',
106
+ call_id: fc.call_id,
107
+ output: outcome.error ? `Error: ${outcome.error}` : JSON.stringify(outcome.result),
108
+ });
109
+ }
110
+ // Extend input: previous input + this response's output items + tool results
111
+ // ResponseOutputItem is a subset of the ResponseInputItem union, so the cast is safe
112
+ input = [
113
+ ...input,
114
+ ...outputItems,
115
+ ...toolOutputs,
116
+ ];
117
+ }
118
+ else {
119
+ // Non-streaming path
120
+ const response = await this.client.responses.create({
121
+ model: request.model,
122
+ input,
123
+ tools: tools.length > 0 ? tools : undefined,
124
+ temperature: request.temperature,
125
+ max_output_tokens: request.max_tokens ?? undefined,
126
+ }, { signal });
127
+ if (response.usage) {
128
+ tokenAccumulator.prompt_tokens += response.usage.input_tokens;
129
+ tokenAccumulator.completion_tokens += response.usage.output_tokens;
130
+ tokenAccumulator.total_tokens += response.usage.total_tokens;
131
+ }
132
+ // Find all function calls in the output
133
+ const functionCalls = response.output.filter((item) => item.type === 'function_call');
134
+ if (functionCalls.length === 0) {
135
+ // No tool calls — done
136
+ return {
137
+ content: response.output_text ?? '',
138
+ tool_calls: allToolCalls,
139
+ finish_reason: 'stop',
140
+ usage: tokenAccumulator.total_tokens > 0 ? tokenAccumulator : undefined,
141
+ };
142
+ }
143
+ // Execute all tool calls
144
+ const toolOutputs = [];
145
+ for (const fc of functionCalls) {
146
+ const args = JSON.parse(fc.arguments);
147
+ const outcome = await executeTool(fc.name, args, fc.call_id);
148
+ allToolCalls.push({ id: fc.call_id, name: fc.name, arguments: args, ...outcome });
149
+ toolOutputs.push({
150
+ type: 'function_call_output',
151
+ call_id: fc.call_id,
152
+ output: outcome.error ? `Error: ${outcome.error}` : JSON.stringify(outcome.result),
153
+ });
154
+ }
155
+ // Extend input: previous input + this response's output items + tool results
156
+ // ResponseOutputItem is a subset of the ResponseInputItem union, so the cast is safe
157
+ input = [
158
+ ...input,
159
+ ...response.output,
160
+ ...toolOutputs,
161
+ ];
162
+ }
163
+ }
164
+ throw new Error(`Maximum tool calling iterations (${MAX_ITERATIONS}) reached.`);
165
+ }
166
+ }
167
+ exports.OpenAIResponsesProvider = OpenAIResponsesProvider;
168
+ function messagesToInput(messages) {
169
+ return messages.map(msg => ({
170
+ type: 'message',
171
+ role: msg.role,
172
+ content: msg.content,
173
+ }));
174
+ }
175
+ //# sourceMappingURL=openai-responses.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openai-responses.js","sourceRoot":"","sources":["../../src/providers/openai-responses.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * OpenAI provider implementation with full tool calling support
3
+ */
4
+ import type { LLMRequest, LLMResponse } from '@studio-foundation/contracts';
5
+ import type { Provider } from './provider.js';
6
+ export declare class OpenAIProvider implements Provider {
7
+ private baseUrl?;
8
+ readonly name = "openai";
9
+ private client;
10
+ constructor(apiKey?: string, baseUrl?: string | undefined);
11
+ call(request: LLMRequest, onToken?: (token: string) => void, signal?: AbortSignal): Promise<LLMResponse>;
12
+ private callStreaming;
13
+ private buildMessages;
14
+ private buildTools;
15
+ }
16
+ //# sourceMappingURL=openai.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openai.d.ts","sourceRoot":"","sources":["../../src/providers/openai.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAC5E,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAI9C,qBAAa,cAAe,YAAW,QAAQ;IAIhB,OAAO,CAAC,OAAO,CAAC;IAH7C,QAAQ,CAAC,IAAI,YAAY;IACzB,OAAO,CAAC,MAAM,CAAS;gBAEX,MAAM,CAAC,EAAE,MAAM,EAAU,OAAO,CAAC,EAAE,MAAM,YAAA;IAO/C,IAAI,CAAC,OAAO,EAAE,UAAU,EAAE,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC;YAsChG,aAAa;IA6D3B,OAAO,CAAC,aAAa;IASrB,OAAO,CAAC,UAAU;CAUnB"}
@@ -0,0 +1,132 @@
1
+ "use strict";
2
+ /**
3
+ * OpenAI provider implementation with full tool calling support
4
+ */
5
+ var __importDefault = (this && this.__importDefault) || function (mod) {
6
+ return (mod && mod.__esModule) ? mod : { "default": mod };
7
+ };
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.OpenAIProvider = void 0;
10
+ const openai_1 = __importDefault(require("openai"));
11
+ class OpenAIProvider {
12
+ baseUrl;
13
+ name = 'openai';
14
+ client;
15
+ constructor(apiKey, baseUrl) {
16
+ this.baseUrl = baseUrl;
17
+ this.client = new openai_1.default({
18
+ apiKey: apiKey || process.env.OPENAI_API_KEY,
19
+ baseURL: baseUrl
20
+ });
21
+ }
22
+ async call(request, onToken, signal) {
23
+ const openaiMessages = this.buildMessages(request);
24
+ const tools = this.buildTools(request);
25
+ if (onToken) {
26
+ return this.callStreaming(request, openaiMessages, tools, onToken, signal);
27
+ }
28
+ // Non-streaming path (existing behavior)
29
+ const completion = await this.client.chat.completions.create({
30
+ model: request.model,
31
+ messages: openaiMessages,
32
+ tools: tools && tools.length > 0 ? tools : undefined,
33
+ temperature: request.temperature,
34
+ max_completion_tokens: request.max_tokens
35
+ }, { signal });
36
+ const choice = completion.choices[0];
37
+ // Extract tool calls if any
38
+ const tool_calls = choice.message.tool_calls?.map(tc => ({
39
+ id: tc.id,
40
+ name: tc.function.name,
41
+ arguments: JSON.parse(tc.function.arguments)
42
+ })) || [];
43
+ return {
44
+ content: choice.message.content || '',
45
+ tool_calls,
46
+ finish_reason: choice.finish_reason,
47
+ usage: {
48
+ prompt_tokens: completion.usage?.prompt_tokens || 0,
49
+ completion_tokens: completion.usage?.completion_tokens || 0,
50
+ total_tokens: completion.usage?.total_tokens || 0
51
+ }
52
+ };
53
+ }
54
+ async callStreaming(request, openaiMessages, tools, onToken, signal) {
55
+ const stream = this.client.chat.completions.create({
56
+ model: request.model,
57
+ messages: openaiMessages,
58
+ tools: tools && tools.length > 0 ? tools : undefined,
59
+ temperature: request.temperature,
60
+ max_completion_tokens: request.max_tokens,
61
+ stream: true,
62
+ stream_options: { include_usage: true },
63
+ }, { signal });
64
+ let textContent = '';
65
+ const toolCallMap = new Map();
66
+ let finishReason = 'stop';
67
+ let usage;
68
+ for await (const chunk of stream) {
69
+ // KEY FIX: check signal at the start of each chunk so we don't keep
70
+ // consuming buffered data after Ctrl-C.
71
+ if (signal?.aborted)
72
+ throw new DOMException('Aborted', 'AbortError');
73
+ const delta = chunk.choices[0]?.delta;
74
+ if (delta?.content) {
75
+ textContent += delta.content;
76
+ onToken(delta.content);
77
+ }
78
+ if (delta?.tool_calls) {
79
+ for (const tc of delta.tool_calls) {
80
+ if (!toolCallMap.has(tc.index)) {
81
+ toolCallMap.set(tc.index, { id: '', name: '', args: '' });
82
+ }
83
+ const acc = toolCallMap.get(tc.index);
84
+ if (tc.id)
85
+ acc.id = tc.id;
86
+ if (tc.function?.name)
87
+ acc.name += tc.function.name;
88
+ if (tc.function?.arguments)
89
+ acc.args += tc.function.arguments;
90
+ }
91
+ }
92
+ if (chunk.choices[0]?.finish_reason)
93
+ finishReason = chunk.choices[0].finish_reason;
94
+ if (chunk.usage) {
95
+ usage = {
96
+ prompt_tokens: chunk.usage.prompt_tokens,
97
+ completion_tokens: chunk.usage.completion_tokens,
98
+ total_tokens: chunk.usage.total_tokens,
99
+ };
100
+ }
101
+ }
102
+ const tool_calls = Array.from(toolCallMap.values()).map(tc => ({
103
+ id: tc.id,
104
+ name: tc.name,
105
+ arguments: JSON.parse(tc.args || '{}'),
106
+ }));
107
+ return { content: textContent, tool_calls, finish_reason: finishReason, usage };
108
+ }
109
+ buildMessages(request) {
110
+ return request.messages.map(msg => {
111
+ if (msg.role === 'system')
112
+ return { role: 'system', content: msg.content };
113
+ if (msg.role === 'user')
114
+ return { role: 'user', content: msg.content };
115
+ if (msg.role === 'assistant')
116
+ return { role: 'assistant', content: msg.content };
117
+ throw new Error(`Unsupported message role: ${msg.role}`);
118
+ });
119
+ }
120
+ buildTools(request) {
121
+ return request.tools?.map(tool => ({
122
+ type: 'function',
123
+ function: {
124
+ name: tool.name,
125
+ description: tool.description,
126
+ parameters: tool.parameters
127
+ }
128
+ }));
129
+ }
130
+ }
131
+ exports.OpenAIProvider = OpenAIProvider;
132
+ //# sourceMappingURL=openai.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openai.js","sourceRoot":"","sources":["../../src/providers/openai.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=openai.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openai.test.d.ts","sourceRoot":"","sources":["../../src/providers/openai.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const vitest_1 = require("vitest");
4
+ const openai_js_1 = require("./openai.js");
5
+ // Fake async iterable that yields chunks with a delay between each,
6
+ // simulating a slow stream that should be interruptible.
7
+ async function* slowStream(chunks, delayMs = 10) {
8
+ for (const chunk of chunks) {
9
+ await new Promise((r) => setTimeout(r, delayMs));
10
+ yield chunk;
11
+ }
12
+ }
13
+ vitest_1.vi.mock('openai', () => {
14
+ return {
15
+ default: class FakeOpenAI {
16
+ chat = {
17
+ completions: {
18
+ create: (_params, _opts) => slowStream([
19
+ { choices: [{ delta: { content: 'hello' }, finish_reason: null }] },
20
+ { choices: [{ delta: { content: ' world' }, finish_reason: 'stop' }] },
21
+ ]),
22
+ },
23
+ };
24
+ },
25
+ };
26
+ });
27
+ (0, vitest_1.describe)('OpenAIProvider', () => {
28
+ (0, vitest_1.it)('aborts streaming when signal fires mid-iteration', async () => {
29
+ const provider = new openai_js_1.OpenAIProvider('test-key');
30
+ const controller = new AbortController();
31
+ const onToken = vitest_1.vi.fn();
32
+ const callPromise = provider.call({
33
+ model: 'gpt-4o',
34
+ messages: [{ role: 'user', content: 'hi' }],
35
+ }, onToken, controller.signal);
36
+ // Abort after first chunk has a chance to arrive
37
+ setTimeout(() => controller.abort(), 5);
38
+ await (0, vitest_1.expect)(callPromise).rejects.toSatisfy((e) => e instanceof DOMException && e.name === 'AbortError');
39
+ });
40
+ (0, vitest_1.it)('completes normally when signal is not aborted', async () => {
41
+ const provider = new openai_js_1.OpenAIProvider('test-key');
42
+ const onToken = vitest_1.vi.fn();
43
+ const result = await provider.call({
44
+ model: 'gpt-4o',
45
+ messages: [{ role: 'user', content: 'hi' }],
46
+ }, onToken);
47
+ (0, vitest_1.expect)(result.content).toBe('hello world');
48
+ (0, vitest_1.expect)(onToken).toHaveBeenCalledTimes(2);
49
+ });
50
+ });
51
+ //# sourceMappingURL=openai.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openai.test.js","sourceRoot":"","sources":["../../src/providers/openai.test.ts"],"names":[],"mappings":";;AAAA,mCAAkD;AAClD,2CAA6C;AAE7C,oEAAoE;AACpE,yDAAyD;AACzD,KAAK,SAAS,CAAC,CAAC,UAAU,CAAC,MAAiB,EAAE,OAAO,GAAG,EAAE;IACxD,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC;QACjD,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC;AAED,WAAE,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,EAAE;IACrB,OAAO;QACL,OAAO,EAAE,MAAM,UAAU;YACvB,IAAI,GAAG;gBACL,WAAW,EAAE;oBACX,MAAM,EAAE,CAAC,OAAgB,EAAE,KAA+B,EAAE,EAAE,CAC5D,UAAU,CAAC;wBACT,EAAE,OAAO,EAAE,CAAC,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,EAAE;wBACnE,EAAE,OAAO,EAAE,CAAC,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,aAAa,EAAE,MAAM,EAAE,CAAC,EAAE;qBACvE,CAAC;iBACL;aACF,CAAC;SACH;KACF,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,IAAA,iBAAQ,EAAC,gBAAgB,EAAE,GAAG,EAAE;IAC9B,IAAA,WAAE,EAAC,kDAAkD,EAAE,KAAK,IAAI,EAAE;QAChE,MAAM,QAAQ,GAAG,IAAI,0BAAc,CAAC,UAAU,CAAC,CAAC;QAChD,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;QACzC,MAAM,OAAO,GAAG,WAAE,CAAC,EAAE,EAAE,CAAC;QAExB,MAAM,WAAW,GAAG,QAAQ,CAAC,IAAI,CAC/B;YACE,KAAK,EAAE,QAAQ;YACf,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;SAC5C,EACD,OAAO,EACP,UAAU,CAAC,MAAM,CAClB,CAAC;QAEF,iDAAiD;QACjD,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC;QAExC,MAAM,IAAA,eAAM,EAAC,WAAW,CAAC,CAAC,OAAO,CAAC,SAAS,CACzC,CAAC,CAAU,EAAE,EAAE,CAAC,CAAC,YAAY,YAAY,IAAK,CAAkB,CAAC,IAAI,KAAK,YAAY,CACvF,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,+CAA+C,EAAE,KAAK,IAAI,EAAE;QAC7D,MAAM,QAAQ,GAAG,IAAI,0BAAc,CAAC,UAAU,CAAC,CAAC;QAChD,MAAM,OAAO,GAAG,WAAE,CAAC,EAAE,EAAE,CAAC;QAExB,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,IAAI,CAChC;YACE,KAAK,EAAE,QAAQ;YACf,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;SAC5C,EACD,OAAO,CACR,CAAC;QAEF,IAAA,eAAM,EAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QAC3C,IAAA,eAAM,EAAC,OAAO,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;IAC3C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Provider interface - aligned with @studio/contracts
3
+ */
4
+ import type { LLMRequest, LLMResponse } from '@studio-foundation/contracts';
5
+ export interface Provider {
6
+ readonly name: string;
7
+ call(request: LLMRequest, onToken?: (token: string) => void, signal?: AbortSignal): Promise<LLMResponse>;
8
+ }
9
+ export interface ToolCallOutcome {
10
+ result?: unknown;
11
+ error?: string;
12
+ }
13
+ /**
14
+ * Extended interface for providers that own the full agent loop.
15
+ * Used by providers (e.g. OpenAI Responses API) where multi-turn
16
+ * tool calling cannot be expressed as plain text messages.
17
+ */
18
+ export interface AgentLoopProvider extends Provider {
19
+ runAgentLoop(request: LLMRequest, executeTool: (name: string, args: Record<string, unknown>, callId: string) => Promise<ToolCallOutcome>, onToken?: (token: string) => void, signal?: AbortSignal): Promise<AgentLoopResult>;
20
+ }
21
+ /**
22
+ * Full result of an agent loop execution.
23
+ * Distinct from LLMResponse (in @studio/contracts) because it includes
24
+ * per-tool-call execution outcomes (result/error) that are only known
25
+ * after the runner has actually invoked each tool.
26
+ */
27
+ export interface AgentLoopResult {
28
+ content: string;
29
+ tool_calls: Array<{
30
+ id: string;
31
+ name: string;
32
+ arguments: Record<string, unknown>;
33
+ } & ToolCallOutcome>;
34
+ finish_reason: string;
35
+ usage?: {
36
+ prompt_tokens: number;
37
+ completion_tokens: number;
38
+ total_tokens: number;
39
+ };
40
+ }
41
+ export declare function isAgentLoopProvider(p: Provider): p is AgentLoopProvider;
42
+ //# sourceMappingURL=provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../../src/providers/provider.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAE5E,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,IAAI,CAAC,OAAO,EAAE,UAAU,EAAE,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;CAC1G;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;GAIG;AACH,MAAM,WAAW,iBAAkB,SAAQ,QAAQ;IACjD,YAAY,CACV,OAAO,EAAE,UAAU,EACnB,WAAW,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,eAAe,CAAC,EACtG,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,EACjC,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,eAAe,CAAC,CAAC;CAC7B;AAED;;;;;GAKG;AACH,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,KAAK,CAAC;QAChB,EAAE,EAAE,MAAM,CAAC;QACX,IAAI,EAAE,MAAM,CAAC;QACb,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;KACpC,GAAG,eAAe,CAAC,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE;QACN,aAAa,EAAE,MAAM,CAAC;QACtB,iBAAiB,EAAE,MAAM,CAAC;QAC1B,YAAY,EAAE,MAAM,CAAC;KACtB,CAAC;CACH;AAED,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,QAAQ,GAAG,CAAC,IAAI,iBAAiB,CAEvE"}
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ /**
3
+ * Provider interface - aligned with @studio/contracts
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.isAgentLoopProvider = isAgentLoopProvider;
7
+ function isAgentLoopProvider(p) {
8
+ return typeof p.runAgentLoop === 'function';
9
+ }
10
+ //# sourceMappingURL=provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider.js","sourceRoot":"","sources":["../../src/providers/provider.ts"],"names":[],"mappings":";AAAA;;GAEG;;AAiDH,kDAEC;AAFD,SAAgB,mBAAmB,CAAC,CAAW;IAC7C,OAAO,OAAQ,CAAuB,CAAC,YAAY,KAAK,UAAU,CAAC;AACrE,CAAC"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Provider registry - factory for LLM providers
3
+ */
4
+ import type { Provider } from './provider.js';
5
+ export declare class ProviderRegistry {
6
+ private providers;
7
+ /**
8
+ * Register a provider instance
9
+ */
10
+ register(provider: Provider): void;
11
+ /**
12
+ * Get provider by name
13
+ */
14
+ get(name: string): Provider;
15
+ /**
16
+ * Check if provider exists
17
+ */
18
+ has(name: string): boolean;
19
+ /**
20
+ * List available provider names
21
+ */
22
+ list(): string[];
23
+ }
24
+ /**
25
+ * Factory function to create a registry with default providers
26
+ */
27
+ export declare function createDefaultRegistry(config: {
28
+ openai?: {
29
+ apiKey: string;
30
+ baseUrl?: string;
31
+ };
32
+ anthropic?: {
33
+ apiKey: string;
34
+ };
35
+ openaiResponses?: {
36
+ apiKey: string;
37
+ };
38
+ ollama?: {
39
+ baseUrl?: string;
40
+ };
41
+ }): ProviderRegistry;
42
+ //# sourceMappingURL=registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/providers/registry.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAM9C,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,SAAS,CAAoC;IAErD;;OAEG;IACH,QAAQ,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI;IAIlC;;OAEG;IACH,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ;IAU3B;;OAEG;IACH,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAI1B;;OAEG;IACH,IAAI,IAAI,MAAM,EAAE;CAGjB;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE;IAC5C,MAAM,CAAC,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC9C,SAAS,CAAC,EAAE;QAAE,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAC/B,eAAe,CAAC,EAAE;QAAE,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IACrC,MAAM,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CAC/B,GAAG,gBAAgB,CAoBnB"}
@@ -0,0 +1,65 @@
1
+ "use strict";
2
+ /**
3
+ * Provider registry - factory for LLM providers
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.ProviderRegistry = void 0;
7
+ exports.createDefaultRegistry = createDefaultRegistry;
8
+ const openai_js_1 = require("./openai.js");
9
+ const anthropic_js_1 = require("./anthropic.js");
10
+ const openai_responses_js_1 = require("./openai-responses.js");
11
+ const ollama_js_1 = require("./ollama.js");
12
+ class ProviderRegistry {
13
+ providers = new Map();
14
+ /**
15
+ * Register a provider instance
16
+ */
17
+ register(provider) {
18
+ this.providers.set(provider.name, provider);
19
+ }
20
+ /**
21
+ * Get provider by name
22
+ */
23
+ get(name) {
24
+ const provider = this.providers.get(name);
25
+ if (!provider) {
26
+ const available = this.list();
27
+ const detail = available.length > 0 ? available.join(', ') : '(none registered)';
28
+ throw new Error(`Provider not found: ${name}. Available providers: ${detail}`);
29
+ }
30
+ return provider;
31
+ }
32
+ /**
33
+ * Check if provider exists
34
+ */
35
+ has(name) {
36
+ return this.providers.has(name);
37
+ }
38
+ /**
39
+ * List available provider names
40
+ */
41
+ list() {
42
+ return Array.from(this.providers.keys());
43
+ }
44
+ }
45
+ exports.ProviderRegistry = ProviderRegistry;
46
+ /**
47
+ * Factory function to create a registry with default providers
48
+ */
49
+ function createDefaultRegistry(config) {
50
+ const registry = new ProviderRegistry();
51
+ if (config.openai) {
52
+ registry.register(new openai_js_1.OpenAIProvider(config.openai.apiKey, config.openai.baseUrl));
53
+ }
54
+ if (config.anthropic) {
55
+ registry.register(new anthropic_js_1.AnthropicProvider(config.anthropic.apiKey));
56
+ }
57
+ if (config.openaiResponses) {
58
+ registry.register(new openai_responses_js_1.OpenAIResponsesProvider(config.openaiResponses.apiKey));
59
+ }
60
+ if (config.ollama) {
61
+ registry.register(new ollama_js_1.OllamaProvider(config.ollama.baseUrl));
62
+ }
63
+ return registry;
64
+ }
65
+ //# sourceMappingURL=registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/providers/registry.ts"],"names":[],"mappings":";AAAA;;GAEG;;;AAiDH,sDAyBC;AAvED,2CAA6C;AAC7C,iDAAmD;AACnD,+DAAgE;AAChE,2CAA6C;AAE7C,MAAa,gBAAgB;IACnB,SAAS,GAA0B,IAAI,GAAG,EAAE,CAAC;IAErD;;OAEG;IACH,QAAQ,CAAC,QAAkB;QACzB,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;IAC9C,CAAC;IAED;;OAEG;IACH,GAAG,CAAC,IAAY;QACd,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC1C,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;YAC9B,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,mBAAmB,CAAC;YACjF,MAAM,IAAI,KAAK,CAAC,uBAAuB,IAAI,0BAA0B,MAAM,EAAE,CAAC,CAAC;QACjF,CAAC;QACD,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED;;OAEG;IACH,GAAG,CAAC,IAAY;QACd,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAClC,CAAC;IAED;;OAEG;IACH,IAAI;QACF,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC;IAC3C,CAAC;CACF;AApCD,4CAoCC;AAED;;GAEG;AACH,SAAgB,qBAAqB,CAAC,MAKrC;IACC,MAAM,QAAQ,GAAG,IAAI,gBAAgB,EAAE,CAAC;IAExC,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;QAClB,QAAQ,CAAC,QAAQ,CAAC,IAAI,0BAAc,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;IACrF,CAAC;IAED,IAAI,MAAM,CAAC,SAAS,EAAE,CAAC;QACrB,QAAQ,CAAC,QAAQ,CAAC,IAAI,gCAAiB,CAAC,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC;IACpE,CAAC;IAED,IAAI,MAAM,CAAC,eAAe,EAAE,CAAC;QAC3B,QAAQ,CAAC,QAAQ,CAAC,IAAI,6CAAuB,CAAC,MAAM,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,CAAC;IAChF,CAAC;IAED,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;QAClB,QAAQ,CAAC,QAAQ,CAAC,IAAI,0BAAc,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;IAC/D,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC"}
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Main agent runner function - executes agent with LLM + tools
3
+ */
4
+ import type { ResolvedAgentConfig, ToolCall, LLMResponse, OutputContract, RunnerCallbacks } from '@studio-foundation/contracts';
5
+ import { type TaskInput, type AgentContext, type ExecutionContext } from './prompt-builder.js';
6
+ import type { ToolRegistry } from './tools/tool-registry.js';
7
+ import type { ProviderRegistry } from './providers/registry.js';
8
+ import type { AnonymizationMiddleware } from './middleware/anonymization.js';
9
+ export interface RunAgentConfig {
10
+ agent: ResolvedAgentConfig;
11
+ task: TaskInput;
12
+ context: AgentContext;
13
+ executionContext?: ExecutionContext;
14
+ toolRegistry: ToolRegistry;
15
+ providerRegistry: ProviderRegistry;
16
+ outputContract?: OutputContract;
17
+ maxToolCalls?: number;
18
+ anonymizationMiddleware?: AnonymizationMiddleware;
19
+ callbacks?: RunnerCallbacks;
20
+ signal?: AbortSignal;
21
+ }
22
+ export interface AgentRunResult {
23
+ output: unknown;
24
+ tool_calls: ToolCall[];
25
+ tool_calls_count: number;
26
+ raw_response?: LLMResponse;
27
+ duration_ms: number;
28
+ token_usage?: {
29
+ prompt_tokens: number;
30
+ completion_tokens: number;
31
+ total_tokens: number;
32
+ };
33
+ /** Set when the runner hit a terminal error (e.g. max tool iterations). RALPH treats this as a validation failure. */
34
+ error?: string;
35
+ }
36
+ /**
37
+ * Run an agent task with LLM + tool execution
38
+ *
39
+ * Flow:
40
+ * 1. Build prompt with context + retry info
41
+ * 2. Call LLM provider
42
+ * 3. Execute tool calls (multi-turn loop)
43
+ * 4. Return complete result with tracked tool calls
44
+ */
45
+ export declare function runAgent(config: RunAgentConfig): Promise<AgentRunResult>;
46
+ //# sourceMappingURL=runner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../src/runner.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,QAAQ,EAAE,WAAW,EAAW,cAAc,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AACzI,OAAO,EAAe,KAAK,SAAS,EAAE,KAAK,YAAY,EAAE,KAAK,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAC5G,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAE7D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAEhE,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,+BAA+B,CAAC;AAE7E,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,mBAAmB,CAAC;IAC3B,IAAI,EAAE,SAAS,CAAC;IAChB,OAAO,EAAE,YAAY,CAAC;IACtB,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IACpC,YAAY,EAAE,YAAY,CAAC;IAC3B,gBAAgB,EAAE,gBAAgB,CAAC;IACnC,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,uBAAuB,CAAC,EAAE,uBAAuB,CAAC;IAClD,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,OAAO,CAAC;IAChB,UAAU,EAAE,QAAQ,EAAE,CAAC;IACvB,gBAAgB,EAAE,MAAM,CAAC;IACzB,YAAY,CAAC,EAAE,WAAW,CAAC;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE;QACZ,aAAa,EAAE,MAAM,CAAC;QACtB,iBAAiB,EAAE,MAAM,CAAC;QAC1B,YAAY,EAAE,MAAM,CAAC;KACtB,CAAC;IACF,sHAAsH;IACtH,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAID;;;;;;;;GAQG;AACH,wBAAsB,QAAQ,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,cAAc,CAAC,CA6T9E"}