@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.
Files changed (193) hide show
  1. package/dist/engine/context-loader.d.ts +31 -0
  2. package/dist/engine/context-loader.d.ts.map +1 -0
  3. package/dist/engine/context-loader.js +90 -0
  4. package/dist/engine/context-loader.js.map +1 -0
  5. package/dist/engine/index.d.ts +6 -0
  6. package/dist/engine/index.d.ts.map +1 -0
  7. package/dist/engine/index.js +6 -0
  8. package/dist/engine/index.js.map +1 -0
  9. package/dist/engine/runner.d.ts +92 -0
  10. package/dist/engine/runner.d.ts.map +1 -0
  11. package/dist/engine/runner.js +852 -0
  12. package/dist/engine/runner.js.map +1 -0
  13. package/dist/engine/schema-validator.d.ts +32 -0
  14. package/dist/engine/schema-validator.d.ts.map +1 -0
  15. package/dist/engine/schema-validator.js +69 -0
  16. package/dist/engine/schema-validator.js.map +1 -0
  17. package/dist/engine/system-config-loader.d.ts +39 -0
  18. package/dist/engine/system-config-loader.d.ts.map +1 -0
  19. package/dist/engine/system-config-loader.js +80 -0
  20. package/dist/engine/system-config-loader.js.map +1 -0
  21. package/dist/engine/types.d.ts +324 -0
  22. package/dist/engine/types.d.ts.map +1 -0
  23. package/dist/engine/types.js +10 -0
  24. package/dist/engine/types.js.map +1 -0
  25. package/dist/evals/index.d.ts +3 -0
  26. package/dist/evals/index.d.ts.map +1 -0
  27. package/dist/evals/index.js +3 -0
  28. package/dist/evals/index.js.map +1 -0
  29. package/dist/evals/scorer.d.ts +23 -0
  30. package/dist/evals/scorer.d.ts.map +1 -0
  31. package/dist/evals/scorer.js +133 -0
  32. package/dist/evals/scorer.js.map +1 -0
  33. package/dist/evals/types.d.ts +128 -0
  34. package/dist/evals/types.d.ts.map +1 -0
  35. package/dist/evals/types.js +11 -0
  36. package/dist/evals/types.js.map +1 -0
  37. package/dist/extensions/builtin.d.ts +44 -0
  38. package/dist/extensions/builtin.d.ts.map +1 -0
  39. package/dist/extensions/builtin.js +66 -0
  40. package/dist/extensions/builtin.js.map +1 -0
  41. package/dist/extensions/index.d.ts +4 -0
  42. package/dist/extensions/index.d.ts.map +1 -0
  43. package/dist/extensions/index.js +4 -0
  44. package/dist/extensions/index.js.map +1 -0
  45. package/dist/extensions/progress-loggers/file-logger.d.ts +27 -0
  46. package/dist/extensions/progress-loggers/file-logger.d.ts.map +1 -0
  47. package/dist/extensions/progress-loggers/file-logger.js +54 -0
  48. package/dist/extensions/progress-loggers/file-logger.js.map +1 -0
  49. package/dist/extensions/registry.d.ts +74 -0
  50. package/dist/extensions/registry.d.ts.map +1 -0
  51. package/dist/extensions/registry.js +126 -0
  52. package/dist/extensions/registry.js.map +1 -0
  53. package/dist/extensions/types.d.ts +78 -0
  54. package/dist/extensions/types.d.ts.map +1 -0
  55. package/dist/extensions/types.js +7 -0
  56. package/dist/extensions/types.js.map +1 -0
  57. package/dist/index.d.ts +10 -0
  58. package/dist/index.d.ts.map +1 -0
  59. package/dist/index.js +10 -0
  60. package/dist/index.js.map +1 -0
  61. package/dist/mounts/hydrator.d.ts +46 -0
  62. package/dist/mounts/hydrator.d.ts.map +1 -0
  63. package/dist/mounts/hydrator.js +142 -0
  64. package/dist/mounts/hydrator.js.map +1 -0
  65. package/dist/mounts/index.d.ts +4 -0
  66. package/dist/mounts/index.d.ts.map +1 -0
  67. package/dist/mounts/index.js +4 -0
  68. package/dist/mounts/index.js.map +1 -0
  69. package/dist/mounts/interpolation.d.ts +33 -0
  70. package/dist/mounts/interpolation.d.ts.map +1 -0
  71. package/dist/mounts/interpolation.js +59 -0
  72. package/dist/mounts/interpolation.js.map +1 -0
  73. package/dist/mounts/types.d.ts +80 -0
  74. package/dist/mounts/types.d.ts.map +1 -0
  75. package/dist/mounts/types.js +10 -0
  76. package/dist/mounts/types.js.map +1 -0
  77. package/dist/policies/enforcer.d.ts +23 -0
  78. package/dist/policies/enforcer.d.ts.map +1 -0
  79. package/dist/policies/enforcer.js +111 -0
  80. package/dist/policies/enforcer.js.map +1 -0
  81. package/dist/policies/index.d.ts +3 -0
  82. package/dist/policies/index.d.ts.map +1 -0
  83. package/dist/policies/index.js +3 -0
  84. package/dist/policies/index.js.map +1 -0
  85. package/dist/policies/types.d.ts +87 -0
  86. package/dist/policies/types.d.ts.map +1 -0
  87. package/dist/policies/types.js +11 -0
  88. package/dist/policies/types.js.map +1 -0
  89. package/dist/protocols/a2a/a2a-transport.d.ts +40 -0
  90. package/dist/protocols/a2a/a2a-transport.d.ts.map +1 -0
  91. package/dist/protocols/a2a/a2a-transport.js +212 -0
  92. package/dist/protocols/a2a/a2a-transport.js.map +1 -0
  93. package/dist/protocols/a2a/index.d.ts +3 -0
  94. package/dist/protocols/a2a/index.d.ts.map +1 -0
  95. package/dist/protocols/a2a/index.js +2 -0
  96. package/dist/protocols/a2a/index.js.map +1 -0
  97. package/dist/protocols/agent-transport.d.ts +101 -0
  98. package/dist/protocols/agent-transport.d.ts.map +1 -0
  99. package/dist/protocols/agent-transport.js +11 -0
  100. package/dist/protocols/agent-transport.js.map +1 -0
  101. package/dist/protocols/index.d.ts +5 -0
  102. package/dist/protocols/index.d.ts.map +1 -0
  103. package/dist/protocols/index.js +5 -0
  104. package/dist/protocols/index.js.map +1 -0
  105. package/dist/protocols/mcp/index.d.ts +2 -0
  106. package/dist/protocols/mcp/index.d.ts.map +1 -0
  107. package/dist/protocols/mcp/index.js +2 -0
  108. package/dist/protocols/mcp/index.js.map +1 -0
  109. package/dist/protocols/mcp/mcp-tool-invoker.d.ts +30 -0
  110. package/dist/protocols/mcp/mcp-tool-invoker.d.ts.map +1 -0
  111. package/dist/protocols/mcp/mcp-tool-invoker.js +121 -0
  112. package/dist/protocols/mcp/mcp-tool-invoker.js.map +1 -0
  113. package/dist/protocols/tool-invoker.d.ts +91 -0
  114. package/dist/protocols/tool-invoker.d.ts.map +1 -0
  115. package/dist/protocols/tool-invoker.js +11 -0
  116. package/dist/protocols/tool-invoker.js.map +1 -0
  117. package/dist/providers/index.d.ts +4 -0
  118. package/dist/providers/index.d.ts.map +1 -0
  119. package/dist/providers/index.js +4 -0
  120. package/dist/providers/index.js.map +1 -0
  121. package/dist/providers/model-provider.d.ts +132 -0
  122. package/dist/providers/model-provider.d.ts.map +1 -0
  123. package/dist/providers/model-provider.js +10 -0
  124. package/dist/providers/model-provider.js.map +1 -0
  125. package/dist/providers/ollama/index.d.ts +3 -0
  126. package/dist/providers/ollama/index.d.ts.map +1 -0
  127. package/dist/providers/ollama/index.js +2 -0
  128. package/dist/providers/ollama/index.js.map +1 -0
  129. package/dist/providers/ollama/ollama-provider.d.ts +41 -0
  130. package/dist/providers/ollama/ollama-provider.d.ts.map +1 -0
  131. package/dist/providers/ollama/ollama-provider.js +113 -0
  132. package/dist/providers/ollama/ollama-provider.js.map +1 -0
  133. package/dist/providers/openai/index.d.ts +3 -0
  134. package/dist/providers/openai/index.d.ts.map +1 -0
  135. package/dist/providers/openai/index.js +2 -0
  136. package/dist/providers/openai/index.js.map +1 -0
  137. package/dist/providers/openai/openai-provider.d.ts +41 -0
  138. package/dist/providers/openai/openai-provider.d.ts.map +1 -0
  139. package/dist/providers/openai/openai-provider.js +150 -0
  140. package/dist/providers/openai/openai-provider.js.map +1 -0
  141. package/dist/testing/cassette.d.ts +88 -0
  142. package/dist/testing/cassette.d.ts.map +1 -0
  143. package/dist/testing/cassette.js +123 -0
  144. package/dist/testing/cassette.js.map +1 -0
  145. package/dist/testing/index.d.ts +5 -0
  146. package/dist/testing/index.d.ts.map +1 -0
  147. package/dist/testing/index.js +5 -0
  148. package/dist/testing/index.js.map +1 -0
  149. package/dist/testing/mock-agent-transport.d.ts +49 -0
  150. package/dist/testing/mock-agent-transport.d.ts.map +1 -0
  151. package/dist/testing/mock-agent-transport.js +71 -0
  152. package/dist/testing/mock-agent-transport.js.map +1 -0
  153. package/dist/testing/mock-model-provider.d.ts +69 -0
  154. package/dist/testing/mock-model-provider.d.ts.map +1 -0
  155. package/dist/testing/mock-model-provider.js +92 -0
  156. package/dist/testing/mock-model-provider.js.map +1 -0
  157. package/dist/testing/mock-tool-invoker.d.ts +65 -0
  158. package/dist/testing/mock-tool-invoker.d.ts.map +1 -0
  159. package/dist/testing/mock-tool-invoker.js +85 -0
  160. package/dist/testing/mock-tool-invoker.js.map +1 -0
  161. package/dist/tracing/collector.d.ts +75 -0
  162. package/dist/tracing/collector.d.ts.map +1 -0
  163. package/dist/tracing/collector.js +106 -0
  164. package/dist/tracing/collector.js.map +1 -0
  165. package/dist/tracing/exporters/console.d.ts +17 -0
  166. package/dist/tracing/exporters/console.d.ts.map +1 -0
  167. package/dist/tracing/exporters/console.js +76 -0
  168. package/dist/tracing/exporters/console.js.map +1 -0
  169. package/dist/tracing/exporters/index.d.ts +4 -0
  170. package/dist/tracing/exporters/index.d.ts.map +1 -0
  171. package/dist/tracing/exporters/index.js +3 -0
  172. package/dist/tracing/exporters/index.js.map +1 -0
  173. package/dist/tracing/exporters/json-file.d.ts +30 -0
  174. package/dist/tracing/exporters/json-file.d.ts.map +1 -0
  175. package/dist/tracing/exporters/json-file.js +28 -0
  176. package/dist/tracing/exporters/json-file.js.map +1 -0
  177. package/dist/tracing/formatter.d.ts +16 -0
  178. package/dist/tracing/formatter.d.ts.map +1 -0
  179. package/dist/tracing/formatter.js +81 -0
  180. package/dist/tracing/formatter.js.map +1 -0
  181. package/dist/tracing/graph.d.ts +17 -0
  182. package/dist/tracing/graph.d.ts.map +1 -0
  183. package/dist/tracing/graph.js +116 -0
  184. package/dist/tracing/graph.js.map +1 -0
  185. package/dist/tracing/index.d.ts +6 -0
  186. package/dist/tracing/index.d.ts.map +1 -0
  187. package/dist/tracing/index.js +6 -0
  188. package/dist/tracing/index.js.map +1 -0
  189. package/dist/tracing/types.d.ts +124 -0
  190. package/dist/tracing/types.d.ts.map +1 -0
  191. package/dist/tracing/types.js +11 -0
  192. package/dist/tracing/types.js.map +1 -0
  193. 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,3 @@
1
+ export { OpenAIProvider } from "./openai-provider.js";
2
+ export type { OpenAIProviderConfig } from "./openai-provider.js";
3
+ //# sourceMappingURL=index.d.ts.map
@@ -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,2 @@
1
+ export { OpenAIProvider } from "./openai-provider.js";
2
+ //# sourceMappingURL=index.js.map
@@ -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,5 @@
1
+ export * from "./mock-model-provider.js";
2
+ export * from "./mock-tool-invoker.js";
3
+ export * from "./mock-agent-transport.js";
4
+ export * from "./cassette.js";
5
+ //# sourceMappingURL=index.d.ts.map
@@ -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,5 @@
1
+ export * from "./mock-model-provider.js";
2
+ export * from "./mock-tool-invoker.js";
3
+ export * from "./mock-agent-transport.js";
4
+ export * from "./cassette.js";
5
+ //# sourceMappingURL=index.js.map
@@ -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"}