openai-api-mock 0.2.0 → 0.2.2
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 +107 -47
- package/dist/index.cjs +331 -353
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +331 -353
- package/dist/index.js.map +1 -1
- package/index.d.ts +10 -3
- package/package.json +9 -5
package/README.md
CHANGED
|
@@ -7,6 +7,7 @@ This is a Node.js module for mocking OpenAI API responses in a development envir
|
|
|
7
7
|
It's useful for testing and development purposes when you don't want to make actual API calls.
|
|
8
8
|
|
|
9
9
|
The module supports the following OpenAI API endpoints:
|
|
10
|
+
|
|
10
11
|
- chat completions
|
|
11
12
|
- chat completions with streaming
|
|
12
13
|
- chat completions with functions
|
|
@@ -55,15 +56,17 @@ mockOpenAIResponse(true);
|
|
|
55
56
|
|
|
56
57
|
// With configuration options
|
|
57
58
|
mockOpenAIResponse(false, {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
59
|
+
includeErrors: true, // Simulate random API errors
|
|
60
|
+
latency: 1000, // Add 1 second delay to responses
|
|
61
|
+
logRequests: true, // Log incoming requests to console
|
|
62
|
+
seed: 12345, // Seed for consistent/deterministic responses
|
|
63
|
+
useFixedResponses: true, // Use predefined fixed response templates
|
|
64
|
+
baseUrl: 'https://api.openai.com', // Base URL for OpenAI API or compatible service
|
|
63
65
|
});
|
|
64
66
|
```
|
|
65
67
|
|
|
66
68
|
The function accepts two parameters:
|
|
69
|
+
|
|
67
70
|
- `force` (boolean): Determines whether the mock response should be used regardless of the environment. If false or not provided, mocking only occurs in development environment.
|
|
68
71
|
- `options` (object): Additional configuration options
|
|
69
72
|
- `includeErrors` (boolean): When true, randomly simulates API errors
|
|
@@ -71,8 +74,10 @@ The function accepts two parameters:
|
|
|
71
74
|
- `logRequests` (boolean): Logs incoming requests to console for debugging
|
|
72
75
|
- `seed` (number|string): Seed value for consistent/deterministic responses using faker.js
|
|
73
76
|
- `useFixedResponses` (boolean): Use predefined fixed response templates for completely consistent responses
|
|
77
|
+
- `baseUrl` (string): Base URL for the OpenAI API or OpenAI-compatible service (defaults to `https://api.openai.com`)
|
|
74
78
|
|
|
75
79
|
The function returns an object with control methods:
|
|
80
|
+
|
|
76
81
|
```js
|
|
77
82
|
const mock = mockOpenAIResponse();
|
|
78
83
|
|
|
@@ -83,36 +88,78 @@ console.log(mock.isActive);
|
|
|
83
88
|
mock.stopMocking();
|
|
84
89
|
|
|
85
90
|
// Seed management for consistent outputs
|
|
86
|
-
mock.setSeed(12345);
|
|
87
|
-
mock.resetSeed();
|
|
91
|
+
mock.setSeed(12345); // Set a new seed for deterministic responses
|
|
92
|
+
mock.resetSeed(); // Reset to random responses
|
|
88
93
|
|
|
89
94
|
// Template management
|
|
90
95
|
const templates = mock.getResponseTemplates(); // Get available templates
|
|
91
96
|
const customTemplate = mock.createResponseTemplate('SIMPLE_CHAT', {
|
|
92
|
-
|
|
97
|
+
choices: [{ message: { content: 'Custom response' } }],
|
|
93
98
|
});
|
|
94
99
|
|
|
95
|
-
// Add custom endpoint mock (uses
|
|
100
|
+
// Add custom endpoint mock (uses configured base URL)
|
|
96
101
|
mock.addCustomEndpoint('POST', '/v1/custom', (uri, body) => {
|
|
97
|
-
|
|
102
|
+
return [200, { custom: 'response' }];
|
|
103
|
+
});
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### Using with OpenAI-Compatible Services
|
|
107
|
+
|
|
108
|
+
The library supports mocking any OpenAI-compatible API by configuring the `baseUrl` option. This is useful when working with services like Azure OpenAI, local models, or other OpenAI-compatible endpoints.
|
|
109
|
+
|
|
110
|
+
```js
|
|
111
|
+
// Mock Azure OpenAI Service
|
|
112
|
+
mockOpenAIResponse(true, {
|
|
113
|
+
baseUrl: 'https://your-resource.openai.azure.com',
|
|
114
|
+
logRequests: true,
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
// Mock local OpenAI-compatible server (e.g., Ollama, LocalAI)
|
|
118
|
+
mockOpenAIResponse(true, {
|
|
119
|
+
baseUrl: 'http://localhost:11434', // Ollama default port
|
|
120
|
+
logRequests: true,
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
// Mock other OpenAI-compatible services
|
|
124
|
+
mockOpenAIResponse(true, {
|
|
125
|
+
baseUrl: 'https://api.anthropic.com', // or other compatible endpoints
|
|
126
|
+
logRequests: true,
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
// Your existing OpenAI client code will work unchanged
|
|
130
|
+
const openai = new OpenAI({
|
|
131
|
+
apiKey: 'your-api-key',
|
|
132
|
+
baseURL: 'https://your-resource.openai.azure.com', // This will be mocked
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
const response = await openai.chat.completions.create({
|
|
136
|
+
model: 'gpt-4',
|
|
137
|
+
messages: [{ role: 'user', content: 'Hello!' }],
|
|
98
138
|
});
|
|
99
139
|
```
|
|
100
140
|
|
|
141
|
+
When using custom `baseUrl`, the mock will:
|
|
142
|
+
|
|
143
|
+
- Intercept requests to the specified base URL instead of `api.openai.com`
|
|
144
|
+
- Block network connections to that specific host while allowing other network requests
|
|
145
|
+
- Apply all the same mocking behavior (errors, latency, seeding, etc.) to the custom endpoint
|
|
146
|
+
|
|
101
147
|
### Example responses
|
|
102
148
|
|
|
103
149
|
```js
|
|
104
150
|
// Call the mockOpenAIResponse function once to set up the mock
|
|
105
|
-
mockOpenAIResponse()
|
|
151
|
+
mockOpenAIResponse();
|
|
106
152
|
|
|
107
153
|
// Now, when you call the OpenAI API, it will return a mock response
|
|
108
154
|
const response = await openai.chat.completions.create({
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
155
|
+
model: 'gpt-3.5',
|
|
156
|
+
messages: [
|
|
157
|
+
{ role: 'system', content: "You're an expert chef" },
|
|
158
|
+
{ role: 'user', content: 'Suggest at least 5 recipes' },
|
|
159
|
+
],
|
|
114
160
|
});
|
|
115
|
-
|
|
161
|
+
```
|
|
162
|
+
|
|
116
163
|
In this example, the `response` constant will contain mock data, simulating a response from the OpenAI API:
|
|
117
164
|
|
|
118
165
|
```javascript
|
|
@@ -132,24 +179,25 @@ In this example, the `response` constant will contain mock data, simulating a re
|
|
|
132
179
|
usage: { completion_tokens: 17, prompt_tokens: 57, total_tokens: 74 }
|
|
133
180
|
}
|
|
134
181
|
```
|
|
182
|
+
|
|
135
183
|
The library also supports mocking `stream` responses
|
|
136
184
|
|
|
137
185
|
```js
|
|
138
186
|
// Call the mockOpenAIResponse function once to set up the mock
|
|
139
|
-
mockOpenAIResponse()
|
|
187
|
+
mockOpenAIResponse();
|
|
140
188
|
// Now, when you call the OpenAI API, it will return a mock response
|
|
141
189
|
const response = await openai.chat.completions.create({
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
190
|
+
model: 'gpt-3.5',
|
|
191
|
+
stream: true,
|
|
192
|
+
messages: [
|
|
193
|
+
{ role: 'system', content: "You're an expert chef" },
|
|
194
|
+
{ role: 'user', content: 'Suggest at least 5 recipes' },
|
|
195
|
+
],
|
|
148
196
|
});
|
|
149
197
|
|
|
150
|
-
// then read it
|
|
198
|
+
// then read it
|
|
151
199
|
for await (const part of response) {
|
|
152
|
-
|
|
200
|
+
console.log(part.choices[0]?.delta?.content || '');
|
|
153
201
|
}
|
|
154
202
|
```
|
|
155
203
|
|
|
@@ -168,12 +216,12 @@ const mock = mockOpenAIResponse(true, { seed: 12345 });
|
|
|
168
216
|
// Multiple calls will return identical responses
|
|
169
217
|
const response1 = await openai.chat.completions.create({
|
|
170
218
|
model: 'gpt-3.5-turbo',
|
|
171
|
-
messages: [{ role: 'user', content: 'Hello' }]
|
|
219
|
+
messages: [{ role: 'user', content: 'Hello' }],
|
|
172
220
|
});
|
|
173
221
|
|
|
174
222
|
const response2 = await openai.chat.completions.create({
|
|
175
223
|
model: 'gpt-3.5-turbo',
|
|
176
|
-
messages: [{ role: 'user', content: 'Hello' }]
|
|
224
|
+
messages: [{ role: 'user', content: 'Hello' }],
|
|
177
225
|
});
|
|
178
226
|
|
|
179
227
|
// response1 and response2 will be identical
|
|
@@ -190,11 +238,11 @@ const mock = mockOpenAIResponse(true, { useFixedResponses: true });
|
|
|
190
238
|
|
|
191
239
|
const response = await openai.chat.completions.create({
|
|
192
240
|
model: 'gpt-3.5-turbo',
|
|
193
|
-
messages: [{ role: 'user', content: 'Any message' }]
|
|
241
|
+
messages: [{ role: 'user', content: 'Any message' }],
|
|
194
242
|
});
|
|
195
243
|
|
|
196
244
|
// Will always return the same fixed response
|
|
197
|
-
console.log(response.choices[0].message.content);
|
|
245
|
+
console.log(response.choices[0].message.content);
|
|
198
246
|
// "This is a consistent test response."
|
|
199
247
|
```
|
|
200
248
|
|
|
@@ -209,7 +257,7 @@ const mock = mockOpenAIResponse(true);
|
|
|
209
257
|
mock.setSeed(12345);
|
|
210
258
|
const responseA = await openai.chat.completions.create({...});
|
|
211
259
|
|
|
212
|
-
// Test scenario B
|
|
260
|
+
// Test scenario B
|
|
213
261
|
mock.setSeed(54321);
|
|
214
262
|
const responseB = await openai.chat.completions.create({...});
|
|
215
263
|
|
|
@@ -219,15 +267,24 @@ const responseRandom = await openai.chat.completions.create({...});
|
|
|
219
267
|
```
|
|
220
268
|
|
|
221
269
|
For comprehensive examples and best practices, see [CONSISTENCY_EXAMPLES.md](./CONSISTENCY_EXAMPLES.md).
|
|
222
|
-
```
|
|
223
270
|
|
|
224
271
|
## Intercepted URLs
|
|
225
272
|
|
|
226
|
-
This module uses the `nock` library to intercept HTTP calls to
|
|
273
|
+
This module uses the `nock` library to intercept HTTP calls to OpenAI API endpoints. By default, it intercepts:
|
|
227
274
|
|
|
228
275
|
- `https://api.openai.com/v1/chat/completions`: This endpoint is used for generating chat completions.
|
|
229
276
|
- `https://api.openai.com/v1/images/generations`: This endpoint is used for generating images.
|
|
230
277
|
|
|
278
|
+
When using the `baseUrl` option, the intercepted URLs will use your configured base URL instead:
|
|
279
|
+
|
|
280
|
+
```js
|
|
281
|
+
// Custom base URL example
|
|
282
|
+
mockOpenAIResponse(true, { baseUrl: 'https://your-api.example.com' });
|
|
283
|
+
|
|
284
|
+
// Will intercept:
|
|
285
|
+
// - https://your-api.example.com/v1/chat/completions
|
|
286
|
+
// - https://your-api.example.com/v1/images/generations
|
|
287
|
+
```
|
|
231
288
|
|
|
232
289
|
## TypeScript Support
|
|
233
290
|
|
|
@@ -238,38 +295,41 @@ import { mockOpenAIResponse, MockOptions } from 'openai-api-mock';
|
|
|
238
295
|
|
|
239
296
|
// Configure with TypeScript types
|
|
240
297
|
const options: MockOptions = {
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
298
|
+
includeErrors: true, // Optional: simulate random API errors
|
|
299
|
+
latency: 1000, // Optional: add 1 second delay
|
|
300
|
+
logRequests: true, // Optional: log requests to console
|
|
301
|
+
seed: 12345, // Optional: seed for consistent responses
|
|
302
|
+
useFixedResponses: true, // Optional: use fixed response templates
|
|
303
|
+
baseUrl: 'https://api.openai.com', // Optional: custom base URL
|
|
246
304
|
};
|
|
247
305
|
|
|
248
306
|
const mock = mockOpenAIResponse(true, options);
|
|
249
307
|
|
|
250
308
|
// TypeScript provides full type checking and autocompletion
|
|
251
|
-
console.log(mock.isActive);
|
|
252
|
-
mock.stopMocking();
|
|
253
|
-
mock.setSeed(54321);
|
|
254
|
-
mock.resetSeed();
|
|
309
|
+
console.log(mock.isActive); // boolean
|
|
310
|
+
mock.stopMocking(); // function
|
|
311
|
+
mock.setSeed(54321); // function with type checking
|
|
312
|
+
mock.resetSeed(); // function
|
|
255
313
|
|
|
256
314
|
// Template methods with type safety
|
|
257
|
-
const templates = mock.getResponseTemplates();
|
|
315
|
+
const templates = mock.getResponseTemplates(); // Record<string, any>
|
|
258
316
|
const customTemplate = mock.createResponseTemplate('SIMPLE_CHAT', {
|
|
259
|
-
|
|
317
|
+
choices: [{ message: { content: 'Custom content' } }],
|
|
260
318
|
});
|
|
261
319
|
|
|
262
320
|
// Custom endpoints with type safety
|
|
263
321
|
mock.addCustomEndpoint('POST', '/v1/custom', (uri, body) => {
|
|
264
|
-
|
|
322
|
+
return [200, { custom: 'response' }];
|
|
265
323
|
});
|
|
266
324
|
```
|
|
267
325
|
|
|
268
326
|
## Dependencies
|
|
327
|
+
|
|
269
328
|
This module depends on the following npm packages:
|
|
270
329
|
|
|
271
|
-
- nock : For intercepting HTTP calls.
|
|
272
|
-
-
|
|
330
|
+
- `nock` : For intercepting HTTP calls.
|
|
331
|
+
- `@faker-js/faker` : For generating fake data.
|
|
273
332
|
|
|
274
333
|
## License
|
|
334
|
+
|
|
275
335
|
This project is licensed under the MIT License.
|