@axlsdk/testing 0.1.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/README.md ADDED
@@ -0,0 +1,142 @@
1
+ # axl-testing
2
+
3
+ Testing utilities for Axl agentic workflows. Provides deterministic mocks and assertions for unit testing workflows without hitting real LLM APIs.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install axl-testing --save-dev
9
+ ```
10
+
11
+ ## API
12
+
13
+ ### `MockProvider`
14
+
15
+ Mock LLM provider with multiple response modes:
16
+
17
+ ```typescript
18
+ import { MockProvider } from 'axl-testing';
19
+
20
+ // Sequence mode — return responses in order
21
+ const provider = MockProvider.sequence(['Hello!', 'World!']);
22
+
23
+ // Echo mode — return the user's prompt back
24
+ const provider = MockProvider.echo();
25
+
26
+ // JSON mode — return structured data
27
+ const provider = MockProvider.json({ answer: 42, confidence: 0.95 });
28
+
29
+ // Replay mode — replay from a recorded file
30
+ const provider = MockProvider.replay('./fixtures/conversation.json');
31
+
32
+ // Function mode — custom response logic
33
+ const provider = MockProvider.fn((messages, options) => {
34
+ const lastMessage = messages[messages.length - 1];
35
+ return `You said: ${lastMessage.content}`;
36
+ });
37
+ ```
38
+
39
+ MockProvider also supports tool call simulation:
40
+
41
+ ```typescript
42
+ const provider = MockProvider.sequence([
43
+ {
44
+ content: '',
45
+ tool_calls: [{
46
+ id: 'call_1',
47
+ type: 'function',
48
+ function: { name: 'calculator', arguments: '{"expression":"2+2"}' },
49
+ }],
50
+ },
51
+ 'The answer is 4.',
52
+ ]);
53
+ ```
54
+
55
+ ### `MockTool`
56
+
57
+ Wrap a tool to intercept and record calls:
58
+
59
+ ```typescript
60
+ import { MockTool } from 'axl-testing';
61
+ import { calculator } from './tools';
62
+
63
+ const mock = new MockTool(calculator);
64
+
65
+ // Use in agent
66
+ const myAgent = agent({ model: 'test:mock', system: 'Test', tools: [mock] });
67
+
68
+ // After execution, inspect calls
69
+ console.log(mock.calls); // [{ input: { expression: '2+2' }, output: { result: 4 } }]
70
+ ```
71
+
72
+ ### `AxlTestRuntime`
73
+
74
+ Test runtime that mirrors `WorkflowContext` for deterministic testing:
75
+
76
+ ```typescript
77
+ import { AxlTestRuntime, MockProvider } from 'axl-testing';
78
+
79
+ const provider = MockProvider.sequence(['42']);
80
+ const runtime = new AxlTestRuntime({ provider });
81
+
82
+ // Ask an agent
83
+ const result = await runtime.ask(myAgent, 'What is the answer?');
84
+ expect(result).toBe('42');
85
+
86
+ // Inspect recorded calls
87
+ expect(runtime.agentCalls()).toHaveLength(1);
88
+ expect(runtime.toolCalls()).toHaveLength(0);
89
+ expect(runtime.totalCost()).toBe(0);
90
+
91
+ // Test spawn
92
+ const results = await runtime.spawn(3, async (i) => runtime.ask(myAgent, `Q${i}`));
93
+ expect(results.filter(r => r.ok)).toHaveLength(3);
94
+
95
+ // Test vote
96
+ const winner = runtime.vote(results, { strategy: 'majority', key: 'answer' });
97
+
98
+ // Test budget
99
+ const budgeted = await runtime.budget({ cost: '$1.00' }, async () => {
100
+ return runtime.ask(myAgent, 'Hello');
101
+ });
102
+ expect(budgeted.budgetExceeded).toBe(false);
103
+ ```
104
+
105
+ ### Assertions
106
+
107
+ ```typescript
108
+ const runtime = new AxlTestRuntime({ provider });
109
+
110
+ // After running your workflow:
111
+ runtime.agentCalls(); // All recorded agent invocations
112
+ runtime.toolCalls(); // All recorded tool invocations
113
+ runtime.totalCost(); // Cumulative cost
114
+ runtime.steps(); // All recorded steps (agents + tools)
115
+ runtime.traces(); // All trace events
116
+ ```
117
+
118
+ ## Example: Testing a Workflow
119
+
120
+ ```typescript
121
+ import { describe, it, expect } from 'vitest';
122
+ import { AxlTestRuntime, MockProvider } from 'axl-testing';
123
+ import { myAgent } from '../agents';
124
+
125
+ describe('my workflow', () => {
126
+ it('returns structured output', async () => {
127
+ const provider = MockProvider.json({ answer: 42 });
128
+ const runtime = new AxlTestRuntime({ provider });
129
+
130
+ const result = await runtime.ask(myAgent, 'What is the answer?', {
131
+ schema: z.object({ answer: z.number() }),
132
+ });
133
+
134
+ expect(result).toEqual({ answer: 42 });
135
+ expect(runtime.agentCalls()).toHaveLength(1);
136
+ });
137
+ });
138
+ ```
139
+
140
+ ## License
141
+
142
+ [Apache 2.0](../../LICENSE)
package/dist/index.cjs ADDED
@@ -0,0 +1,353 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/index.ts
31
+ var index_exports = {};
32
+ __export(index_exports, {
33
+ AxlTestRuntime: () => AxlTestRuntime,
34
+ MockProvider: () => MockProvider,
35
+ MockTool: () => MockTool
36
+ });
37
+ module.exports = __toCommonJS(index_exports);
38
+
39
+ // src/mock-provider.ts
40
+ var import_node_fs = require("fs");
41
+ function randomAlphanumeric(length) {
42
+ const chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
43
+ let result = "";
44
+ for (let i = 0; i < length; i++) {
45
+ result += chars[Math.floor(Math.random() * chars.length)];
46
+ }
47
+ return result;
48
+ }
49
+ function generateFromSchema(schema) {
50
+ const def = schema?._def;
51
+ if (!def) return {};
52
+ switch (def.typeName) {
53
+ case "ZodString": {
54
+ const length = 8 + Math.floor(Math.random() * 13);
55
+ return randomAlphanumeric(length);
56
+ }
57
+ case "ZodNumber": {
58
+ const checks = def.checks ?? [];
59
+ let min = 0;
60
+ let max = 100;
61
+ for (const check of checks) {
62
+ if (check.kind === "min") min = check.value;
63
+ if (check.kind === "max") max = check.value;
64
+ }
65
+ return min + Math.random() * (max - min);
66
+ }
67
+ case "ZodBoolean":
68
+ return Math.random() < 0.5;
69
+ case "ZodArray": {
70
+ const count = 1 + Math.floor(Math.random() * 3);
71
+ const items = [];
72
+ for (let i = 0; i < count; i++) {
73
+ items.push(generateFromSchema(def.type));
74
+ }
75
+ return items;
76
+ }
77
+ case "ZodObject": {
78
+ const shape = def.shape?.() ?? {};
79
+ const obj = {};
80
+ for (const [key, value] of Object.entries(shape)) {
81
+ obj[key] = generateFromSchema(value);
82
+ }
83
+ return obj;
84
+ }
85
+ case "ZodOptional": {
86
+ if (Math.random() < 0.5) return void 0;
87
+ return generateFromSchema(def.innerType);
88
+ }
89
+ case "ZodDefault":
90
+ return def.defaultValue();
91
+ case "ZodEnum": {
92
+ const values = def.values ?? [];
93
+ if (values.length === 0) return "";
94
+ return values[Math.floor(Math.random() * values.length)];
95
+ }
96
+ case "ZodNullable":
97
+ return null;
98
+ default:
99
+ return {};
100
+ }
101
+ }
102
+ var MockProvider = class _MockProvider {
103
+ constructor(responseFn) {
104
+ this.responseFn = responseFn;
105
+ }
106
+ name = "mock";
107
+ _calls = [];
108
+ get calls() {
109
+ return this._calls;
110
+ }
111
+ async chat(messages, options) {
112
+ this._calls.push({ messages, options });
113
+ return this.responseFn(messages, this._calls.length - 1);
114
+ }
115
+ async *stream(messages, options) {
116
+ const response = await this.chat(messages, options);
117
+ yield { type: "text_delta", content: response.content };
118
+ yield { type: "done", usage: response.usage };
119
+ }
120
+ static sequence(responses) {
121
+ return new _MockProvider((_messages, callIndex) => {
122
+ if (callIndex >= responses.length) {
123
+ throw new Error(
124
+ `MockProvider.sequence: no response for call index ${callIndex}. Only ${responses.length} responses defined.`
125
+ );
126
+ }
127
+ return {
128
+ content: responses[callIndex].content,
129
+ tool_calls: responses[callIndex].tool_calls,
130
+ usage: { prompt_tokens: 10, completion_tokens: 10, total_tokens: 20 },
131
+ cost: 0
132
+ };
133
+ });
134
+ }
135
+ static echo() {
136
+ return new _MockProvider((messages) => {
137
+ const lastUser = [...messages].reverse().find((m) => m.role === "user");
138
+ return {
139
+ content: lastUser?.content ?? "",
140
+ usage: { prompt_tokens: 10, completion_tokens: 10, total_tokens: 20 },
141
+ cost: 0
142
+ };
143
+ });
144
+ }
145
+ static json(schema) {
146
+ return new _MockProvider(() => ({
147
+ content: JSON.stringify(generateFromSchema(schema)),
148
+ usage: { prompt_tokens: 10, completion_tokens: 10, total_tokens: 20 },
149
+ cost: 0
150
+ }));
151
+ }
152
+ static replay(source) {
153
+ const data = typeof source === "string" ? JSON.parse((0, import_node_fs.readFileSync)(source, "utf-8")) : source;
154
+ return new _MockProvider((_messages, callIndex) => {
155
+ if (callIndex >= data.length) {
156
+ throw new Error(`MockProvider.replay: no recorded response for call index ${callIndex}`);
157
+ }
158
+ return data[callIndex];
159
+ });
160
+ }
161
+ static fn(handler) {
162
+ return new _MockProvider((messages, callIndex) => ({
163
+ ...handler(messages, callIndex),
164
+ usage: { prompt_tokens: 10, completion_tokens: 10, total_tokens: 20 },
165
+ cost: 0
166
+ }));
167
+ }
168
+ };
169
+
170
+ // src/mock-tool.ts
171
+ var MockTool = class _MockTool {
172
+ constructor(name, handler) {
173
+ this.name = name;
174
+ this.handler = handler;
175
+ }
176
+ _calls = [];
177
+ get calls() {
178
+ return this._calls;
179
+ }
180
+ async execute(input) {
181
+ this._calls.push({ input });
182
+ return this.handler(input);
183
+ }
184
+ static create(name, handler) {
185
+ return new _MockTool(name, handler);
186
+ }
187
+ };
188
+
189
+ // src/test-runtime.ts
190
+ var import_axl = require("@axlsdk/axl");
191
+ function generateExecutionId() {
192
+ return `test-${Date.now()}-${Math.random().toString(36).slice(2, 10)}`;
193
+ }
194
+ var AxlTestRuntime = class {
195
+ workflows = /* @__PURE__ */ new Map();
196
+ mockProviders = /* @__PURE__ */ new Map();
197
+ mockToolMap = /* @__PURE__ */ new Map();
198
+ _toolCalls = [];
199
+ _agentCalls = [];
200
+ _steps = [];
201
+ _traceLog = [];
202
+ _totalCost = 0;
203
+ _stepCounter = 0;
204
+ recordPath;
205
+ recorded = [];
206
+ _executionId = generateExecutionId();
207
+ _humanDecisionHandler;
208
+ constructor(options) {
209
+ this.recordPath = options?.record;
210
+ this._humanDecisionHandler = options?.humanDecisions;
211
+ }
212
+ register(workflow) {
213
+ this.workflows.set(workflow.name, workflow);
214
+ }
215
+ mockProvider(name, provider) {
216
+ this.mockProviders.set(name, provider);
217
+ }
218
+ mockTool(name, handler) {
219
+ this.mockToolMap.set(name, MockTool.create(name, handler));
220
+ }
221
+ async execute(workflowName, input, options) {
222
+ const workflow = this.workflows.get(workflowName);
223
+ if (!workflow) throw new Error(`Workflow "${workflowName}" not registered`);
224
+ this._toolCalls = [];
225
+ this._agentCalls = [];
226
+ this._steps = [];
227
+ this._traceLog = [];
228
+ this._totalCost = 0;
229
+ this._stepCounter = 0;
230
+ this.recorded = [];
231
+ this._executionId = generateExecutionId();
232
+ const validated = workflow.inputSchema.parse(input);
233
+ const registry = new import_axl.ProviderRegistry();
234
+ registry.clearFactories();
235
+ for (const [name, provider] of this.mockProviders) {
236
+ registry.registerInstance(name, provider);
237
+ }
238
+ const defaultProvider = this.mockProviders.get("default");
239
+ if (defaultProvider) {
240
+ registry.setFallback(defaultProvider);
241
+ } else if (this.mockProviders.size === 1) {
242
+ const onlyProvider = this.mockProviders.values().next().value;
243
+ registry.setFallback(onlyProvider);
244
+ }
245
+ const toolOverrides = /* @__PURE__ */ new Map();
246
+ for (const [name, mockTool] of this.mockToolMap) {
247
+ toolOverrides.set(name, async (args) => {
248
+ return mockTool.execute(args);
249
+ });
250
+ }
251
+ this._recordStep("workflow_start", { workflow: workflowName, input: validated });
252
+ this._pushTrace({
253
+ type: "workflow_start",
254
+ workflow: workflowName,
255
+ data: { input: validated }
256
+ });
257
+ const init = {
258
+ input: validated,
259
+ executionId: this._executionId,
260
+ metadata: options?.metadata,
261
+ config: {},
262
+ providerRegistry: registry,
263
+ stateStore: new import_axl.MemoryStore(),
264
+ toolOverrides: toolOverrides.size > 0 ? toolOverrides : void 0,
265
+ awaitHumanHandler: this._humanDecisionHandler ? (opts) => this._humanDecisionHandler(opts) : void 0,
266
+ onTrace: (event) => {
267
+ this._traceLog.push(event);
268
+ this._stepCounter++;
269
+ this._steps.push({ step: this._stepCounter, type: event.type, data: event.data });
270
+ if (event.type === "tool_call" && event.data) {
271
+ const { args, result: result2 } = event.data;
272
+ this._toolCalls.push({ name: event.tool, args, result: result2 });
273
+ }
274
+ if (event.cost) {
275
+ this._totalCost += event.cost;
276
+ }
277
+ if (event.type === "agent_call" && event.data) {
278
+ const { response } = event.data;
279
+ if (response !== void 0) {
280
+ this.recorded.push({
281
+ content: response,
282
+ usage: { prompt_tokens: 0, completion_tokens: 0, total_tokens: 0 },
283
+ cost: event.cost ?? 0
284
+ });
285
+ }
286
+ }
287
+ },
288
+ onAgentCallComplete: (call) => {
289
+ this._agentCalls.push({
290
+ agent: call.agent,
291
+ prompt: call.prompt,
292
+ response: call.response,
293
+ model: call.model,
294
+ cost: call.cost,
295
+ duration: call.duration,
296
+ promptVersion: call.promptVersion
297
+ });
298
+ }
299
+ };
300
+ const ctx = new import_axl.WorkflowContext(init);
301
+ const result = await workflow.handler(ctx);
302
+ if (workflow.outputSchema) workflow.outputSchema.parse(result);
303
+ this._recordStep("workflow_end", { workflow: workflowName, result });
304
+ this._pushTrace({
305
+ type: "workflow_end",
306
+ workflow: workflowName,
307
+ data: { result }
308
+ });
309
+ if (this.recordPath) await this._writeRecording();
310
+ return result;
311
+ }
312
+ toolCalls(name) {
313
+ return name ? this._toolCalls.filter((c) => c.name === name) : this._toolCalls;
314
+ }
315
+ agentCalls(name) {
316
+ return name ? this._agentCalls.filter((c) => c.agent === name) : this._agentCalls;
317
+ }
318
+ totalCost() {
319
+ return this._totalCost;
320
+ }
321
+ steps() {
322
+ return this._steps;
323
+ }
324
+ traceLog() {
325
+ return this._traceLog;
326
+ }
327
+ _recordStep(type, data) {
328
+ this._stepCounter++;
329
+ this._steps.push({ step: this._stepCounter, type, data });
330
+ }
331
+ _pushTrace(partial) {
332
+ this._traceLog.push({
333
+ executionId: this._executionId,
334
+ step: this._stepCounter,
335
+ timestamp: Date.now(),
336
+ ...partial
337
+ });
338
+ }
339
+ async _writeRecording() {
340
+ if (!this.recordPath) return;
341
+ const { writeFile, mkdir } = await import("fs/promises");
342
+ const { dirname } = await import("path");
343
+ await mkdir(dirname(this.recordPath), { recursive: true });
344
+ await writeFile(this.recordPath, JSON.stringify(this.recorded, null, 2), "utf8");
345
+ }
346
+ };
347
+ // Annotate the CommonJS export names for ESM import in node:
348
+ 0 && (module.exports = {
349
+ AxlTestRuntime,
350
+ MockProvider,
351
+ MockTool
352
+ });
353
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/mock-provider.ts","../src/mock-tool.ts","../src/test-runtime.ts"],"sourcesContent":["export { AxlTestRuntime } from './test-runtime.js';\nexport type { RecordedToolCall, RecordedAgentCall, RecordedStep } from './test-runtime.js';\nexport { MockProvider } from './mock-provider.js';\nexport { MockTool } from './mock-tool.js';\n","import { readFileSync } from 'node:fs';\nimport type { ChatMessage, ToolCallMessage, ProviderResponse, StreamChunk, Provider } from '@axlsdk/axl';\n\nfunction randomAlphanumeric(length: number): string {\n const chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';\n let result = '';\n for (let i = 0; i < length; i++) {\n result += chars[Math.floor(Math.random() * chars.length)];\n }\n return result;\n}\n\nfunction generateFromSchema(schema: any): unknown {\n const def = schema?._def;\n if (!def) return {};\n switch (def.typeName) {\n case 'ZodString': {\n const length = 8 + Math.floor(Math.random() * 13); // 8-20 chars\n return randomAlphanumeric(length);\n }\n case 'ZodNumber': {\n const checks: any[] = def.checks ?? [];\n let min = 0;\n let max = 100;\n for (const check of checks) {\n if (check.kind === 'min') min = check.value;\n if (check.kind === 'max') max = check.value;\n }\n return min + Math.random() * (max - min);\n }\n case 'ZodBoolean':\n return Math.random() < 0.5;\n case 'ZodArray': {\n const count = 1 + Math.floor(Math.random() * 3); // 1-3 items\n const items: unknown[] = [];\n for (let i = 0; i < count; i++) {\n items.push(generateFromSchema(def.type));\n }\n return items;\n }\n case 'ZodObject': {\n const shape = def.shape?.() ?? {};\n const obj: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(shape)) {\n obj[key] = generateFromSchema(value);\n }\n return obj;\n }\n case 'ZodOptional': {\n if (Math.random() < 0.5) return undefined;\n return generateFromSchema(def.innerType);\n }\n case 'ZodDefault':\n return def.defaultValue();\n case 'ZodEnum': {\n const values: unknown[] = def.values ?? [];\n if (values.length === 0) return '';\n return values[Math.floor(Math.random() * values.length)];\n }\n case 'ZodNullable':\n return null;\n default:\n return {};\n }\n}\n\nexport class MockProvider implements Provider {\n readonly name = 'mock';\n private _calls: { messages: ChatMessage[]; options: any }[] = [];\n\n private constructor(\n private responseFn: (messages: ChatMessage[], callIndex: number) => ProviderResponse,\n ) {}\n\n get calls() {\n return this._calls;\n }\n\n async chat(messages: ChatMessage[], options: any): Promise<ProviderResponse> {\n this._calls.push({ messages, options });\n return this.responseFn(messages, this._calls.length - 1);\n }\n\n async *stream(messages: ChatMessage[], options: any): AsyncGenerator<StreamChunk> {\n const response = await this.chat(messages, options);\n yield { type: 'text_delta', content: response.content };\n yield { type: 'done', usage: response.usage };\n }\n\n static sequence(\n responses: Array<{ content: string; tool_calls?: ToolCallMessage[] }>,\n ): MockProvider {\n return new MockProvider((_messages, callIndex) => {\n if (callIndex >= responses.length) {\n throw new Error(\n `MockProvider.sequence: no response for call index ${callIndex}. Only ${responses.length} responses defined.`,\n );\n }\n return {\n content: responses[callIndex].content,\n tool_calls: responses[callIndex].tool_calls,\n usage: { prompt_tokens: 10, completion_tokens: 10, total_tokens: 20 },\n cost: 0,\n };\n });\n }\n\n static echo(): MockProvider {\n return new MockProvider((messages) => {\n const lastUser = [...messages].reverse().find((m) => m.role === 'user');\n return {\n content: lastUser?.content ?? '',\n usage: { prompt_tokens: 10, completion_tokens: 10, total_tokens: 20 },\n cost: 0,\n };\n });\n }\n\n static json(schema: any): MockProvider {\n return new MockProvider(() => ({\n content: JSON.stringify(generateFromSchema(schema)),\n usage: { prompt_tokens: 10, completion_tokens: 10, total_tokens: 20 },\n cost: 0,\n }));\n }\n\n static replay(source: string | ProviderResponse[]): MockProvider {\n const data =\n typeof source === 'string'\n ? (JSON.parse(readFileSync(source, 'utf-8')) as ProviderResponse[])\n : source;\n return new MockProvider((_messages, callIndex) => {\n if (callIndex >= data.length) {\n throw new Error(`MockProvider.replay: no recorded response for call index ${callIndex}`);\n }\n return data[callIndex];\n });\n }\n\n static fn(\n handler: (\n messages: ChatMessage[],\n callIndex: number,\n ) => { content: string; tool_calls?: ToolCallMessage[] },\n ): MockProvider {\n return new MockProvider((messages, callIndex) => ({\n ...handler(messages, callIndex),\n usage: { prompt_tokens: 10, completion_tokens: 10, total_tokens: 20 },\n cost: 0,\n }));\n }\n}\n","export class MockTool {\n private _calls: { input: unknown }[] = [];\n\n constructor(\n readonly name: string,\n private handler: (input: any) => unknown | Promise<unknown>,\n ) {}\n\n get calls() {\n return this._calls;\n }\n\n async execute(input: unknown): Promise<unknown> {\n this._calls.push({ input });\n return this.handler(input);\n }\n\n static create(name: string, handler: (input: any) => unknown | Promise<unknown>): MockTool {\n return new MockTool(name, handler);\n }\n}\n","import { MockProvider } from './mock-provider.js';\nimport { MockTool } from './mock-tool.js';\nimport type { TraceEvent, AwaitHumanOptions, HumanDecision, ProviderResponse } from '@axlsdk/axl';\nimport { WorkflowContext, MemoryStore, ProviderRegistry } from '@axlsdk/axl';\nimport type { WorkflowContextInit } from '@axlsdk/axl';\n\ninterface WorkflowLike {\n readonly name: string;\n readonly inputSchema: any;\n readonly outputSchema: any | undefined;\n readonly handler: (ctx: any) => Promise<any>;\n}\n\nexport type RecordedToolCall = { name: string; args: unknown; result: unknown };\nexport type RecordedAgentCall = {\n agent: string;\n prompt: string;\n response: string;\n model?: string;\n cost?: number;\n duration?: number;\n promptVersion?: string;\n};\nexport type RecordedStep = { step: number; type: string; data: unknown };\n\nfunction generateExecutionId(): string {\n return `test-${Date.now()}-${Math.random().toString(36).slice(2, 10)}`;\n}\n\nexport type AxlTestRuntimeOptions = {\n record?: string;\n humanDecisions?: (options: AwaitHumanOptions) => HumanDecision;\n};\n\nexport class AxlTestRuntime {\n private workflows = new Map<string, WorkflowLike>();\n private mockProviders = new Map<string, MockProvider>();\n private mockToolMap = new Map<string, MockTool>();\n private _toolCalls: RecordedToolCall[] = [];\n private _agentCalls: RecordedAgentCall[] = [];\n private _steps: RecordedStep[] = [];\n private _traceLog: TraceEvent[] = [];\n private _totalCost = 0;\n private _stepCounter = 0;\n private recordPath?: string;\n private recorded: ProviderResponse[] = [];\n private _executionId: string = generateExecutionId();\n private _humanDecisionHandler?: (options: AwaitHumanOptions) => HumanDecision;\n\n constructor(options?: AxlTestRuntimeOptions) {\n this.recordPath = options?.record;\n this._humanDecisionHandler = options?.humanDecisions;\n }\n\n register(workflow: WorkflowLike): void {\n this.workflows.set(workflow.name, workflow);\n }\n\n mockProvider(name: string, provider: MockProvider): void {\n this.mockProviders.set(name, provider);\n }\n\n mockTool(name: string, handler: (input: any) => unknown | Promise<unknown>): void {\n this.mockToolMap.set(name, MockTool.create(name, handler));\n }\n\n async execute(\n workflowName: string,\n input: unknown,\n options?: { metadata?: Record<string, unknown> },\n ): Promise<unknown> {\n const workflow = this.workflows.get(workflowName);\n if (!workflow) throw new Error(`Workflow \"${workflowName}\" not registered`);\n\n // Reset state between executions\n this._toolCalls = [];\n this._agentCalls = [];\n this._steps = [];\n this._traceLog = [];\n this._totalCost = 0;\n this._stepCounter = 0;\n this.recorded = [];\n this._executionId = generateExecutionId();\n\n const validated = workflow.inputSchema.parse(input);\n\n // Build ProviderRegistry from registered mock providers\n const registry = new ProviderRegistry();\n registry.clearFactories(); // Remove built-in factories; only use explicit mocks\n for (const [name, provider] of this.mockProviders) {\n registry.registerInstance(name, provider as any);\n }\n // Fallback resolution: 'default' key or single-provider\n const defaultProvider = this.mockProviders.get('default');\n if (defaultProvider) {\n registry.setFallback(defaultProvider as any);\n } else if (this.mockProviders.size === 1) {\n const onlyProvider = this.mockProviders.values().next().value!;\n registry.setFallback(onlyProvider as any);\n }\n\n // Build toolOverrides from mockToolMap\n const toolOverrides = new Map<string, (args: unknown) => Promise<unknown>>();\n for (const [name, mockTool] of this.mockToolMap) {\n toolOverrides.set(name, async (args: unknown) => {\n return mockTool.execute(args);\n });\n }\n\n // Record steps and traces via callbacks\n this._recordStep('workflow_start', { workflow: workflowName, input: validated });\n this._pushTrace({\n type: 'workflow_start',\n workflow: workflowName,\n data: { input: validated },\n });\n\n const init: WorkflowContextInit = {\n input: validated,\n executionId: this._executionId,\n metadata: options?.metadata,\n config: {},\n providerRegistry: registry,\n stateStore: new MemoryStore(),\n toolOverrides: toolOverrides.size > 0 ? toolOverrides : undefined,\n awaitHumanHandler: this._humanDecisionHandler\n ? (opts: AwaitHumanOptions) => this._humanDecisionHandler!(opts)\n : undefined,\n onTrace: (event: TraceEvent) => {\n this._traceLog.push(event);\n this._stepCounter++;\n this._steps.push({ step: this._stepCounter, type: event.type, data: event.data });\n\n if (event.type === 'tool_call' && event.data) {\n const { args, result } = event.data as { args: unknown; result: unknown };\n this._toolCalls.push({ name: event.tool!, args, result });\n }\n\n if (event.cost) {\n this._totalCost += event.cost;\n }\n\n // Track provider responses for recording\n if (event.type === 'agent_call' && event.data) {\n const { response } = event.data as { prompt?: string; response?: string };\n if (response !== undefined) {\n this.recorded.push({\n content: response,\n usage: { prompt_tokens: 0, completion_tokens: 0, total_tokens: 0 },\n cost: event.cost ?? 0,\n });\n }\n }\n },\n onAgentCallComplete: (call) => {\n this._agentCalls.push({\n agent: call.agent,\n prompt: call.prompt,\n response: call.response,\n model: call.model,\n cost: call.cost,\n duration: call.duration,\n promptVersion: call.promptVersion,\n });\n },\n };\n\n const ctx = new WorkflowContext(init);\n const result = await workflow.handler(ctx);\n\n // Validate output schema if defined\n if (workflow.outputSchema) workflow.outputSchema.parse(result);\n\n this._recordStep('workflow_end', { workflow: workflowName, result });\n this._pushTrace({\n type: 'workflow_end',\n workflow: workflowName,\n data: { result },\n });\n\n if (this.recordPath) await this._writeRecording();\n return result;\n }\n\n toolCalls(name?: string): RecordedToolCall[] {\n return name ? this._toolCalls.filter((c) => c.name === name) : this._toolCalls;\n }\n\n agentCalls(name?: string): RecordedAgentCall[] {\n return name ? this._agentCalls.filter((c) => c.agent === name) : this._agentCalls;\n }\n\n totalCost(): number {\n return this._totalCost;\n }\n steps(): RecordedStep[] {\n return this._steps;\n }\n traceLog(): TraceEvent[] {\n return this._traceLog;\n }\n\n private _recordStep(type: string, data: unknown): void {\n this._stepCounter++;\n this._steps.push({ step: this._stepCounter, type, data });\n }\n\n private _pushTrace(partial: Omit<TraceEvent, 'executionId' | 'step' | 'timestamp'>): void {\n this._traceLog.push({\n executionId: this._executionId,\n step: this._stepCounter,\n timestamp: Date.now(),\n ...partial,\n });\n }\n\n private async _writeRecording(): Promise<void> {\n if (!this.recordPath) return;\n const { writeFile, mkdir } = await import('node:fs/promises');\n const { dirname } = await import('node:path');\n await mkdir(dirname(this.recordPath), { recursive: true });\n await writeFile(this.recordPath, JSON.stringify(this.recorded, null, 2), 'utf8');\n }\n}\n"],"mappings":"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","names":["result"]}
@@ -0,0 +1,99 @@
1
+ import { Provider, ChatMessage, ProviderResponse, StreamChunk, ToolCallMessage, AwaitHumanOptions, HumanDecision, TraceEvent } from '@axlsdk/axl';
2
+
3
+ declare class MockProvider implements Provider {
4
+ private responseFn;
5
+ readonly name = "mock";
6
+ private _calls;
7
+ private constructor();
8
+ get calls(): {
9
+ messages: ChatMessage[];
10
+ options: any;
11
+ }[];
12
+ chat(messages: ChatMessage[], options: any): Promise<ProviderResponse>;
13
+ stream(messages: ChatMessage[], options: any): AsyncGenerator<StreamChunk>;
14
+ static sequence(responses: Array<{
15
+ content: string;
16
+ tool_calls?: ToolCallMessage[];
17
+ }>): MockProvider;
18
+ static echo(): MockProvider;
19
+ static json(schema: any): MockProvider;
20
+ static replay(source: string | ProviderResponse[]): MockProvider;
21
+ static fn(handler: (messages: ChatMessage[], callIndex: number) => {
22
+ content: string;
23
+ tool_calls?: ToolCallMessage[];
24
+ }): MockProvider;
25
+ }
26
+
27
+ interface WorkflowLike {
28
+ readonly name: string;
29
+ readonly inputSchema: any;
30
+ readonly outputSchema: any | undefined;
31
+ readonly handler: (ctx: any) => Promise<any>;
32
+ }
33
+ type RecordedToolCall = {
34
+ name: string;
35
+ args: unknown;
36
+ result: unknown;
37
+ };
38
+ type RecordedAgentCall = {
39
+ agent: string;
40
+ prompt: string;
41
+ response: string;
42
+ model?: string;
43
+ cost?: number;
44
+ duration?: number;
45
+ promptVersion?: string;
46
+ };
47
+ type RecordedStep = {
48
+ step: number;
49
+ type: string;
50
+ data: unknown;
51
+ };
52
+ type AxlTestRuntimeOptions = {
53
+ record?: string;
54
+ humanDecisions?: (options: AwaitHumanOptions) => HumanDecision;
55
+ };
56
+ declare class AxlTestRuntime {
57
+ private workflows;
58
+ private mockProviders;
59
+ private mockToolMap;
60
+ private _toolCalls;
61
+ private _agentCalls;
62
+ private _steps;
63
+ private _traceLog;
64
+ private _totalCost;
65
+ private _stepCounter;
66
+ private recordPath?;
67
+ private recorded;
68
+ private _executionId;
69
+ private _humanDecisionHandler?;
70
+ constructor(options?: AxlTestRuntimeOptions);
71
+ register(workflow: WorkflowLike): void;
72
+ mockProvider(name: string, provider: MockProvider): void;
73
+ mockTool(name: string, handler: (input: any) => unknown | Promise<unknown>): void;
74
+ execute(workflowName: string, input: unknown, options?: {
75
+ metadata?: Record<string, unknown>;
76
+ }): Promise<unknown>;
77
+ toolCalls(name?: string): RecordedToolCall[];
78
+ agentCalls(name?: string): RecordedAgentCall[];
79
+ totalCost(): number;
80
+ steps(): RecordedStep[];
81
+ traceLog(): TraceEvent[];
82
+ private _recordStep;
83
+ private _pushTrace;
84
+ private _writeRecording;
85
+ }
86
+
87
+ declare class MockTool {
88
+ readonly name: string;
89
+ private handler;
90
+ private _calls;
91
+ constructor(name: string, handler: (input: any) => unknown | Promise<unknown>);
92
+ get calls(): {
93
+ input: unknown;
94
+ }[];
95
+ execute(input: unknown): Promise<unknown>;
96
+ static create(name: string, handler: (input: any) => unknown | Promise<unknown>): MockTool;
97
+ }
98
+
99
+ export { AxlTestRuntime, MockProvider, MockTool, type RecordedAgentCall, type RecordedStep, type RecordedToolCall };
@@ -0,0 +1,99 @@
1
+ import { Provider, ChatMessage, ProviderResponse, StreamChunk, ToolCallMessage, AwaitHumanOptions, HumanDecision, TraceEvent } from '@axlsdk/axl';
2
+
3
+ declare class MockProvider implements Provider {
4
+ private responseFn;
5
+ readonly name = "mock";
6
+ private _calls;
7
+ private constructor();
8
+ get calls(): {
9
+ messages: ChatMessage[];
10
+ options: any;
11
+ }[];
12
+ chat(messages: ChatMessage[], options: any): Promise<ProviderResponse>;
13
+ stream(messages: ChatMessage[], options: any): AsyncGenerator<StreamChunk>;
14
+ static sequence(responses: Array<{
15
+ content: string;
16
+ tool_calls?: ToolCallMessage[];
17
+ }>): MockProvider;
18
+ static echo(): MockProvider;
19
+ static json(schema: any): MockProvider;
20
+ static replay(source: string | ProviderResponse[]): MockProvider;
21
+ static fn(handler: (messages: ChatMessage[], callIndex: number) => {
22
+ content: string;
23
+ tool_calls?: ToolCallMessage[];
24
+ }): MockProvider;
25
+ }
26
+
27
+ interface WorkflowLike {
28
+ readonly name: string;
29
+ readonly inputSchema: any;
30
+ readonly outputSchema: any | undefined;
31
+ readonly handler: (ctx: any) => Promise<any>;
32
+ }
33
+ type RecordedToolCall = {
34
+ name: string;
35
+ args: unknown;
36
+ result: unknown;
37
+ };
38
+ type RecordedAgentCall = {
39
+ agent: string;
40
+ prompt: string;
41
+ response: string;
42
+ model?: string;
43
+ cost?: number;
44
+ duration?: number;
45
+ promptVersion?: string;
46
+ };
47
+ type RecordedStep = {
48
+ step: number;
49
+ type: string;
50
+ data: unknown;
51
+ };
52
+ type AxlTestRuntimeOptions = {
53
+ record?: string;
54
+ humanDecisions?: (options: AwaitHumanOptions) => HumanDecision;
55
+ };
56
+ declare class AxlTestRuntime {
57
+ private workflows;
58
+ private mockProviders;
59
+ private mockToolMap;
60
+ private _toolCalls;
61
+ private _agentCalls;
62
+ private _steps;
63
+ private _traceLog;
64
+ private _totalCost;
65
+ private _stepCounter;
66
+ private recordPath?;
67
+ private recorded;
68
+ private _executionId;
69
+ private _humanDecisionHandler?;
70
+ constructor(options?: AxlTestRuntimeOptions);
71
+ register(workflow: WorkflowLike): void;
72
+ mockProvider(name: string, provider: MockProvider): void;
73
+ mockTool(name: string, handler: (input: any) => unknown | Promise<unknown>): void;
74
+ execute(workflowName: string, input: unknown, options?: {
75
+ metadata?: Record<string, unknown>;
76
+ }): Promise<unknown>;
77
+ toolCalls(name?: string): RecordedToolCall[];
78
+ agentCalls(name?: string): RecordedAgentCall[];
79
+ totalCost(): number;
80
+ steps(): RecordedStep[];
81
+ traceLog(): TraceEvent[];
82
+ private _recordStep;
83
+ private _pushTrace;
84
+ private _writeRecording;
85
+ }
86
+
87
+ declare class MockTool {
88
+ readonly name: string;
89
+ private handler;
90
+ private _calls;
91
+ constructor(name: string, handler: (input: any) => unknown | Promise<unknown>);
92
+ get calls(): {
93
+ input: unknown;
94
+ }[];
95
+ execute(input: unknown): Promise<unknown>;
96
+ static create(name: string, handler: (input: any) => unknown | Promise<unknown>): MockTool;
97
+ }
98
+
99
+ export { AxlTestRuntime, MockProvider, MockTool, type RecordedAgentCall, type RecordedStep, type RecordedToolCall };
package/dist/index.js ADDED
@@ -0,0 +1,314 @@
1
+ // src/mock-provider.ts
2
+ import { readFileSync } from "fs";
3
+ function randomAlphanumeric(length) {
4
+ const chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
5
+ let result = "";
6
+ for (let i = 0; i < length; i++) {
7
+ result += chars[Math.floor(Math.random() * chars.length)];
8
+ }
9
+ return result;
10
+ }
11
+ function generateFromSchema(schema) {
12
+ const def = schema?._def;
13
+ if (!def) return {};
14
+ switch (def.typeName) {
15
+ case "ZodString": {
16
+ const length = 8 + Math.floor(Math.random() * 13);
17
+ return randomAlphanumeric(length);
18
+ }
19
+ case "ZodNumber": {
20
+ const checks = def.checks ?? [];
21
+ let min = 0;
22
+ let max = 100;
23
+ for (const check of checks) {
24
+ if (check.kind === "min") min = check.value;
25
+ if (check.kind === "max") max = check.value;
26
+ }
27
+ return min + Math.random() * (max - min);
28
+ }
29
+ case "ZodBoolean":
30
+ return Math.random() < 0.5;
31
+ case "ZodArray": {
32
+ const count = 1 + Math.floor(Math.random() * 3);
33
+ const items = [];
34
+ for (let i = 0; i < count; i++) {
35
+ items.push(generateFromSchema(def.type));
36
+ }
37
+ return items;
38
+ }
39
+ case "ZodObject": {
40
+ const shape = def.shape?.() ?? {};
41
+ const obj = {};
42
+ for (const [key, value] of Object.entries(shape)) {
43
+ obj[key] = generateFromSchema(value);
44
+ }
45
+ return obj;
46
+ }
47
+ case "ZodOptional": {
48
+ if (Math.random() < 0.5) return void 0;
49
+ return generateFromSchema(def.innerType);
50
+ }
51
+ case "ZodDefault":
52
+ return def.defaultValue();
53
+ case "ZodEnum": {
54
+ const values = def.values ?? [];
55
+ if (values.length === 0) return "";
56
+ return values[Math.floor(Math.random() * values.length)];
57
+ }
58
+ case "ZodNullable":
59
+ return null;
60
+ default:
61
+ return {};
62
+ }
63
+ }
64
+ var MockProvider = class _MockProvider {
65
+ constructor(responseFn) {
66
+ this.responseFn = responseFn;
67
+ }
68
+ name = "mock";
69
+ _calls = [];
70
+ get calls() {
71
+ return this._calls;
72
+ }
73
+ async chat(messages, options) {
74
+ this._calls.push({ messages, options });
75
+ return this.responseFn(messages, this._calls.length - 1);
76
+ }
77
+ async *stream(messages, options) {
78
+ const response = await this.chat(messages, options);
79
+ yield { type: "text_delta", content: response.content };
80
+ yield { type: "done", usage: response.usage };
81
+ }
82
+ static sequence(responses) {
83
+ return new _MockProvider((_messages, callIndex) => {
84
+ if (callIndex >= responses.length) {
85
+ throw new Error(
86
+ `MockProvider.sequence: no response for call index ${callIndex}. Only ${responses.length} responses defined.`
87
+ );
88
+ }
89
+ return {
90
+ content: responses[callIndex].content,
91
+ tool_calls: responses[callIndex].tool_calls,
92
+ usage: { prompt_tokens: 10, completion_tokens: 10, total_tokens: 20 },
93
+ cost: 0
94
+ };
95
+ });
96
+ }
97
+ static echo() {
98
+ return new _MockProvider((messages) => {
99
+ const lastUser = [...messages].reverse().find((m) => m.role === "user");
100
+ return {
101
+ content: lastUser?.content ?? "",
102
+ usage: { prompt_tokens: 10, completion_tokens: 10, total_tokens: 20 },
103
+ cost: 0
104
+ };
105
+ });
106
+ }
107
+ static json(schema) {
108
+ return new _MockProvider(() => ({
109
+ content: JSON.stringify(generateFromSchema(schema)),
110
+ usage: { prompt_tokens: 10, completion_tokens: 10, total_tokens: 20 },
111
+ cost: 0
112
+ }));
113
+ }
114
+ static replay(source) {
115
+ const data = typeof source === "string" ? JSON.parse(readFileSync(source, "utf-8")) : source;
116
+ return new _MockProvider((_messages, callIndex) => {
117
+ if (callIndex >= data.length) {
118
+ throw new Error(`MockProvider.replay: no recorded response for call index ${callIndex}`);
119
+ }
120
+ return data[callIndex];
121
+ });
122
+ }
123
+ static fn(handler) {
124
+ return new _MockProvider((messages, callIndex) => ({
125
+ ...handler(messages, callIndex),
126
+ usage: { prompt_tokens: 10, completion_tokens: 10, total_tokens: 20 },
127
+ cost: 0
128
+ }));
129
+ }
130
+ };
131
+
132
+ // src/mock-tool.ts
133
+ var MockTool = class _MockTool {
134
+ constructor(name, handler) {
135
+ this.name = name;
136
+ this.handler = handler;
137
+ }
138
+ _calls = [];
139
+ get calls() {
140
+ return this._calls;
141
+ }
142
+ async execute(input) {
143
+ this._calls.push({ input });
144
+ return this.handler(input);
145
+ }
146
+ static create(name, handler) {
147
+ return new _MockTool(name, handler);
148
+ }
149
+ };
150
+
151
+ // src/test-runtime.ts
152
+ import { WorkflowContext, MemoryStore, ProviderRegistry } from "@axlsdk/axl";
153
+ function generateExecutionId() {
154
+ return `test-${Date.now()}-${Math.random().toString(36).slice(2, 10)}`;
155
+ }
156
+ var AxlTestRuntime = class {
157
+ workflows = /* @__PURE__ */ new Map();
158
+ mockProviders = /* @__PURE__ */ new Map();
159
+ mockToolMap = /* @__PURE__ */ new Map();
160
+ _toolCalls = [];
161
+ _agentCalls = [];
162
+ _steps = [];
163
+ _traceLog = [];
164
+ _totalCost = 0;
165
+ _stepCounter = 0;
166
+ recordPath;
167
+ recorded = [];
168
+ _executionId = generateExecutionId();
169
+ _humanDecisionHandler;
170
+ constructor(options) {
171
+ this.recordPath = options?.record;
172
+ this._humanDecisionHandler = options?.humanDecisions;
173
+ }
174
+ register(workflow) {
175
+ this.workflows.set(workflow.name, workflow);
176
+ }
177
+ mockProvider(name, provider) {
178
+ this.mockProviders.set(name, provider);
179
+ }
180
+ mockTool(name, handler) {
181
+ this.mockToolMap.set(name, MockTool.create(name, handler));
182
+ }
183
+ async execute(workflowName, input, options) {
184
+ const workflow = this.workflows.get(workflowName);
185
+ if (!workflow) throw new Error(`Workflow "${workflowName}" not registered`);
186
+ this._toolCalls = [];
187
+ this._agentCalls = [];
188
+ this._steps = [];
189
+ this._traceLog = [];
190
+ this._totalCost = 0;
191
+ this._stepCounter = 0;
192
+ this.recorded = [];
193
+ this._executionId = generateExecutionId();
194
+ const validated = workflow.inputSchema.parse(input);
195
+ const registry = new ProviderRegistry();
196
+ registry.clearFactories();
197
+ for (const [name, provider] of this.mockProviders) {
198
+ registry.registerInstance(name, provider);
199
+ }
200
+ const defaultProvider = this.mockProviders.get("default");
201
+ if (defaultProvider) {
202
+ registry.setFallback(defaultProvider);
203
+ } else if (this.mockProviders.size === 1) {
204
+ const onlyProvider = this.mockProviders.values().next().value;
205
+ registry.setFallback(onlyProvider);
206
+ }
207
+ const toolOverrides = /* @__PURE__ */ new Map();
208
+ for (const [name, mockTool] of this.mockToolMap) {
209
+ toolOverrides.set(name, async (args) => {
210
+ return mockTool.execute(args);
211
+ });
212
+ }
213
+ this._recordStep("workflow_start", { workflow: workflowName, input: validated });
214
+ this._pushTrace({
215
+ type: "workflow_start",
216
+ workflow: workflowName,
217
+ data: { input: validated }
218
+ });
219
+ const init = {
220
+ input: validated,
221
+ executionId: this._executionId,
222
+ metadata: options?.metadata,
223
+ config: {},
224
+ providerRegistry: registry,
225
+ stateStore: new MemoryStore(),
226
+ toolOverrides: toolOverrides.size > 0 ? toolOverrides : void 0,
227
+ awaitHumanHandler: this._humanDecisionHandler ? (opts) => this._humanDecisionHandler(opts) : void 0,
228
+ onTrace: (event) => {
229
+ this._traceLog.push(event);
230
+ this._stepCounter++;
231
+ this._steps.push({ step: this._stepCounter, type: event.type, data: event.data });
232
+ if (event.type === "tool_call" && event.data) {
233
+ const { args, result: result2 } = event.data;
234
+ this._toolCalls.push({ name: event.tool, args, result: result2 });
235
+ }
236
+ if (event.cost) {
237
+ this._totalCost += event.cost;
238
+ }
239
+ if (event.type === "agent_call" && event.data) {
240
+ const { response } = event.data;
241
+ if (response !== void 0) {
242
+ this.recorded.push({
243
+ content: response,
244
+ usage: { prompt_tokens: 0, completion_tokens: 0, total_tokens: 0 },
245
+ cost: event.cost ?? 0
246
+ });
247
+ }
248
+ }
249
+ },
250
+ onAgentCallComplete: (call) => {
251
+ this._agentCalls.push({
252
+ agent: call.agent,
253
+ prompt: call.prompt,
254
+ response: call.response,
255
+ model: call.model,
256
+ cost: call.cost,
257
+ duration: call.duration,
258
+ promptVersion: call.promptVersion
259
+ });
260
+ }
261
+ };
262
+ const ctx = new WorkflowContext(init);
263
+ const result = await workflow.handler(ctx);
264
+ if (workflow.outputSchema) workflow.outputSchema.parse(result);
265
+ this._recordStep("workflow_end", { workflow: workflowName, result });
266
+ this._pushTrace({
267
+ type: "workflow_end",
268
+ workflow: workflowName,
269
+ data: { result }
270
+ });
271
+ if (this.recordPath) await this._writeRecording();
272
+ return result;
273
+ }
274
+ toolCalls(name) {
275
+ return name ? this._toolCalls.filter((c) => c.name === name) : this._toolCalls;
276
+ }
277
+ agentCalls(name) {
278
+ return name ? this._agentCalls.filter((c) => c.agent === name) : this._agentCalls;
279
+ }
280
+ totalCost() {
281
+ return this._totalCost;
282
+ }
283
+ steps() {
284
+ return this._steps;
285
+ }
286
+ traceLog() {
287
+ return this._traceLog;
288
+ }
289
+ _recordStep(type, data) {
290
+ this._stepCounter++;
291
+ this._steps.push({ step: this._stepCounter, type, data });
292
+ }
293
+ _pushTrace(partial) {
294
+ this._traceLog.push({
295
+ executionId: this._executionId,
296
+ step: this._stepCounter,
297
+ timestamp: Date.now(),
298
+ ...partial
299
+ });
300
+ }
301
+ async _writeRecording() {
302
+ if (!this.recordPath) return;
303
+ const { writeFile, mkdir } = await import("fs/promises");
304
+ const { dirname } = await import("path");
305
+ await mkdir(dirname(this.recordPath), { recursive: true });
306
+ await writeFile(this.recordPath, JSON.stringify(this.recorded, null, 2), "utf8");
307
+ }
308
+ };
309
+ export {
310
+ AxlTestRuntime,
311
+ MockProvider,
312
+ MockTool
313
+ };
314
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/mock-provider.ts","../src/mock-tool.ts","../src/test-runtime.ts"],"sourcesContent":["import { readFileSync } from 'node:fs';\nimport type { ChatMessage, ToolCallMessage, ProviderResponse, StreamChunk, Provider } from '@axlsdk/axl';\n\nfunction randomAlphanumeric(length: number): string {\n const chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';\n let result = '';\n for (let i = 0; i < length; i++) {\n result += chars[Math.floor(Math.random() * chars.length)];\n }\n return result;\n}\n\nfunction generateFromSchema(schema: any): unknown {\n const def = schema?._def;\n if (!def) return {};\n switch (def.typeName) {\n case 'ZodString': {\n const length = 8 + Math.floor(Math.random() * 13); // 8-20 chars\n return randomAlphanumeric(length);\n }\n case 'ZodNumber': {\n const checks: any[] = def.checks ?? [];\n let min = 0;\n let max = 100;\n for (const check of checks) {\n if (check.kind === 'min') min = check.value;\n if (check.kind === 'max') max = check.value;\n }\n return min + Math.random() * (max - min);\n }\n case 'ZodBoolean':\n return Math.random() < 0.5;\n case 'ZodArray': {\n const count = 1 + Math.floor(Math.random() * 3); // 1-3 items\n const items: unknown[] = [];\n for (let i = 0; i < count; i++) {\n items.push(generateFromSchema(def.type));\n }\n return items;\n }\n case 'ZodObject': {\n const shape = def.shape?.() ?? {};\n const obj: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(shape)) {\n obj[key] = generateFromSchema(value);\n }\n return obj;\n }\n case 'ZodOptional': {\n if (Math.random() < 0.5) return undefined;\n return generateFromSchema(def.innerType);\n }\n case 'ZodDefault':\n return def.defaultValue();\n case 'ZodEnum': {\n const values: unknown[] = def.values ?? [];\n if (values.length === 0) return '';\n return values[Math.floor(Math.random() * values.length)];\n }\n case 'ZodNullable':\n return null;\n default:\n return {};\n }\n}\n\nexport class MockProvider implements Provider {\n readonly name = 'mock';\n private _calls: { messages: ChatMessage[]; options: any }[] = [];\n\n private constructor(\n private responseFn: (messages: ChatMessage[], callIndex: number) => ProviderResponse,\n ) {}\n\n get calls() {\n return this._calls;\n }\n\n async chat(messages: ChatMessage[], options: any): Promise<ProviderResponse> {\n this._calls.push({ messages, options });\n return this.responseFn(messages, this._calls.length - 1);\n }\n\n async *stream(messages: ChatMessage[], options: any): AsyncGenerator<StreamChunk> {\n const response = await this.chat(messages, options);\n yield { type: 'text_delta', content: response.content };\n yield { type: 'done', usage: response.usage };\n }\n\n static sequence(\n responses: Array<{ content: string; tool_calls?: ToolCallMessage[] }>,\n ): MockProvider {\n return new MockProvider((_messages, callIndex) => {\n if (callIndex >= responses.length) {\n throw new Error(\n `MockProvider.sequence: no response for call index ${callIndex}. Only ${responses.length} responses defined.`,\n );\n }\n return {\n content: responses[callIndex].content,\n tool_calls: responses[callIndex].tool_calls,\n usage: { prompt_tokens: 10, completion_tokens: 10, total_tokens: 20 },\n cost: 0,\n };\n });\n }\n\n static echo(): MockProvider {\n return new MockProvider((messages) => {\n const lastUser = [...messages].reverse().find((m) => m.role === 'user');\n return {\n content: lastUser?.content ?? '',\n usage: { prompt_tokens: 10, completion_tokens: 10, total_tokens: 20 },\n cost: 0,\n };\n });\n }\n\n static json(schema: any): MockProvider {\n return new MockProvider(() => ({\n content: JSON.stringify(generateFromSchema(schema)),\n usage: { prompt_tokens: 10, completion_tokens: 10, total_tokens: 20 },\n cost: 0,\n }));\n }\n\n static replay(source: string | ProviderResponse[]): MockProvider {\n const data =\n typeof source === 'string'\n ? (JSON.parse(readFileSync(source, 'utf-8')) as ProviderResponse[])\n : source;\n return new MockProvider((_messages, callIndex) => {\n if (callIndex >= data.length) {\n throw new Error(`MockProvider.replay: no recorded response for call index ${callIndex}`);\n }\n return data[callIndex];\n });\n }\n\n static fn(\n handler: (\n messages: ChatMessage[],\n callIndex: number,\n ) => { content: string; tool_calls?: ToolCallMessage[] },\n ): MockProvider {\n return new MockProvider((messages, callIndex) => ({\n ...handler(messages, callIndex),\n usage: { prompt_tokens: 10, completion_tokens: 10, total_tokens: 20 },\n cost: 0,\n }));\n }\n}\n","export class MockTool {\n private _calls: { input: unknown }[] = [];\n\n constructor(\n readonly name: string,\n private handler: (input: any) => unknown | Promise<unknown>,\n ) {}\n\n get calls() {\n return this._calls;\n }\n\n async execute(input: unknown): Promise<unknown> {\n this._calls.push({ input });\n return this.handler(input);\n }\n\n static create(name: string, handler: (input: any) => unknown | Promise<unknown>): MockTool {\n return new MockTool(name, handler);\n }\n}\n","import { MockProvider } from './mock-provider.js';\nimport { MockTool } from './mock-tool.js';\nimport type { TraceEvent, AwaitHumanOptions, HumanDecision, ProviderResponse } from '@axlsdk/axl';\nimport { WorkflowContext, MemoryStore, ProviderRegistry } from '@axlsdk/axl';\nimport type { WorkflowContextInit } from '@axlsdk/axl';\n\ninterface WorkflowLike {\n readonly name: string;\n readonly inputSchema: any;\n readonly outputSchema: any | undefined;\n readonly handler: (ctx: any) => Promise<any>;\n}\n\nexport type RecordedToolCall = { name: string; args: unknown; result: unknown };\nexport type RecordedAgentCall = {\n agent: string;\n prompt: string;\n response: string;\n model?: string;\n cost?: number;\n duration?: number;\n promptVersion?: string;\n};\nexport type RecordedStep = { step: number; type: string; data: unknown };\n\nfunction generateExecutionId(): string {\n return `test-${Date.now()}-${Math.random().toString(36).slice(2, 10)}`;\n}\n\nexport type AxlTestRuntimeOptions = {\n record?: string;\n humanDecisions?: (options: AwaitHumanOptions) => HumanDecision;\n};\n\nexport class AxlTestRuntime {\n private workflows = new Map<string, WorkflowLike>();\n private mockProviders = new Map<string, MockProvider>();\n private mockToolMap = new Map<string, MockTool>();\n private _toolCalls: RecordedToolCall[] = [];\n private _agentCalls: RecordedAgentCall[] = [];\n private _steps: RecordedStep[] = [];\n private _traceLog: TraceEvent[] = [];\n private _totalCost = 0;\n private _stepCounter = 0;\n private recordPath?: string;\n private recorded: ProviderResponse[] = [];\n private _executionId: string = generateExecutionId();\n private _humanDecisionHandler?: (options: AwaitHumanOptions) => HumanDecision;\n\n constructor(options?: AxlTestRuntimeOptions) {\n this.recordPath = options?.record;\n this._humanDecisionHandler = options?.humanDecisions;\n }\n\n register(workflow: WorkflowLike): void {\n this.workflows.set(workflow.name, workflow);\n }\n\n mockProvider(name: string, provider: MockProvider): void {\n this.mockProviders.set(name, provider);\n }\n\n mockTool(name: string, handler: (input: any) => unknown | Promise<unknown>): void {\n this.mockToolMap.set(name, MockTool.create(name, handler));\n }\n\n async execute(\n workflowName: string,\n input: unknown,\n options?: { metadata?: Record<string, unknown> },\n ): Promise<unknown> {\n const workflow = this.workflows.get(workflowName);\n if (!workflow) throw new Error(`Workflow \"${workflowName}\" not registered`);\n\n // Reset state between executions\n this._toolCalls = [];\n this._agentCalls = [];\n this._steps = [];\n this._traceLog = [];\n this._totalCost = 0;\n this._stepCounter = 0;\n this.recorded = [];\n this._executionId = generateExecutionId();\n\n const validated = workflow.inputSchema.parse(input);\n\n // Build ProviderRegistry from registered mock providers\n const registry = new ProviderRegistry();\n registry.clearFactories(); // Remove built-in factories; only use explicit mocks\n for (const [name, provider] of this.mockProviders) {\n registry.registerInstance(name, provider as any);\n }\n // Fallback resolution: 'default' key or single-provider\n const defaultProvider = this.mockProviders.get('default');\n if (defaultProvider) {\n registry.setFallback(defaultProvider as any);\n } else if (this.mockProviders.size === 1) {\n const onlyProvider = this.mockProviders.values().next().value!;\n registry.setFallback(onlyProvider as any);\n }\n\n // Build toolOverrides from mockToolMap\n const toolOverrides = new Map<string, (args: unknown) => Promise<unknown>>();\n for (const [name, mockTool] of this.mockToolMap) {\n toolOverrides.set(name, async (args: unknown) => {\n return mockTool.execute(args);\n });\n }\n\n // Record steps and traces via callbacks\n this._recordStep('workflow_start', { workflow: workflowName, input: validated });\n this._pushTrace({\n type: 'workflow_start',\n workflow: workflowName,\n data: { input: validated },\n });\n\n const init: WorkflowContextInit = {\n input: validated,\n executionId: this._executionId,\n metadata: options?.metadata,\n config: {},\n providerRegistry: registry,\n stateStore: new MemoryStore(),\n toolOverrides: toolOverrides.size > 0 ? toolOverrides : undefined,\n awaitHumanHandler: this._humanDecisionHandler\n ? (opts: AwaitHumanOptions) => this._humanDecisionHandler!(opts)\n : undefined,\n onTrace: (event: TraceEvent) => {\n this._traceLog.push(event);\n this._stepCounter++;\n this._steps.push({ step: this._stepCounter, type: event.type, data: event.data });\n\n if (event.type === 'tool_call' && event.data) {\n const { args, result } = event.data as { args: unknown; result: unknown };\n this._toolCalls.push({ name: event.tool!, args, result });\n }\n\n if (event.cost) {\n this._totalCost += event.cost;\n }\n\n // Track provider responses for recording\n if (event.type === 'agent_call' && event.data) {\n const { response } = event.data as { prompt?: string; response?: string };\n if (response !== undefined) {\n this.recorded.push({\n content: response,\n usage: { prompt_tokens: 0, completion_tokens: 0, total_tokens: 0 },\n cost: event.cost ?? 0,\n });\n }\n }\n },\n onAgentCallComplete: (call) => {\n this._agentCalls.push({\n agent: call.agent,\n prompt: call.prompt,\n response: call.response,\n model: call.model,\n cost: call.cost,\n duration: call.duration,\n promptVersion: call.promptVersion,\n });\n },\n };\n\n const ctx = new WorkflowContext(init);\n const result = await workflow.handler(ctx);\n\n // Validate output schema if defined\n if (workflow.outputSchema) workflow.outputSchema.parse(result);\n\n this._recordStep('workflow_end', { workflow: workflowName, result });\n this._pushTrace({\n type: 'workflow_end',\n workflow: workflowName,\n data: { result },\n });\n\n if (this.recordPath) await this._writeRecording();\n return result;\n }\n\n toolCalls(name?: string): RecordedToolCall[] {\n return name ? this._toolCalls.filter((c) => c.name === name) : this._toolCalls;\n }\n\n agentCalls(name?: string): RecordedAgentCall[] {\n return name ? this._agentCalls.filter((c) => c.agent === name) : this._agentCalls;\n }\n\n totalCost(): number {\n return this._totalCost;\n }\n steps(): RecordedStep[] {\n return this._steps;\n }\n traceLog(): TraceEvent[] {\n return this._traceLog;\n }\n\n private _recordStep(type: string, data: unknown): void {\n this._stepCounter++;\n this._steps.push({ step: this._stepCounter, type, data });\n }\n\n private _pushTrace(partial: Omit<TraceEvent, 'executionId' | 'step' | 'timestamp'>): void {\n this._traceLog.push({\n executionId: this._executionId,\n step: this._stepCounter,\n timestamp: Date.now(),\n ...partial,\n });\n }\n\n private async _writeRecording(): Promise<void> {\n if (!this.recordPath) return;\n const { writeFile, mkdir } = await import('node:fs/promises');\n const { dirname } = await import('node:path');\n await mkdir(dirname(this.recordPath), { recursive: true });\n await writeFile(this.recordPath, JSON.stringify(this.recorded, null, 2), 'utf8');\n }\n}\n"],"mappings":"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","names":["result"]}
package/package.json ADDED
@@ -0,0 +1,63 @@
1
+ {
2
+ "name": "@axlsdk/testing",
3
+ "version": "0.1.0",
4
+ "description": "Testing utilities for Axl agentic workflows",
5
+ "type": "module",
6
+ "main": "./dist/index.cjs",
7
+ "module": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "import": {
12
+ "types": "./dist/index.d.ts",
13
+ "default": "./dist/index.js"
14
+ },
15
+ "require": {
16
+ "types": "./dist/index.d.cts",
17
+ "default": "./dist/index.cjs"
18
+ }
19
+ }
20
+ },
21
+ "files": [
22
+ "dist"
23
+ ],
24
+ "scripts": {
25
+ "build": "tsup",
26
+ "typecheck": "tsc --noEmit",
27
+ "test": "vitest run",
28
+ "test:watch": "vitest watch",
29
+ "lint": "tsc --noEmit"
30
+ },
31
+ "dependencies": {
32
+ "@axlsdk/axl": "workspace:*"
33
+ },
34
+ "devDependencies": {
35
+ "@types/node": "^25.2.3",
36
+ "tsup": "^8.3.0",
37
+ "typescript": "^5.7.0",
38
+ "vitest": "^3.0.0",
39
+ "zod": "^3.24.0"
40
+ },
41
+ "keywords": [
42
+ "ai",
43
+ "testing",
44
+ "mock",
45
+ "agents"
46
+ ],
47
+ "license": "Apache-2.0",
48
+ "repository": {
49
+ "type": "git",
50
+ "url": "git+https://github.com/axl-sdk/axl.git",
51
+ "directory": "packages/axl-testing"
52
+ },
53
+ "homepage": "https://github.com/axl-sdk/axl#readme",
54
+ "bugs": {
55
+ "url": "https://github.com/axl-sdk/axl/issues"
56
+ },
57
+ "publishConfig": {
58
+ "access": "public"
59
+ },
60
+ "engines": {
61
+ "node": ">=20.0.0"
62
+ }
63
+ }