@agentxjs/devtools 1.9.3-dev → 1.9.6-dev

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.
@@ -0,0 +1,152 @@
1
+ // src/recorder/RecordingDriver.ts
2
+ import { createLogger } from "commonxjs/logger";
3
+ var logger = createLogger("devtools/RecordingDriver");
4
+ var RecordingDriver = class {
5
+ name = "RecordingDriver";
6
+ realDriver;
7
+ fixtureName;
8
+ fixtureDescription;
9
+ recordedEvents = [];
10
+ recordingStartTime = 0;
11
+ constructor(options) {
12
+ this.realDriver = options.driver;
13
+ this.fixtureName = options.name;
14
+ this.fixtureDescription = options.description;
15
+ logger.info("RecordingDriver created", { name: this.fixtureName });
16
+ }
17
+ // ============================================================================
18
+ // Driver Interface Properties (delegate to real driver)
19
+ // ============================================================================
20
+ get sessionId() {
21
+ return this.realDriver.sessionId;
22
+ }
23
+ get state() {
24
+ return this.realDriver.state;
25
+ }
26
+ // ============================================================================
27
+ // Lifecycle Methods (delegate to real driver)
28
+ // ============================================================================
29
+ async initialize() {
30
+ await this.realDriver.initialize();
31
+ this.recordingStartTime = Date.now();
32
+ this.recordedEvents = [];
33
+ logger.info("RecordingDriver initialized, recording started", {
34
+ name: this.fixtureName
35
+ });
36
+ }
37
+ async dispose() {
38
+ await this.realDriver.dispose();
39
+ logger.info("RecordingDriver disposed", {
40
+ name: this.fixtureName,
41
+ eventsRecorded: this.recordedEvents.length
42
+ });
43
+ }
44
+ // ============================================================================
45
+ // Core Methods
46
+ // ============================================================================
47
+ /**
48
+ * Receive a user message and return stream of events
49
+ *
50
+ * Wraps the real driver's receive() and records all events.
51
+ */
52
+ async *receive(message) {
53
+ logger.debug("RecordingDriver receiving message", {
54
+ name: this.fixtureName
55
+ });
56
+ for await (const event of this.realDriver.receive(message)) {
57
+ this.recordEvent(event);
58
+ yield event;
59
+ }
60
+ logger.debug("RecordingDriver receive completed", {
61
+ name: this.fixtureName,
62
+ eventsRecorded: this.recordedEvents.length
63
+ });
64
+ }
65
+ /**
66
+ * Interrupt current operation (delegate to real driver)
67
+ */
68
+ interrupt() {
69
+ this.realDriver.interrupt();
70
+ }
71
+ // ============================================================================
72
+ // Recording Methods
73
+ // ============================================================================
74
+ /**
75
+ * Record an event
76
+ */
77
+ recordEvent(event) {
78
+ this.recordedEvents.push({
79
+ event,
80
+ timestamp: Date.now()
81
+ });
82
+ logger.debug("Event recorded", {
83
+ type: event.type,
84
+ totalEvents: this.recordedEvents.length
85
+ });
86
+ }
87
+ /**
88
+ * Get the recorded fixture
89
+ */
90
+ getFixture() {
91
+ const events = [];
92
+ let lastTimestamp = this.recordingStartTime;
93
+ for (const recorded of this.recordedEvents) {
94
+ const delay = recorded.timestamp - lastTimestamp;
95
+ lastTimestamp = recorded.timestamp;
96
+ events.push({
97
+ type: recorded.event.type,
98
+ delay: Math.max(0, delay),
99
+ data: recorded.event.data
100
+ });
101
+ }
102
+ return {
103
+ name: this.fixtureName,
104
+ description: this.fixtureDescription,
105
+ recordedAt: this.recordingStartTime,
106
+ events
107
+ };
108
+ }
109
+ /**
110
+ * Save the recorded fixture to a JSON file
111
+ */
112
+ async saveFixture(filePath) {
113
+ const fixture = this.getFixture();
114
+ const json = JSON.stringify(fixture, null, 2);
115
+ const { writeFile } = await import("fs/promises");
116
+ await writeFile(filePath, json, "utf-8");
117
+ logger.info("Fixture saved", {
118
+ path: filePath,
119
+ name: fixture.name,
120
+ eventCount: fixture.events.length
121
+ });
122
+ }
123
+ /**
124
+ * Get the number of recorded events
125
+ */
126
+ get eventCount() {
127
+ return this.recordedEvents.length;
128
+ }
129
+ /**
130
+ * Clear recorded events (start fresh recording)
131
+ */
132
+ clearRecording() {
133
+ this.recordedEvents = [];
134
+ this.recordingStartTime = Date.now();
135
+ logger.debug("Recording cleared");
136
+ }
137
+ /**
138
+ * Get raw recorded events (for debugging)
139
+ */
140
+ getRawEvents() {
141
+ return [...this.recordedEvents];
142
+ }
143
+ };
144
+ function createRecordingDriver(options) {
145
+ return new RecordingDriver(options);
146
+ }
147
+
148
+ export {
149
+ RecordingDriver,
150
+ createRecordingDriver
151
+ };
152
+ //# sourceMappingURL=chunk-YRTTCKHM.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/recorder/RecordingDriver.ts"],"sourcesContent":["/**\n * RecordingDriver - Wraps a real driver to record events\n *\n * Used to capture real LLM API responses and save them as fixtures.\n * These fixtures can then be played back by MockDriver for testing.\n *\n * Usage:\n * ```typescript\n * import { createClaudeDriver } from \"@agentxjs/claude-driver\";\n * import { RecordingDriver } from \"@agentxjs/devtools/recorder\";\n *\n * // Create real driver\n * const realDriver = createClaudeDriver(config);\n *\n * // Wrap with recorder\n * const recorder = new RecordingDriver({\n * driver: realDriver,\n * name: \"my-scenario\",\n * description: \"User asks about weather\",\n * });\n *\n * await recorder.initialize();\n *\n * // Use like a normal driver - events are recorded\n * for await (const event of recorder.receive({ content: \"Hello\" })) {\n * console.log(event);\n * }\n *\n * // Save the fixture\n * await recorder.saveFixture(\"./fixtures/my-scenario.json\");\n * ```\n */\n\nimport type {\n Driver,\n DriverState,\n DriverStreamEvent,\n} from \"@agentxjs/core/driver\";\nimport type { UserMessage } from \"@agentxjs/core/agent\";\nimport type { Fixture, FixtureEvent } from \"../types\";\nimport { createLogger } from \"commonxjs/logger\";\n\nconst logger = createLogger(\"devtools/RecordingDriver\");\n\n/**\n * Options for RecordingDriver\n */\nexport interface RecordingDriverOptions {\n /**\n * The real driver to wrap\n */\n driver: Driver;\n\n /**\n * Fixture name for the recording\n */\n name: string;\n\n /**\n * Description for the recording\n */\n description?: string;\n}\n\n/**\n * Recorded event with timing\n */\ninterface RecordedEvent {\n event: DriverStreamEvent;\n timestamp: number;\n}\n\n/**\n * RecordingDriver - Records events from a real driver\n *\n * Implements the new Driver interface by wrapping a real driver\n * and intercepting events from receive().\n */\nexport class RecordingDriver implements Driver {\n readonly name = \"RecordingDriver\";\n\n private readonly realDriver: Driver;\n private readonly fixtureName: string;\n private readonly fixtureDescription?: string;\n\n private recordedEvents: RecordedEvent[] = [];\n private recordingStartTime: number = 0;\n\n constructor(options: RecordingDriverOptions) {\n this.realDriver = options.driver;\n this.fixtureName = options.name;\n this.fixtureDescription = options.description;\n\n logger.info(\"RecordingDriver created\", { name: this.fixtureName });\n }\n\n // ============================================================================\n // Driver Interface Properties (delegate to real driver)\n // ============================================================================\n\n get sessionId(): string | null {\n return this.realDriver.sessionId;\n }\n\n get state(): DriverState {\n return this.realDriver.state;\n }\n\n // ============================================================================\n // Lifecycle Methods (delegate to real driver)\n // ============================================================================\n\n async initialize(): Promise<void> {\n await this.realDriver.initialize();\n this.recordingStartTime = Date.now();\n this.recordedEvents = [];\n logger.info(\"RecordingDriver initialized, recording started\", {\n name: this.fixtureName,\n });\n }\n\n async dispose(): Promise<void> {\n await this.realDriver.dispose();\n logger.info(\"RecordingDriver disposed\", {\n name: this.fixtureName,\n eventsRecorded: this.recordedEvents.length,\n });\n }\n\n // ============================================================================\n // Core Methods\n // ============================================================================\n\n /**\n * Receive a user message and return stream of events\n *\n * Wraps the real driver's receive() and records all events.\n */\n async *receive(message: UserMessage): AsyncIterable<DriverStreamEvent> {\n logger.debug(\"RecordingDriver receiving message\", {\n name: this.fixtureName,\n });\n\n // Call the real driver and intercept events\n for await (const event of this.realDriver.receive(message)) {\n // Record the event\n this.recordEvent(event);\n\n // Pass through to caller\n yield event;\n }\n\n logger.debug(\"RecordingDriver receive completed\", {\n name: this.fixtureName,\n eventsRecorded: this.recordedEvents.length,\n });\n }\n\n /**\n * Interrupt current operation (delegate to real driver)\n */\n interrupt(): void {\n this.realDriver.interrupt();\n }\n\n // ============================================================================\n // Recording Methods\n // ============================================================================\n\n /**\n * Record an event\n */\n private recordEvent(event: DriverStreamEvent): void {\n this.recordedEvents.push({\n event,\n timestamp: Date.now(),\n });\n\n logger.debug(\"Event recorded\", {\n type: event.type,\n totalEvents: this.recordedEvents.length,\n });\n }\n\n /**\n * Get the recorded fixture\n */\n getFixture(): Fixture {\n const events: FixtureEvent[] = [];\n let lastTimestamp = this.recordingStartTime;\n\n for (const recorded of this.recordedEvents) {\n const delay = recorded.timestamp - lastTimestamp;\n lastTimestamp = recorded.timestamp;\n\n events.push({\n type: recorded.event.type,\n delay: Math.max(0, delay),\n data: recorded.event.data,\n });\n }\n\n return {\n name: this.fixtureName,\n description: this.fixtureDescription,\n recordedAt: this.recordingStartTime,\n events,\n };\n }\n\n /**\n * Save the recorded fixture to a JSON file\n */\n async saveFixture(filePath: string): Promise<void> {\n const fixture = this.getFixture();\n const json = JSON.stringify(fixture, null, 2);\n\n // Use dynamic import for Node.js fs\n const { writeFile } = await import(\"node:fs/promises\");\n await writeFile(filePath, json, \"utf-8\");\n\n logger.info(\"Fixture saved\", {\n path: filePath,\n name: fixture.name,\n eventCount: fixture.events.length,\n });\n }\n\n /**\n * Get the number of recorded events\n */\n get eventCount(): number {\n return this.recordedEvents.length;\n }\n\n /**\n * Clear recorded events (start fresh recording)\n */\n clearRecording(): void {\n this.recordedEvents = [];\n this.recordingStartTime = Date.now();\n logger.debug(\"Recording cleared\");\n }\n\n /**\n * Get raw recorded events (for debugging)\n */\n getRawEvents(): RecordedEvent[] {\n return [...this.recordedEvents];\n }\n}\n\n/**\n * Create a RecordingDriver that wraps a real driver\n */\nexport function createRecordingDriver(options: RecordingDriverOptions): RecordingDriver {\n return new RecordingDriver(options);\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,49 @@
1
+ import { F as Fixture } from '../types-C6Lf3vz2.js';
2
+
3
+ /**
4
+ * Built-in Fixtures for MockDriver
5
+ *
6
+ * These fixtures simulate common conversation patterns.
7
+ * They can be used directly or as templates for custom fixtures.
8
+ */
9
+
10
+ /**
11
+ * Simple text reply - no tool calls
12
+ *
13
+ * Simulates: "Hello!" -> "Hello! How can I help you today?"
14
+ */
15
+ declare const SIMPLE_REPLY: Fixture;
16
+ /**
17
+ * Multi-paragraph response
18
+ *
19
+ * Simulates a longer response with multiple sentences
20
+ */
21
+ declare const LONG_REPLY: Fixture;
22
+ /**
23
+ * Tool call response - demonstrates tool_use flow
24
+ *
25
+ * Simulates: "What time is it?" -> tool_call(get_current_time) -> "It's 2:30 PM"
26
+ */
27
+ declare const TOOL_CALL: Fixture;
28
+ /**
29
+ * Error response
30
+ */
31
+ declare const ERROR_RESPONSE: Fixture;
32
+ /**
33
+ * Empty response (for edge case testing)
34
+ */
35
+ declare const EMPTY_RESPONSE: Fixture;
36
+ /**
37
+ * All built-in fixtures
38
+ */
39
+ declare const BUILTIN_FIXTURES: Map<string, Fixture>;
40
+ /**
41
+ * Get a built-in fixture by name
42
+ */
43
+ declare function getFixture(name: string): Fixture | undefined;
44
+ /**
45
+ * List all built-in fixture names
46
+ */
47
+ declare function listFixtures(): string[];
48
+
49
+ export { BUILTIN_FIXTURES, EMPTY_RESPONSE, ERROR_RESPONSE, LONG_REPLY, SIMPLE_REPLY, TOOL_CALL, getFixture, listFixtures };
@@ -0,0 +1,21 @@
1
+ import {
2
+ BUILTIN_FIXTURES,
3
+ EMPTY_RESPONSE,
4
+ ERROR_RESPONSE,
5
+ LONG_REPLY,
6
+ SIMPLE_REPLY,
7
+ TOOL_CALL,
8
+ getFixture,
9
+ listFixtures
10
+ } from "../chunk-6OHXS7LW.js";
11
+ export {
12
+ BUILTIN_FIXTURES,
13
+ EMPTY_RESPONSE,
14
+ ERROR_RESPONSE,
15
+ LONG_REPLY,
16
+ SIMPLE_REPLY,
17
+ TOOL_CALL,
18
+ getFixture,
19
+ listFixtures
20
+ };
21
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,207 @@
1
+ import { CreateDriver, Driver } from '@agentxjs/core/driver';
2
+ import { F as Fixture } from './types-C6Lf3vz2.js';
3
+ export { a as FixtureEvent, M as MockDriverOptions } from './types-C6Lf3vz2.js';
4
+ export { MockDriver, createMockDriver } from './mock/index.js';
5
+ export { RecordingDriver, RecordingDriverOptions, createRecordingDriver } from './recorder/index.js';
6
+ export { BUILTIN_FIXTURES, EMPTY_RESPONSE, ERROR_RESPONSE, LONG_REPLY, SIMPLE_REPLY, TOOL_CALL, getFixture, listFixtures } from './fixtures/index.js';
7
+ import '@agentxjs/core/agent';
8
+
9
+ /**
10
+ * Devtools SDK - VCR-style fixture management
11
+ *
12
+ * Automatically uses existing fixtures or records new ones on-the-fly.
13
+ *
14
+ * Usage:
15
+ * ```typescript
16
+ * import { createDevtools } from "@agentxjs/devtools";
17
+ *
18
+ * const devtools = createDevtools({
19
+ * fixturesDir: "./fixtures",
20
+ * apiKey: process.env.DEEPRACTICE_API_KEY,
21
+ * });
22
+ *
23
+ * // Has fixture → playback (MockDriver)
24
+ * // No fixture → call API, record, save, return MockDriver
25
+ * const driver = await devtools.driver("hello-test", {
26
+ * message: "Hello!",
27
+ * });
28
+ *
29
+ * await driver.initialize();
30
+ * for await (const event of driver.receive({ content: "Hello" })) {
31
+ * console.log(event);
32
+ * }
33
+ * ```
34
+ */
35
+
36
+ /**
37
+ * Devtools configuration
38
+ */
39
+ interface DevtoolsConfig {
40
+ /**
41
+ * Directory to store/load fixtures
42
+ */
43
+ fixturesDir: string;
44
+ /**
45
+ * API key for recording (required if recording)
46
+ */
47
+ apiKey?: string;
48
+ /**
49
+ * API base URL
50
+ */
51
+ baseUrl?: string;
52
+ /**
53
+ * Default model
54
+ */
55
+ model?: string;
56
+ /**
57
+ * Default system prompt
58
+ */
59
+ systemPrompt?: string;
60
+ /**
61
+ * Working directory for tool execution
62
+ */
63
+ cwd?: string;
64
+ /**
65
+ * Real driver factory for recording
66
+ * If not provided, will try to use @agentxjs/claude-driver
67
+ */
68
+ createDriver?: CreateDriver;
69
+ }
70
+ /**
71
+ * Options for getting a driver
72
+ */
73
+ interface DriverOptions {
74
+ /**
75
+ * Message to send if recording is needed
76
+ */
77
+ message: string;
78
+ /**
79
+ * Override system prompt
80
+ */
81
+ systemPrompt?: string;
82
+ /**
83
+ * Override working directory
84
+ */
85
+ cwd?: string;
86
+ /**
87
+ * Force re-record even if fixture exists
88
+ */
89
+ forceRecord?: boolean;
90
+ }
91
+ /**
92
+ * Devtools SDK
93
+ */
94
+ declare class Devtools {
95
+ private config;
96
+ private realCreateDriver;
97
+ constructor(config: DevtoolsConfig);
98
+ /**
99
+ * Get a driver for the given fixture name
100
+ *
101
+ * - If fixture exists → returns MockDriver with playback
102
+ * - If fixture doesn't exist → records, saves, returns MockDriver
103
+ */
104
+ driver(name: string, options: DriverOptions): Promise<Driver>;
105
+ /**
106
+ * Get a CreateDriver function that uses a pre-loaded fixture
107
+ *
108
+ * NOTE: This loads the fixture synchronously, so the fixture must exist.
109
+ * For async loading/recording, use driver() instead.
110
+ */
111
+ createDriverForFixture(fixturePath: string): CreateDriver;
112
+ /**
113
+ * Record a fixture
114
+ */
115
+ record(name: string, options: DriverOptions): Promise<Fixture>;
116
+ /**
117
+ * Load a fixture by name
118
+ */
119
+ load(name: string): Promise<Fixture>;
120
+ /**
121
+ * Check if a fixture exists
122
+ */
123
+ exists(name: string): boolean;
124
+ /**
125
+ * Delete a fixture
126
+ */
127
+ delete(name: string): Promise<void>;
128
+ private getFixturePath;
129
+ private loadFixture;
130
+ private saveFixture;
131
+ private getRealCreateDriver;
132
+ }
133
+ /**
134
+ * Create a Devtools instance
135
+ */
136
+ declare function createDevtools(config: DevtoolsConfig): Devtools;
137
+ /**
138
+ * Configuration for VCR-aware CreateDriver
139
+ */
140
+ interface VcrCreateDriverConfig {
141
+ /**
142
+ * Directory to store/load fixtures
143
+ */
144
+ fixturesDir: string;
145
+ /**
146
+ * Get current fixture name. Return null to skip VCR (use real driver).
147
+ * Called when driver is created.
148
+ */
149
+ getFixtureName: () => string | null;
150
+ /**
151
+ * API key for recording
152
+ */
153
+ apiKey?: string;
154
+ /**
155
+ * API base URL
156
+ */
157
+ baseUrl?: string;
158
+ /**
159
+ * Default model
160
+ */
161
+ model?: string;
162
+ /**
163
+ * Real driver factory (optional, defaults to @agentxjs/claude-driver)
164
+ */
165
+ createRealDriver?: CreateDriver;
166
+ /**
167
+ * Called when playback mode is used
168
+ */
169
+ onPlayback?: (fixtureName: string) => void;
170
+ /**
171
+ * Called when recording mode is used
172
+ */
173
+ onRecording?: (fixtureName: string) => void;
174
+ /**
175
+ * Called when fixture is saved
176
+ */
177
+ onSaved?: (fixtureName: string, eventCount: number) => void;
178
+ }
179
+ /**
180
+ * Create a VCR-aware CreateDriver function
181
+ *
182
+ * VCR logic (hardcoded):
183
+ * - Fixture exists → Playback (MockDriver)
184
+ * - Fixture missing → Recording (RecordingDriver) → Auto-save on dispose
185
+ *
186
+ * @example
187
+ * ```typescript
188
+ * let currentFixture: string | null = null;
189
+ *
190
+ * const vcrCreateDriver = createVcrCreateDriver({
191
+ * fixturesDir: "./fixtures",
192
+ * getFixtureName: () => currentFixture,
193
+ * apiKey: process.env.API_KEY,
194
+ * });
195
+ *
196
+ * // Before each test:
197
+ * currentFixture = "test-scenario-name";
198
+ *
199
+ * // Use with server/provider:
200
+ * const provider = await createNodeProvider({
201
+ * createDriver: vcrCreateDriver,
202
+ * });
203
+ * ```
204
+ */
205
+ declare function createVcrCreateDriver(config: VcrCreateDriverConfig): CreateDriver;
206
+
207
+ export { Devtools, type DevtoolsConfig, type DriverOptions, Fixture, type VcrCreateDriverConfig, createDevtools, createVcrCreateDriver };