@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.
- package/ARCHITECTURE.md +53 -0
- package/LICENSE +663 -0
- package/README.md +125 -0
- package/configs/agents/analyst.agent.yaml +31 -0
- package/configs/agents/code-generator.agent.yaml +31 -0
- package/configs/agents/generic.agent.yaml +23 -0
- package/dist/__tests__/script-executor.test.d.ts +2 -0
- package/dist/__tests__/script-executor.test.d.ts.map +1 -0
- package/dist/__tests__/script-executor.test.js +173 -0
- package/dist/__tests__/script-executor.test.js.map +1 -0
- package/dist/index.d.ts +38 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +76 -0
- package/dist/index.js.map +1 -0
- package/dist/integrations/integration-loader.d.ts +20 -0
- package/dist/integrations/integration-loader.d.ts.map +1 -0
- package/dist/integrations/integration-loader.js +71 -0
- package/dist/integrations/integration-loader.js.map +1 -0
- package/dist/integrations/integration-loader.test.d.ts +2 -0
- package/dist/integrations/integration-loader.test.d.ts.map +1 -0
- package/dist/integrations/integration-loader.test.js +77 -0
- package/dist/integrations/integration-loader.test.js.map +1 -0
- package/dist/middleware/anonymization.d.ts +22 -0
- package/dist/middleware/anonymization.d.ts.map +1 -0
- package/dist/middleware/anonymization.js +37 -0
- package/dist/middleware/anonymization.js.map +1 -0
- package/dist/plugins/index.d.ts +5 -0
- package/dist/plugins/index.d.ts.map +1 -0
- package/dist/plugins/index.js +10 -0
- package/dist/plugins/index.js.map +1 -0
- package/dist/plugins/mcp-client.d.ts +19 -0
- package/dist/plugins/mcp-client.d.ts.map +1 -0
- package/dist/plugins/mcp-client.js +126 -0
- package/dist/plugins/mcp-client.js.map +1 -0
- package/dist/plugins/mcp-client.test.d.ts +2 -0
- package/dist/plugins/mcp-client.test.d.ts.map +1 -0
- package/dist/plugins/mcp-client.test.js +160 -0
- package/dist/plugins/mcp-client.test.js.map +1 -0
- package/dist/plugins/oauth-provider.d.ts +27 -0
- package/dist/plugins/oauth-provider.d.ts.map +1 -0
- package/dist/plugins/oauth-provider.js +140 -0
- package/dist/plugins/oauth-provider.js.map +1 -0
- package/dist/plugins/oauth-provider.test.d.ts +2 -0
- package/dist/plugins/oauth-provider.test.d.ts.map +1 -0
- package/dist/plugins/oauth-provider.test.js +144 -0
- package/dist/plugins/oauth-provider.test.js.map +1 -0
- package/dist/plugins/plugin-loader.d.ts +29 -0
- package/dist/plugins/plugin-loader.d.ts.map +1 -0
- package/dist/plugins/plugin-loader.js +71 -0
- package/dist/plugins/plugin-loader.js.map +1 -0
- package/dist/plugins/plugin-loader.test.d.ts +2 -0
- package/dist/plugins/plugin-loader.test.d.ts.map +1 -0
- package/dist/plugins/plugin-loader.test.js +87 -0
- package/dist/plugins/plugin-loader.test.js.map +1 -0
- package/dist/prompt-builder.d.ts +47 -0
- package/dist/prompt-builder.d.ts.map +1 -0
- package/dist/prompt-builder.js +263 -0
- package/dist/prompt-builder.js.map +1 -0
- package/dist/prompt-builder.test.d.ts +2 -0
- package/dist/prompt-builder.test.d.ts.map +1 -0
- package/dist/prompt-builder.test.js +154 -0
- package/dist/prompt-builder.test.js.map +1 -0
- package/dist/providers/anthropic.d.ts +14 -0
- package/dist/providers/anthropic.d.ts.map +1 -0
- package/dist/providers/anthropic.js +118 -0
- package/dist/providers/anthropic.js.map +1 -0
- package/dist/providers/anthropic.test.d.ts +2 -0
- package/dist/providers/anthropic.test.d.ts.map +1 -0
- package/dist/providers/anthropic.test.js +76 -0
- package/dist/providers/anthropic.test.js.map +1 -0
- package/dist/providers/mock.d.ts +17 -0
- package/dist/providers/mock.d.ts.map +1 -0
- package/dist/providers/mock.js +39 -0
- package/dist/providers/mock.js.map +1 -0
- package/dist/providers/ollama.d.ts +18 -0
- package/dist/providers/ollama.d.ts.map +1 -0
- package/dist/providers/ollama.js +155 -0
- package/dist/providers/ollama.js.map +1 -0
- package/dist/providers/ollama.test.d.ts +2 -0
- package/dist/providers/ollama.test.d.ts.map +1 -0
- package/dist/providers/ollama.test.js +123 -0
- package/dist/providers/ollama.test.js.map +1 -0
- package/dist/providers/openai-responses.d.ts +18 -0
- package/dist/providers/openai-responses.d.ts.map +1 -0
- package/dist/providers/openai-responses.js +175 -0
- package/dist/providers/openai-responses.js.map +1 -0
- package/dist/providers/openai.d.ts +16 -0
- package/dist/providers/openai.d.ts.map +1 -0
- package/dist/providers/openai.js +132 -0
- package/dist/providers/openai.js.map +1 -0
- package/dist/providers/openai.test.d.ts +2 -0
- package/dist/providers/openai.test.d.ts.map +1 -0
- package/dist/providers/openai.test.js +51 -0
- package/dist/providers/openai.test.js.map +1 -0
- package/dist/providers/provider.d.ts +42 -0
- package/dist/providers/provider.d.ts.map +1 -0
- package/dist/providers/provider.js +10 -0
- package/dist/providers/provider.js.map +1 -0
- package/dist/providers/registry.d.ts +42 -0
- package/dist/providers/registry.d.ts.map +1 -0
- package/dist/providers/registry.js +65 -0
- package/dist/providers/registry.js.map +1 -0
- package/dist/runner.d.ts +46 -0
- package/dist/runner.d.ts.map +1 -0
- package/dist/runner.js +324 -0
- package/dist/runner.js.map +1 -0
- package/dist/runner.test.d.ts +2 -0
- package/dist/runner.test.d.ts.map +1 -0
- package/dist/runner.test.js +280 -0
- package/dist/runner.test.js.map +1 -0
- package/dist/script-executor.d.ts +11 -0
- package/dist/script-executor.d.ts.map +1 -0
- package/dist/script-executor.js +85 -0
- package/dist/script-executor.js.map +1 -0
- package/dist/tools/builtin/git.d.ts +6 -0
- package/dist/tools/builtin/git.d.ts.map +1 -0
- package/dist/tools/builtin/git.js +294 -0
- package/dist/tools/builtin/git.js.map +1 -0
- package/dist/tools/builtin/patch.d.ts +6 -0
- package/dist/tools/builtin/patch.d.ts.map +1 -0
- package/dist/tools/builtin/patch.js +238 -0
- package/dist/tools/builtin/patch.js.map +1 -0
- package/dist/tools/builtin/repo-manager.d.ts +6 -0
- package/dist/tools/builtin/repo-manager.d.ts.map +1 -0
- package/dist/tools/builtin/repo-manager.js +171 -0
- package/dist/tools/builtin/repo-manager.js.map +1 -0
- package/dist/tools/builtin/search.d.ts +6 -0
- package/dist/tools/builtin/search.d.ts.map +1 -0
- package/dist/tools/builtin/search.js +104 -0
- package/dist/tools/builtin/search.js.map +1 -0
- package/dist/tools/builtin/shell.d.ts +6 -0
- package/dist/tools/builtin/shell.d.ts.map +1 -0
- package/dist/tools/builtin/shell.js +78 -0
- package/dist/tools/builtin/shell.js.map +1 -0
- package/dist/tools/builtin/studio-run.d.ts +12 -0
- package/dist/tools/builtin/studio-run.d.ts.map +1 -0
- package/dist/tools/builtin/studio-run.js +61 -0
- package/dist/tools/builtin/studio-run.js.map +1 -0
- package/dist/tools/builtin/web-search.d.ts +7 -0
- package/dist/tools/builtin/web-search.d.ts.map +1 -0
- package/dist/tools/builtin/web-search.js +94 -0
- package/dist/tools/builtin/web-search.js.map +1 -0
- package/dist/tools/builtin/web-search.test.d.ts +5 -0
- package/dist/tools/builtin/web-search.test.d.ts.map +1 -0
- package/dist/tools/builtin/web-search.test.js +90 -0
- package/dist/tools/builtin/web-search.test.js.map +1 -0
- package/dist/tools/errors.d.ts +4 -0
- package/dist/tools/errors.d.ts.map +1 -0
- package/dist/tools/errors.js +11 -0
- package/dist/tools/errors.js.map +1 -0
- package/dist/tools/errors.test.d.ts +2 -0
- package/dist/tools/errors.test.d.ts.map +1 -0
- package/dist/tools/errors.test.js +14 -0
- package/dist/tools/errors.test.js.map +1 -0
- package/dist/tools/plugin-loader.d.ts +31 -0
- package/dist/tools/plugin-loader.d.ts.map +1 -0
- package/dist/tools/plugin-loader.js +183 -0
- package/dist/tools/plugin-loader.js.map +1 -0
- package/dist/tools/plugin-loader.test.d.ts +2 -0
- package/dist/tools/plugin-loader.test.d.ts.map +1 -0
- package/dist/tools/plugin-loader.test.js +116 -0
- package/dist/tools/plugin-loader.test.js.map +1 -0
- package/dist/tools/skills/skill-loader.d.ts +23 -0
- package/dist/tools/skills/skill-loader.d.ts.map +1 -0
- package/dist/tools/skills/skill-loader.js +58 -0
- package/dist/tools/skills/skill-loader.js.map +1 -0
- package/dist/tools/skills/skill-loader.test.d.ts +2 -0
- package/dist/tools/skills/skill-loader.test.d.ts.map +1 -0
- package/dist/tools/skills/skill-loader.test.js +92 -0
- package/dist/tools/skills/skill-loader.test.js.map +1 -0
- package/dist/tools/tool-executor.d.ts +12 -0
- package/dist/tools/tool-executor.d.ts.map +1 -0
- package/dist/tools/tool-executor.js +76 -0
- package/dist/tools/tool-executor.js.map +1 -0
- package/dist/tools/tool-executor.test.d.ts +2 -0
- package/dist/tools/tool-executor.test.d.ts.map +1 -0
- package/dist/tools/tool-executor.test.js +83 -0
- package/dist/tools/tool-executor.test.js.map +1 -0
- package/dist/tools/tool-registry.d.ts +65 -0
- package/dist/tools/tool-registry.d.ts.map +1 -0
- package/dist/tools/tool-registry.js +112 -0
- package/dist/tools/tool-registry.js.map +1 -0
- package/dist/tools/yaml-executor.d.ts +22 -0
- package/dist/tools/yaml-executor.d.ts.map +1 -0
- package/dist/tools/yaml-executor.js +80 -0
- package/dist/tools/yaml-executor.js.map +1 -0
- package/dist/utils/race-signal.d.ts +6 -0
- package/dist/utils/race-signal.d.ts.map +1 -0
- package/dist/utils/race-signal.js +21 -0
- package/dist/utils/race-signal.js.map +1 -0
- package/dist/utils/race-signal.test.d.ts +2 -0
- package/dist/utils/race-signal.test.d.ts.map +1 -0
- package/dist/utils/race-signal.test.js +48 -0
- package/dist/utils/race-signal.test.js.map +1 -0
- package/package.json +36 -0
- package/src/__tests__/script-executor.test.ts +180 -0
- package/src/index.ts +68 -0
- package/src/integrations/integration-loader.test.ts +88 -0
- package/src/integrations/integration-loader.ts +68 -0
- package/src/middleware/anonymization.ts +38 -0
- package/src/plugins/index.ts +4 -0
- package/src/plugins/mcp-client.test.ts +148 -0
- package/src/plugins/mcp-client.ts +128 -0
- package/src/plugins/oauth-provider.test.ts +167 -0
- package/src/plugins/oauth-provider.ts +175 -0
- package/src/plugins/plugin-loader.test.ts +114 -0
- package/src/plugins/plugin-loader.ts +90 -0
- package/src/prompt-builder.test.ts +167 -0
- package/src/prompt-builder.ts +332 -0
- package/src/providers/anthropic.test.ts +101 -0
- package/src/providers/anthropic.ts +135 -0
- package/src/providers/mock.ts +57 -0
- package/src/providers/ollama.test.ts +166 -0
- package/src/providers/ollama.ts +152 -0
- package/src/providers/openai-responses.ts +212 -0
- package/src/providers/openai.test.ts +67 -0
- package/src/providers/openai.ts +139 -0
- package/src/providers/provider.ts +54 -0
- package/src/providers/registry.ts +77 -0
- package/src/runner.test.ts +343 -0
- package/src/runner.ts +396 -0
- package/src/script-executor.ts +107 -0
- package/src/tools/builtin/git.ts +311 -0
- package/src/tools/builtin/patch.ts +257 -0
- package/src/tools/builtin/repo-manager.ts +142 -0
- package/src/tools/builtin/search.ts +108 -0
- package/src/tools/builtin/shell.ts +82 -0
- package/src/tools/builtin/studio-run.ts +73 -0
- package/src/tools/builtin/web-search.test.ts +122 -0
- package/src/tools/builtin/web-search.ts +101 -0
- package/src/tools/errors.test.ts +12 -0
- package/src/tools/errors.ts +6 -0
- package/src/tools/plugin-loader.test.ts +130 -0
- package/src/tools/plugin-loader.ts +203 -0
- package/src/tools/skills/README.md +49 -0
- package/src/tools/skills/skill-loader.test.ts +106 -0
- package/src/tools/skills/skill-loader.ts +62 -0
- package/src/tools/tool-executor.test.ts +88 -0
- package/src/tools/tool-executor.ts +84 -0
- package/src/tools/tool-registry.ts +130 -0
- package/src/tools/yaml-executor.ts +120 -0
- package/src/utils/race-signal.test.ts +50 -0
- package/src/utils/race-signal.ts +17 -0
- package/templates/integrations/linear.integration.yaml +35 -0
- package/templates/integrations/slack.integration.yaml +22 -0
- package/templates/integrations/webhook.integration.yaml +17 -0
- package/templates/tools/git.tool.yaml +80 -0
- package/templates/tools/repo-manager.tool.yaml +64 -0
- package/templates/tools/search.tool.yaml +22 -0
- package/templates/tools/shell.tool.yaml +19 -0
- package/templates/tools/web-search.tool.yaml +24 -0
- package/tests/anonymization-middleware.test.ts +61 -0
- package/tests/anthropic.test.ts +87 -0
- package/tests/apply-patch.test.ts +355 -0
- package/tests/fixtures/tools/test-builtin.tool.yaml +14 -0
- package/tests/fixtures/tools/test-shell.tool.yaml +19 -0
- package/tests/mock-provider.test.ts +104 -0
- package/tests/openai.test.ts +72 -0
- package/tests/plugin-loader.test.ts +54 -0
- package/tests/prompt-builder.test.ts +468 -0
- package/tests/runner-anonymization.test.ts +89 -0
- package/tests/runner.test.ts +885 -0
- package/tests/studio-run.test.ts +94 -0
- package/tests/tool-executor.test.ts +115 -0
- package/tests/tool-registry.test.ts +84 -0
- package/tests/yaml-executor.test.ts +76 -0
- package/tsconfig.json +20 -0
- 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 @@
|
|
|
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"}
|
package/dist/runner.d.ts
ADDED
|
@@ -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"}
|