@executioncontrolprotocol/runtime 0.3.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.
- package/dist/engine/context-loader.d.ts +31 -0
- package/dist/engine/context-loader.d.ts.map +1 -0
- package/dist/engine/context-loader.js +90 -0
- package/dist/engine/context-loader.js.map +1 -0
- package/dist/engine/index.d.ts +6 -0
- package/dist/engine/index.d.ts.map +1 -0
- package/dist/engine/index.js +6 -0
- package/dist/engine/index.js.map +1 -0
- package/dist/engine/runner.d.ts +92 -0
- package/dist/engine/runner.d.ts.map +1 -0
- package/dist/engine/runner.js +852 -0
- package/dist/engine/runner.js.map +1 -0
- package/dist/engine/schema-validator.d.ts +32 -0
- package/dist/engine/schema-validator.d.ts.map +1 -0
- package/dist/engine/schema-validator.js +69 -0
- package/dist/engine/schema-validator.js.map +1 -0
- package/dist/engine/system-config-loader.d.ts +39 -0
- package/dist/engine/system-config-loader.d.ts.map +1 -0
- package/dist/engine/system-config-loader.js +80 -0
- package/dist/engine/system-config-loader.js.map +1 -0
- package/dist/engine/types.d.ts +324 -0
- package/dist/engine/types.d.ts.map +1 -0
- package/dist/engine/types.js +10 -0
- package/dist/engine/types.js.map +1 -0
- package/dist/evals/index.d.ts +3 -0
- package/dist/evals/index.d.ts.map +1 -0
- package/dist/evals/index.js +3 -0
- package/dist/evals/index.js.map +1 -0
- package/dist/evals/scorer.d.ts +23 -0
- package/dist/evals/scorer.d.ts.map +1 -0
- package/dist/evals/scorer.js +133 -0
- package/dist/evals/scorer.js.map +1 -0
- package/dist/evals/types.d.ts +128 -0
- package/dist/evals/types.d.ts.map +1 -0
- package/dist/evals/types.js +11 -0
- package/dist/evals/types.js.map +1 -0
- package/dist/extensions/builtin.d.ts +44 -0
- package/dist/extensions/builtin.d.ts.map +1 -0
- package/dist/extensions/builtin.js +66 -0
- package/dist/extensions/builtin.js.map +1 -0
- package/dist/extensions/index.d.ts +4 -0
- package/dist/extensions/index.d.ts.map +1 -0
- package/dist/extensions/index.js +4 -0
- package/dist/extensions/index.js.map +1 -0
- package/dist/extensions/progress-loggers/file-logger.d.ts +27 -0
- package/dist/extensions/progress-loggers/file-logger.d.ts.map +1 -0
- package/dist/extensions/progress-loggers/file-logger.js +54 -0
- package/dist/extensions/progress-loggers/file-logger.js.map +1 -0
- package/dist/extensions/registry.d.ts +74 -0
- package/dist/extensions/registry.d.ts.map +1 -0
- package/dist/extensions/registry.js +126 -0
- package/dist/extensions/registry.js.map +1 -0
- package/dist/extensions/types.d.ts +78 -0
- package/dist/extensions/types.d.ts.map +1 -0
- package/dist/extensions/types.js +7 -0
- package/dist/extensions/types.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -0
- package/dist/mounts/hydrator.d.ts +46 -0
- package/dist/mounts/hydrator.d.ts.map +1 -0
- package/dist/mounts/hydrator.js +142 -0
- package/dist/mounts/hydrator.js.map +1 -0
- package/dist/mounts/index.d.ts +4 -0
- package/dist/mounts/index.d.ts.map +1 -0
- package/dist/mounts/index.js +4 -0
- package/dist/mounts/index.js.map +1 -0
- package/dist/mounts/interpolation.d.ts +33 -0
- package/dist/mounts/interpolation.d.ts.map +1 -0
- package/dist/mounts/interpolation.js +59 -0
- package/dist/mounts/interpolation.js.map +1 -0
- package/dist/mounts/types.d.ts +80 -0
- package/dist/mounts/types.d.ts.map +1 -0
- package/dist/mounts/types.js +10 -0
- package/dist/mounts/types.js.map +1 -0
- package/dist/policies/enforcer.d.ts +23 -0
- package/dist/policies/enforcer.d.ts.map +1 -0
- package/dist/policies/enforcer.js +111 -0
- package/dist/policies/enforcer.js.map +1 -0
- package/dist/policies/index.d.ts +3 -0
- package/dist/policies/index.d.ts.map +1 -0
- package/dist/policies/index.js +3 -0
- package/dist/policies/index.js.map +1 -0
- package/dist/policies/types.d.ts +87 -0
- package/dist/policies/types.d.ts.map +1 -0
- package/dist/policies/types.js +11 -0
- package/dist/policies/types.js.map +1 -0
- package/dist/protocols/a2a/a2a-transport.d.ts +40 -0
- package/dist/protocols/a2a/a2a-transport.d.ts.map +1 -0
- package/dist/protocols/a2a/a2a-transport.js +212 -0
- package/dist/protocols/a2a/a2a-transport.js.map +1 -0
- package/dist/protocols/a2a/index.d.ts +3 -0
- package/dist/protocols/a2a/index.d.ts.map +1 -0
- package/dist/protocols/a2a/index.js +2 -0
- package/dist/protocols/a2a/index.js.map +1 -0
- package/dist/protocols/agent-transport.d.ts +101 -0
- package/dist/protocols/agent-transport.d.ts.map +1 -0
- package/dist/protocols/agent-transport.js +11 -0
- package/dist/protocols/agent-transport.js.map +1 -0
- package/dist/protocols/index.d.ts +5 -0
- package/dist/protocols/index.d.ts.map +1 -0
- package/dist/protocols/index.js +5 -0
- package/dist/protocols/index.js.map +1 -0
- package/dist/protocols/mcp/index.d.ts +2 -0
- package/dist/protocols/mcp/index.d.ts.map +1 -0
- package/dist/protocols/mcp/index.js +2 -0
- package/dist/protocols/mcp/index.js.map +1 -0
- package/dist/protocols/mcp/mcp-tool-invoker.d.ts +30 -0
- package/dist/protocols/mcp/mcp-tool-invoker.d.ts.map +1 -0
- package/dist/protocols/mcp/mcp-tool-invoker.js +121 -0
- package/dist/protocols/mcp/mcp-tool-invoker.js.map +1 -0
- package/dist/protocols/tool-invoker.d.ts +91 -0
- package/dist/protocols/tool-invoker.d.ts.map +1 -0
- package/dist/protocols/tool-invoker.js +11 -0
- package/dist/protocols/tool-invoker.js.map +1 -0
- package/dist/providers/index.d.ts +4 -0
- package/dist/providers/index.d.ts.map +1 -0
- package/dist/providers/index.js +4 -0
- package/dist/providers/index.js.map +1 -0
- package/dist/providers/model-provider.d.ts +132 -0
- package/dist/providers/model-provider.d.ts.map +1 -0
- package/dist/providers/model-provider.js +10 -0
- package/dist/providers/model-provider.js.map +1 -0
- package/dist/providers/ollama/index.d.ts +3 -0
- package/dist/providers/ollama/index.d.ts.map +1 -0
- package/dist/providers/ollama/index.js +2 -0
- package/dist/providers/ollama/index.js.map +1 -0
- package/dist/providers/ollama/ollama-provider.d.ts +41 -0
- package/dist/providers/ollama/ollama-provider.d.ts.map +1 -0
- package/dist/providers/ollama/ollama-provider.js +113 -0
- package/dist/providers/ollama/ollama-provider.js.map +1 -0
- package/dist/providers/openai/index.d.ts +3 -0
- package/dist/providers/openai/index.d.ts.map +1 -0
- package/dist/providers/openai/index.js +2 -0
- package/dist/providers/openai/index.js.map +1 -0
- package/dist/providers/openai/openai-provider.d.ts +41 -0
- package/dist/providers/openai/openai-provider.d.ts.map +1 -0
- package/dist/providers/openai/openai-provider.js +150 -0
- package/dist/providers/openai/openai-provider.js.map +1 -0
- package/dist/testing/cassette.d.ts +88 -0
- package/dist/testing/cassette.d.ts.map +1 -0
- package/dist/testing/cassette.js +123 -0
- package/dist/testing/cassette.js.map +1 -0
- package/dist/testing/index.d.ts +5 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/index.js +5 -0
- package/dist/testing/index.js.map +1 -0
- package/dist/testing/mock-agent-transport.d.ts +49 -0
- package/dist/testing/mock-agent-transport.d.ts.map +1 -0
- package/dist/testing/mock-agent-transport.js +71 -0
- package/dist/testing/mock-agent-transport.js.map +1 -0
- package/dist/testing/mock-model-provider.d.ts +69 -0
- package/dist/testing/mock-model-provider.d.ts.map +1 -0
- package/dist/testing/mock-model-provider.js +92 -0
- package/dist/testing/mock-model-provider.js.map +1 -0
- package/dist/testing/mock-tool-invoker.d.ts +65 -0
- package/dist/testing/mock-tool-invoker.d.ts.map +1 -0
- package/dist/testing/mock-tool-invoker.js +85 -0
- package/dist/testing/mock-tool-invoker.js.map +1 -0
- package/dist/tracing/collector.d.ts +75 -0
- package/dist/tracing/collector.d.ts.map +1 -0
- package/dist/tracing/collector.js +106 -0
- package/dist/tracing/collector.js.map +1 -0
- package/dist/tracing/exporters/console.d.ts +17 -0
- package/dist/tracing/exporters/console.d.ts.map +1 -0
- package/dist/tracing/exporters/console.js +76 -0
- package/dist/tracing/exporters/console.js.map +1 -0
- package/dist/tracing/exporters/index.d.ts +4 -0
- package/dist/tracing/exporters/index.d.ts.map +1 -0
- package/dist/tracing/exporters/index.js +3 -0
- package/dist/tracing/exporters/index.js.map +1 -0
- package/dist/tracing/exporters/json-file.d.ts +30 -0
- package/dist/tracing/exporters/json-file.d.ts.map +1 -0
- package/dist/tracing/exporters/json-file.js +28 -0
- package/dist/tracing/exporters/json-file.js.map +1 -0
- package/dist/tracing/formatter.d.ts +16 -0
- package/dist/tracing/formatter.d.ts.map +1 -0
- package/dist/tracing/formatter.js +81 -0
- package/dist/tracing/formatter.js.map +1 -0
- package/dist/tracing/graph.d.ts +17 -0
- package/dist/tracing/graph.d.ts.map +1 -0
- package/dist/tracing/graph.js +116 -0
- package/dist/tracing/graph.js.map +1 -0
- package/dist/tracing/index.d.ts +6 -0
- package/dist/tracing/index.d.ts.map +1 -0
- package/dist/tracing/index.js +6 -0
- package/dist/tracing/index.js.map +1 -0
- package/dist/tracing/types.d.ts +124 -0
- package/dist/tracing/types.d.ts.map +1 -0
- package/dist/tracing/types.js +11 -0
- package/dist/tracing/types.js.map +1 -0
- package/package.json +42 -0
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ollama implementation of the {@link ModelProvider} interface.
|
|
3
|
+
*
|
|
4
|
+
* Uses Ollama's native REST API (`/api/chat`) so there is no dependency
|
|
5
|
+
* on the OpenAI SDK. Supports JSON-mode output and tool/function calling.
|
|
6
|
+
*
|
|
7
|
+
* @category Providers
|
|
8
|
+
*/
|
|
9
|
+
import type { GenerateOptions, GenerateResult, ModelProvider } from "../model-provider.js";
|
|
10
|
+
/**
|
|
11
|
+
* Configuration for the Ollama provider.
|
|
12
|
+
*
|
|
13
|
+
* @category Providers
|
|
14
|
+
*/
|
|
15
|
+
export interface OllamaProviderConfig {
|
|
16
|
+
/** Base URL for the Ollama server. Defaults to `http://localhost:11434`. */
|
|
17
|
+
baseURL?: string;
|
|
18
|
+
/** Default model to use (e.g. `"gemma3:1b"`). */
|
|
19
|
+
defaultModel?: string;
|
|
20
|
+
/** Request timeout in milliseconds. Defaults to 120 000 (2 min). */
|
|
21
|
+
timeoutMs?: number;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Ollama model provider implementation.
|
|
25
|
+
*
|
|
26
|
+
* Connects to a locally-running (or remote) Ollama instance via its
|
|
27
|
+
* native HTTP API. Ideal for CI pipelines and local development with
|
|
28
|
+
* open-weight models.
|
|
29
|
+
*
|
|
30
|
+
* @category Providers
|
|
31
|
+
*/
|
|
32
|
+
export declare class OllamaProvider implements ModelProvider {
|
|
33
|
+
readonly name = "ollama";
|
|
34
|
+
private readonly baseURL;
|
|
35
|
+
private readonly defaultModel;
|
|
36
|
+
private readonly timeoutMs;
|
|
37
|
+
constructor(config?: OllamaProviderConfig);
|
|
38
|
+
supportsToolCalling(): boolean;
|
|
39
|
+
generate(options: GenerateOptions): Promise<GenerateResult>;
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=ollama-provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ollama-provider.d.ts","sourceRoot":"","sources":["../../../src/providers/ollama/ollama-provider.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAEV,eAAe,EACf,cAAc,EACd,aAAa,EAId,MAAM,sBAAsB,CAAC;AAE9B;;;;GAIG;AACH,MAAM,WAAW,oBAAoB;IACnC,4EAA4E;IAC5E,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,iDAAiD;IACjD,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB,oEAAoE;IACpE,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AA6ED;;;;;;;;GAQG;AACH,qBAAa,cAAe,YAAW,aAAa;IAClD,QAAQ,CAAC,IAAI,YAAY;IAEzB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;gBAEvB,MAAM,GAAE,oBAAyB;IAS7C,mBAAmB,IAAI,OAAO;IAIxB,QAAQ,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC;CAyDlE"}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ollama implementation of the {@link ModelProvider} interface.
|
|
3
|
+
*
|
|
4
|
+
* Uses Ollama's native REST API (`/api/chat`) so there is no dependency
|
|
5
|
+
* on the OpenAI SDK. Supports JSON-mode output and tool/function calling.
|
|
6
|
+
*
|
|
7
|
+
* @category Providers
|
|
8
|
+
*/
|
|
9
|
+
function toOllamaMessages(messages) {
|
|
10
|
+
return messages.map((msg) => ({
|
|
11
|
+
role: msg.role,
|
|
12
|
+
content: msg.content,
|
|
13
|
+
}));
|
|
14
|
+
}
|
|
15
|
+
function toOllamaTools(tools) {
|
|
16
|
+
return tools.map((tool) => ({
|
|
17
|
+
type: "function",
|
|
18
|
+
function: {
|
|
19
|
+
name: tool.name,
|
|
20
|
+
description: tool.description,
|
|
21
|
+
parameters: tool.parameters,
|
|
22
|
+
},
|
|
23
|
+
}));
|
|
24
|
+
}
|
|
25
|
+
function extractToolCalls(response) {
|
|
26
|
+
const calls = response.message.tool_calls;
|
|
27
|
+
if (!calls?.length)
|
|
28
|
+
return [];
|
|
29
|
+
return calls.map((tc, idx) => ({
|
|
30
|
+
id: `call_${idx}`,
|
|
31
|
+
name: tc.function.name,
|
|
32
|
+
arguments: tc.function.arguments,
|
|
33
|
+
}));
|
|
34
|
+
}
|
|
35
|
+
function extractUsage(response) {
|
|
36
|
+
const prompt = response.prompt_eval_count ?? 0;
|
|
37
|
+
const completion = response.eval_count ?? 0;
|
|
38
|
+
return {
|
|
39
|
+
promptTokens: prompt,
|
|
40
|
+
completionTokens: completion,
|
|
41
|
+
totalTokens: prompt + completion,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Ollama model provider implementation.
|
|
46
|
+
*
|
|
47
|
+
* Connects to a locally-running (or remote) Ollama instance via its
|
|
48
|
+
* native HTTP API. Ideal for CI pipelines and local development with
|
|
49
|
+
* open-weight models.
|
|
50
|
+
*
|
|
51
|
+
* @category Providers
|
|
52
|
+
*/
|
|
53
|
+
export class OllamaProvider {
|
|
54
|
+
name = "ollama";
|
|
55
|
+
baseURL;
|
|
56
|
+
defaultModel;
|
|
57
|
+
timeoutMs;
|
|
58
|
+
constructor(config = {}) {
|
|
59
|
+
this.baseURL = (config.baseURL ?? "http://localhost:11434").replace(/\/$/, "");
|
|
60
|
+
this.defaultModel = config.defaultModel ?? "gemma3:1b";
|
|
61
|
+
this.timeoutMs = config.timeoutMs ?? 120_000;
|
|
62
|
+
}
|
|
63
|
+
supportsToolCalling() {
|
|
64
|
+
return true;
|
|
65
|
+
}
|
|
66
|
+
async generate(options) {
|
|
67
|
+
const model = options.model ?? this.defaultModel;
|
|
68
|
+
const messages = toOllamaMessages(options.messages);
|
|
69
|
+
const body = {
|
|
70
|
+
model,
|
|
71
|
+
messages,
|
|
72
|
+
stream: false,
|
|
73
|
+
};
|
|
74
|
+
if (options.tools?.length) {
|
|
75
|
+
body.tools = toOllamaTools(options.tools);
|
|
76
|
+
}
|
|
77
|
+
if (options.responseFormat) {
|
|
78
|
+
body.format = "json";
|
|
79
|
+
}
|
|
80
|
+
if (options.temperature !== undefined) {
|
|
81
|
+
body.options = { temperature: options.temperature };
|
|
82
|
+
}
|
|
83
|
+
const controller = new AbortController();
|
|
84
|
+
const timeout = setTimeout(() => controller.abort(), this.timeoutMs);
|
|
85
|
+
if (options.signal) {
|
|
86
|
+
options.signal.addEventListener("abort", () => controller.abort());
|
|
87
|
+
}
|
|
88
|
+
try {
|
|
89
|
+
const response = await fetch(`${this.baseURL}/api/chat`, {
|
|
90
|
+
method: "POST",
|
|
91
|
+
headers: { "Content-Type": "application/json" },
|
|
92
|
+
body: JSON.stringify(body),
|
|
93
|
+
signal: controller.signal,
|
|
94
|
+
});
|
|
95
|
+
if (!response.ok) {
|
|
96
|
+
const text = await response.text();
|
|
97
|
+
throw new Error(`Ollama API error (${response.status}): ${text}`);
|
|
98
|
+
}
|
|
99
|
+
const data = (await response.json());
|
|
100
|
+
const toolCalls = extractToolCalls(data);
|
|
101
|
+
return {
|
|
102
|
+
content: data.message.content ?? "",
|
|
103
|
+
toolCalls,
|
|
104
|
+
finishReason: toolCalls.length > 0 ? "tool-calls" : "stop",
|
|
105
|
+
usage: extractUsage(data),
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
finally {
|
|
109
|
+
clearTimeout(timeout);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=ollama-provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ollama-provider.js","sourceRoot":"","sources":["../../../src/providers/ollama/ollama-provider.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/providers/openai/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,YAAY,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/providers/openai/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenAI implementation of the {@link ModelProvider} interface.
|
|
3
|
+
*
|
|
4
|
+
* Uses the official `openai` npm package to call the Chat Completions API.
|
|
5
|
+
* Supports tool/function calling, structured JSON output, and token usage tracking.
|
|
6
|
+
*
|
|
7
|
+
* @category Providers
|
|
8
|
+
*/
|
|
9
|
+
import type { GenerateOptions, GenerateResult, ModelProvider } from "../model-provider.js";
|
|
10
|
+
/**
|
|
11
|
+
* Configuration for the OpenAI provider.
|
|
12
|
+
*
|
|
13
|
+
* @category Providers
|
|
14
|
+
*/
|
|
15
|
+
export interface OpenAIProviderConfig {
|
|
16
|
+
/** OpenAI API key. Falls back to `OPENAI_API_KEY` env var if not set. */
|
|
17
|
+
apiKey?: string;
|
|
18
|
+
/** Base URL override (e.g. for Azure OpenAI or proxies). */
|
|
19
|
+
baseURL?: string;
|
|
20
|
+
/** Default model to use (e.g. `"gpt-4o"`, `"gpt-4o-mini"`). */
|
|
21
|
+
defaultModel?: string;
|
|
22
|
+
/** Default max tokens for generation. */
|
|
23
|
+
defaultMaxTokens?: number;
|
|
24
|
+
/** Organization ID for OpenAI API requests. */
|
|
25
|
+
organization?: string;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* OpenAI model provider implementation.
|
|
29
|
+
*
|
|
30
|
+
* @category Providers
|
|
31
|
+
*/
|
|
32
|
+
export declare class OpenAIProvider implements ModelProvider {
|
|
33
|
+
readonly name = "openai";
|
|
34
|
+
private readonly client;
|
|
35
|
+
private readonly defaultModel;
|
|
36
|
+
private readonly defaultMaxTokens;
|
|
37
|
+
constructor(config?: OpenAIProviderConfig);
|
|
38
|
+
supportsToolCalling(): boolean;
|
|
39
|
+
generate(options: GenerateOptions): Promise<GenerateResult>;
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=openai-provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openai-provider.d.ts","sourceRoot":"","sources":["../../../src/providers/openai/openai-provider.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,EAEV,eAAe,EACf,cAAc,EACd,aAAa,EAId,MAAM,sBAAsB,CAAC;AAE9B;;;;GAIG;AACH,MAAM,WAAW,oBAAoB;IACnC,yEAAyE;IACzE,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB,4DAA4D;IAC5D,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,+DAA+D;IAC/D,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB,yCAAyC;IACzC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAE1B,+CAA+C;IAC/C,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AA6FD;;;;GAIG;AACH,qBAAa,cAAe,YAAW,aAAa;IAClD,QAAQ,CAAC,IAAI,YAAY;IAEzB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAS;gBAE9B,MAAM,GAAE,oBAAyB;IAU7C,mBAAmB,IAAI,OAAO;IAIxB,QAAQ,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC;CA+ClE"}
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenAI implementation of the {@link ModelProvider} interface.
|
|
3
|
+
*
|
|
4
|
+
* Uses the official `openai` npm package to call the Chat Completions API.
|
|
5
|
+
* Supports tool/function calling, structured JSON output, and token usage tracking.
|
|
6
|
+
*
|
|
7
|
+
* @category Providers
|
|
8
|
+
*/
|
|
9
|
+
import OpenAI from "openai";
|
|
10
|
+
function toOpenAIMessages(messages) {
|
|
11
|
+
return messages.map((msg) => {
|
|
12
|
+
switch (msg.role) {
|
|
13
|
+
case "system":
|
|
14
|
+
return {
|
|
15
|
+
role: "system",
|
|
16
|
+
content: msg.content,
|
|
17
|
+
};
|
|
18
|
+
case "user":
|
|
19
|
+
return {
|
|
20
|
+
role: "user",
|
|
21
|
+
content: msg.content,
|
|
22
|
+
};
|
|
23
|
+
case "assistant":
|
|
24
|
+
return {
|
|
25
|
+
role: "assistant",
|
|
26
|
+
content: msg.content,
|
|
27
|
+
};
|
|
28
|
+
case "tool":
|
|
29
|
+
return {
|
|
30
|
+
role: "tool",
|
|
31
|
+
content: msg.content,
|
|
32
|
+
tool_call_id: msg.toolCallId ?? "",
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
function toOpenAITools(tools) {
|
|
38
|
+
return tools.map((tool) => ({
|
|
39
|
+
type: "function",
|
|
40
|
+
function: {
|
|
41
|
+
name: tool.name,
|
|
42
|
+
description: tool.description,
|
|
43
|
+
parameters: tool.parameters,
|
|
44
|
+
},
|
|
45
|
+
}));
|
|
46
|
+
}
|
|
47
|
+
function extractToolCalls(choice) {
|
|
48
|
+
const calls = choice.message.tool_calls;
|
|
49
|
+
if (!calls?.length)
|
|
50
|
+
return [];
|
|
51
|
+
return calls.map((tc) => ({
|
|
52
|
+
id: tc.id,
|
|
53
|
+
name: tc.function.name,
|
|
54
|
+
arguments: parseToolArgs(tc.function.arguments),
|
|
55
|
+
}));
|
|
56
|
+
}
|
|
57
|
+
function parseToolArgs(raw) {
|
|
58
|
+
try {
|
|
59
|
+
return JSON.parse(raw);
|
|
60
|
+
}
|
|
61
|
+
catch {
|
|
62
|
+
return { _raw: raw };
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
function mapFinishReason(reason) {
|
|
66
|
+
switch (reason) {
|
|
67
|
+
case "stop":
|
|
68
|
+
return "stop";
|
|
69
|
+
case "tool_calls":
|
|
70
|
+
return "tool-calls";
|
|
71
|
+
case "length":
|
|
72
|
+
return "length";
|
|
73
|
+
case "content_filter":
|
|
74
|
+
return "content-filter";
|
|
75
|
+
default:
|
|
76
|
+
return "stop";
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
function extractUsage(usage) {
|
|
80
|
+
return {
|
|
81
|
+
promptTokens: usage?.prompt_tokens ?? 0,
|
|
82
|
+
completionTokens: usage?.completion_tokens ?? 0,
|
|
83
|
+
totalTokens: usage?.total_tokens ?? 0,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* OpenAI model provider implementation.
|
|
88
|
+
*
|
|
89
|
+
* @category Providers
|
|
90
|
+
*/
|
|
91
|
+
export class OpenAIProvider {
|
|
92
|
+
name = "openai";
|
|
93
|
+
client;
|
|
94
|
+
defaultModel;
|
|
95
|
+
defaultMaxTokens;
|
|
96
|
+
constructor(config = {}) {
|
|
97
|
+
this.client = new OpenAI({
|
|
98
|
+
apiKey: config.apiKey ?? process.env.OPENAI_API_KEY,
|
|
99
|
+
baseURL: config.baseURL,
|
|
100
|
+
organization: config.organization,
|
|
101
|
+
});
|
|
102
|
+
this.defaultModel = config.defaultModel ?? "gpt-4o";
|
|
103
|
+
this.defaultMaxTokens = config.defaultMaxTokens ?? 4096;
|
|
104
|
+
}
|
|
105
|
+
supportsToolCalling() {
|
|
106
|
+
return true;
|
|
107
|
+
}
|
|
108
|
+
async generate(options) {
|
|
109
|
+
const model = options.model ?? this.defaultModel;
|
|
110
|
+
const messages = toOpenAIMessages(options.messages);
|
|
111
|
+
const params = {
|
|
112
|
+
model,
|
|
113
|
+
messages,
|
|
114
|
+
max_tokens: options.maxTokens ?? this.defaultMaxTokens,
|
|
115
|
+
temperature: options.temperature,
|
|
116
|
+
};
|
|
117
|
+
if (options.tools?.length) {
|
|
118
|
+
params.tools = toOpenAITools(options.tools);
|
|
119
|
+
}
|
|
120
|
+
if (options.responseFormat) {
|
|
121
|
+
params.response_format = {
|
|
122
|
+
type: "json_schema",
|
|
123
|
+
json_schema: {
|
|
124
|
+
name: "response",
|
|
125
|
+
strict: true,
|
|
126
|
+
schema: options.responseFormat.schema,
|
|
127
|
+
},
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
const response = await this.client.chat.completions.create(params, {
|
|
131
|
+
signal: options.signal ?? undefined,
|
|
132
|
+
});
|
|
133
|
+
const choice = response.choices[0];
|
|
134
|
+
if (!choice) {
|
|
135
|
+
return {
|
|
136
|
+
content: "",
|
|
137
|
+
toolCalls: [],
|
|
138
|
+
finishReason: "error",
|
|
139
|
+
usage: extractUsage(response.usage),
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
return {
|
|
143
|
+
content: choice.message.content ?? "",
|
|
144
|
+
toolCalls: extractToolCalls(choice),
|
|
145
|
+
finishReason: mapFinishReason(choice.finish_reason),
|
|
146
|
+
usage: extractUsage(response.usage),
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
//# sourceMappingURL=openai-provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openai-provider.js","sourceRoot":"","sources":["../../../src/providers/openai/openai-provider.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cassette record/replay system for deterministic test runs.
|
|
3
|
+
*
|
|
4
|
+
* Records all model calls, tool calls, and delegations during a run,
|
|
5
|
+
* then replays them to produce identical results without network.
|
|
6
|
+
*
|
|
7
|
+
* @category Testing
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* A single recorded interaction in a cassette.
|
|
11
|
+
*
|
|
12
|
+
* @category Testing
|
|
13
|
+
*/
|
|
14
|
+
export interface CassetteEntry {
|
|
15
|
+
/** Interaction type. */
|
|
16
|
+
type: "model-call" | "tool-call" | "delegation";
|
|
17
|
+
/** Timestamp of the interaction. */
|
|
18
|
+
timestamp: string;
|
|
19
|
+
/** The request sent. */
|
|
20
|
+
request: Record<string, unknown>;
|
|
21
|
+
/** The response received. */
|
|
22
|
+
response: Record<string, unknown>;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* A complete cassette recording of a run.
|
|
26
|
+
*
|
|
27
|
+
* @category Testing
|
|
28
|
+
*/
|
|
29
|
+
export interface Cassette {
|
|
30
|
+
/** The context name this cassette was recorded from. */
|
|
31
|
+
contextName: string;
|
|
32
|
+
/** When the recording was made. */
|
|
33
|
+
recordedAt: string;
|
|
34
|
+
/** Ordered sequence of interactions. */
|
|
35
|
+
entries: CassetteEntry[];
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Load a cassette from disk.
|
|
39
|
+
*
|
|
40
|
+
* @param path - File path to the cassette JSON.
|
|
41
|
+
* @returns The loaded cassette.
|
|
42
|
+
*
|
|
43
|
+
* @category Testing
|
|
44
|
+
*/
|
|
45
|
+
export declare function loadCassette(path: string): Cassette;
|
|
46
|
+
/**
|
|
47
|
+
* Save a cassette to disk.
|
|
48
|
+
*
|
|
49
|
+
* @param cassette - The cassette to save.
|
|
50
|
+
* @param path - File path to write to.
|
|
51
|
+
*
|
|
52
|
+
* @category Testing
|
|
53
|
+
*/
|
|
54
|
+
export declare function saveCassette(cassette: Cassette, path: string): void;
|
|
55
|
+
/**
|
|
56
|
+
* A cassette recorder that captures interactions during a run.
|
|
57
|
+
*
|
|
58
|
+
* @category Testing
|
|
59
|
+
*/
|
|
60
|
+
export declare class CassetteRecorder {
|
|
61
|
+
private entries;
|
|
62
|
+
private contextName;
|
|
63
|
+
setContextName(name: string): void;
|
|
64
|
+
recordModelCall(request: Record<string, unknown>, response: Record<string, unknown>): void;
|
|
65
|
+
recordToolCall(request: Record<string, unknown>, response: Record<string, unknown>): void;
|
|
66
|
+
recordDelegation(request: Record<string, unknown>, response: Record<string, unknown>): void;
|
|
67
|
+
toCassette(): Cassette;
|
|
68
|
+
reset(): void;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* A cassette replayer that provides pre-recorded responses.
|
|
72
|
+
*
|
|
73
|
+
* @category Testing
|
|
74
|
+
*/
|
|
75
|
+
export declare class CassetteReplayer {
|
|
76
|
+
private modelCallIndex;
|
|
77
|
+
private toolCallIndex;
|
|
78
|
+
private delegationIndex;
|
|
79
|
+
private readonly modelCalls;
|
|
80
|
+
private readonly toolCalls;
|
|
81
|
+
private readonly delegationCalls;
|
|
82
|
+
constructor(cassette: Cassette);
|
|
83
|
+
nextModelResponse(): Record<string, unknown> | undefined;
|
|
84
|
+
nextToolResponse(): Record<string, unknown> | undefined;
|
|
85
|
+
nextDelegationResponse(): Record<string, unknown> | undefined;
|
|
86
|
+
get exhausted(): boolean;
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=cassette.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cassette.d.ts","sourceRoot":"","sources":["../../src/testing/cassette.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC5B,wBAAwB;IACxB,IAAI,EAAE,YAAY,GAAG,WAAW,GAAG,YAAY,CAAC;IAEhD,oCAAoC;IACpC,SAAS,EAAE,MAAM,CAAC;IAElB,wBAAwB;IACxB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAEjC,6BAA6B;IAC7B,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAED;;;;GAIG;AACH,MAAM,WAAW,QAAQ;IACvB,wDAAwD;IACxD,WAAW,EAAE,MAAM,CAAC;IAEpB,mCAAmC;IACnC,UAAU,EAAE,MAAM,CAAC;IAEnB,wCAAwC;IACxC,OAAO,EAAE,aAAa,EAAE,CAAC;CAC1B;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,CAGnD;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAMnE;AAED;;;;GAIG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,OAAO,CAAuB;IACtC,OAAO,CAAC,WAAW,CAAM;IAEzB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAIlC,eAAe,CACb,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAChC,IAAI;IASP,cAAc,CACZ,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAChC,IAAI;IASP,gBAAgB,CACd,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAChC,IAAI;IASP,UAAU,IAAI,QAAQ;IAQtB,KAAK,IAAI,IAAI;CAId;AAED;;;;GAIG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,cAAc,CAAK;IAC3B,OAAO,CAAC,aAAa,CAAK;IAC1B,OAAO,CAAC,eAAe,CAAK;IAC5B,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAkB;IAC7C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAkB;IAC5C,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAkB;gBAEtC,QAAQ,EAAE,QAAQ;IAM9B,iBAAiB,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS;IAMxD,gBAAgB,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS;IAMvD,sBAAsB,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS;IAM7D,IAAI,SAAS,IAAI,OAAO,CAMvB;CACF"}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cassette record/replay system for deterministic test runs.
|
|
3
|
+
*
|
|
4
|
+
* Records all model calls, tool calls, and delegations during a run,
|
|
5
|
+
* then replays them to produce identical results without network.
|
|
6
|
+
*
|
|
7
|
+
* @category Testing
|
|
8
|
+
*/
|
|
9
|
+
import { readFileSync, writeFileSync, existsSync, mkdirSync } from "node:fs";
|
|
10
|
+
import { dirname } from "node:path";
|
|
11
|
+
/**
|
|
12
|
+
* Load a cassette from disk.
|
|
13
|
+
*
|
|
14
|
+
* @param path - File path to the cassette JSON.
|
|
15
|
+
* @returns The loaded cassette.
|
|
16
|
+
*
|
|
17
|
+
* @category Testing
|
|
18
|
+
*/
|
|
19
|
+
export function loadCassette(path) {
|
|
20
|
+
const raw = readFileSync(path, "utf-8");
|
|
21
|
+
return JSON.parse(raw);
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Save a cassette to disk.
|
|
25
|
+
*
|
|
26
|
+
* @param cassette - The cassette to save.
|
|
27
|
+
* @param path - File path to write to.
|
|
28
|
+
*
|
|
29
|
+
* @category Testing
|
|
30
|
+
*/
|
|
31
|
+
export function saveCassette(cassette, path) {
|
|
32
|
+
const dir = dirname(path);
|
|
33
|
+
if (!existsSync(dir)) {
|
|
34
|
+
mkdirSync(dir, { recursive: true });
|
|
35
|
+
}
|
|
36
|
+
writeFileSync(path, JSON.stringify(cassette, null, 2));
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* A cassette recorder that captures interactions during a run.
|
|
40
|
+
*
|
|
41
|
+
* @category Testing
|
|
42
|
+
*/
|
|
43
|
+
export class CassetteRecorder {
|
|
44
|
+
entries = [];
|
|
45
|
+
contextName = "";
|
|
46
|
+
setContextName(name) {
|
|
47
|
+
this.contextName = name;
|
|
48
|
+
}
|
|
49
|
+
recordModelCall(request, response) {
|
|
50
|
+
this.entries.push({
|
|
51
|
+
type: "model-call",
|
|
52
|
+
timestamp: new Date().toISOString(),
|
|
53
|
+
request,
|
|
54
|
+
response,
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
recordToolCall(request, response) {
|
|
58
|
+
this.entries.push({
|
|
59
|
+
type: "tool-call",
|
|
60
|
+
timestamp: new Date().toISOString(),
|
|
61
|
+
request,
|
|
62
|
+
response,
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
recordDelegation(request, response) {
|
|
66
|
+
this.entries.push({
|
|
67
|
+
type: "delegation",
|
|
68
|
+
timestamp: new Date().toISOString(),
|
|
69
|
+
request,
|
|
70
|
+
response,
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
toCassette() {
|
|
74
|
+
return {
|
|
75
|
+
contextName: this.contextName,
|
|
76
|
+
recordedAt: new Date().toISOString(),
|
|
77
|
+
entries: [...this.entries],
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
reset() {
|
|
81
|
+
this.entries = [];
|
|
82
|
+
this.contextName = "";
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* A cassette replayer that provides pre-recorded responses.
|
|
87
|
+
*
|
|
88
|
+
* @category Testing
|
|
89
|
+
*/
|
|
90
|
+
export class CassetteReplayer {
|
|
91
|
+
modelCallIndex = 0;
|
|
92
|
+
toolCallIndex = 0;
|
|
93
|
+
delegationIndex = 0;
|
|
94
|
+
modelCalls;
|
|
95
|
+
toolCalls;
|
|
96
|
+
delegationCalls;
|
|
97
|
+
constructor(cassette) {
|
|
98
|
+
this.modelCalls = cassette.entries.filter((e) => e.type === "model-call");
|
|
99
|
+
this.toolCalls = cassette.entries.filter((e) => e.type === "tool-call");
|
|
100
|
+
this.delegationCalls = cassette.entries.filter((e) => e.type === "delegation");
|
|
101
|
+
}
|
|
102
|
+
nextModelResponse() {
|
|
103
|
+
const entry = this.modelCalls[this.modelCallIndex];
|
|
104
|
+
this.modelCallIndex++;
|
|
105
|
+
return entry?.response;
|
|
106
|
+
}
|
|
107
|
+
nextToolResponse() {
|
|
108
|
+
const entry = this.toolCalls[this.toolCallIndex];
|
|
109
|
+
this.toolCallIndex++;
|
|
110
|
+
return entry?.response;
|
|
111
|
+
}
|
|
112
|
+
nextDelegationResponse() {
|
|
113
|
+
const entry = this.delegationCalls[this.delegationIndex];
|
|
114
|
+
this.delegationIndex++;
|
|
115
|
+
return entry?.response;
|
|
116
|
+
}
|
|
117
|
+
get exhausted() {
|
|
118
|
+
return (this.modelCallIndex >= this.modelCalls.length &&
|
|
119
|
+
this.toolCallIndex >= this.toolCalls.length &&
|
|
120
|
+
this.delegationIndex >= this.delegationCalls.length);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
//# sourceMappingURL=cassette.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cassette.js","sourceRoot":"","sources":["../../src/testing/cassette.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/testing/index.ts"],"names":[],"mappings":"AAAA,cAAc,0BAA0B,CAAC;AACzC,cAAc,wBAAwB,CAAC;AACvC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,eAAe,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/testing/index.ts"],"names":[],"mappings":"AAAA,cAAc,0BAA0B,CAAC;AACzC,cAAc,wBAAwB,CAAC;AACvC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,eAAe,CAAC"}
|