openai-api-mock 0.1.33 → 0.2.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 +106 -4
- package/dist/index.cjs +163 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +163 -7
- package/dist/index.js.map +1 -1
- package/index.d.ts +24 -0
- package/package.json +7 -3
package/dist/index.js
CHANGED
|
@@ -2186,16 +2186,129 @@ function getImageResponce(requestBody) {
|
|
|
2186
2186
|
data
|
|
2187
2187
|
};
|
|
2188
2188
|
}
|
|
2189
|
+
const RESPONSE_TEMPLATES = {
|
|
2190
|
+
SIMPLE_CHAT: {
|
|
2191
|
+
choices: [
|
|
2192
|
+
{
|
|
2193
|
+
finish_reason: "stop",
|
|
2194
|
+
index: 0,
|
|
2195
|
+
message: {
|
|
2196
|
+
content: "This is a consistent test response.",
|
|
2197
|
+
role: "assistant"
|
|
2198
|
+
},
|
|
2199
|
+
logprobs: null
|
|
2200
|
+
}
|
|
2201
|
+
],
|
|
2202
|
+
created: 1640995200,
|
|
2203
|
+
id: "chatcmpl-test123456789",
|
|
2204
|
+
model: "gpt-3.5-mock",
|
|
2205
|
+
object: "chat.completion",
|
|
2206
|
+
usage: {
|
|
2207
|
+
completion_tokens: 10,
|
|
2208
|
+
prompt_tokens: 20,
|
|
2209
|
+
total_tokens: 30
|
|
2210
|
+
}
|
|
2211
|
+
},
|
|
2212
|
+
FUNCTION_CALL: {
|
|
2213
|
+
id: "chatcmpl-test123456789",
|
|
2214
|
+
object: "chat.completion",
|
|
2215
|
+
created: 1640995200,
|
|
2216
|
+
model: "gpt-3.5-mock",
|
|
2217
|
+
choices: [
|
|
2218
|
+
{
|
|
2219
|
+
index: 0,
|
|
2220
|
+
message: {
|
|
2221
|
+
role: "assistant",
|
|
2222
|
+
content: null,
|
|
2223
|
+
function_call: {
|
|
2224
|
+
name: "test_function",
|
|
2225
|
+
arguments: '{"param1": "test_value", "param2": 42}'
|
|
2226
|
+
}
|
|
2227
|
+
},
|
|
2228
|
+
finish_reason: "function_call"
|
|
2229
|
+
}
|
|
2230
|
+
],
|
|
2231
|
+
usage: {
|
|
2232
|
+
prompt_tokens: 81,
|
|
2233
|
+
completion_tokens: 19,
|
|
2234
|
+
total_tokens: 100
|
|
2235
|
+
}
|
|
2236
|
+
},
|
|
2237
|
+
TOOL_CALL: {
|
|
2238
|
+
id: "chatcmpl-test123456789",
|
|
2239
|
+
object: "chat.completion",
|
|
2240
|
+
created: 1640995200,
|
|
2241
|
+
model: "gpt-3.5-mock",
|
|
2242
|
+
choices: [
|
|
2243
|
+
{
|
|
2244
|
+
index: 0,
|
|
2245
|
+
message: {
|
|
2246
|
+
role: "assistant",
|
|
2247
|
+
content: null,
|
|
2248
|
+
tool_calls: [
|
|
2249
|
+
{
|
|
2250
|
+
id: "call_test123456789",
|
|
2251
|
+
type: "function",
|
|
2252
|
+
function: {
|
|
2253
|
+
name: "test_function",
|
|
2254
|
+
arguments: '{"param1": "test_value", "param2": 42}'
|
|
2255
|
+
}
|
|
2256
|
+
}
|
|
2257
|
+
]
|
|
2258
|
+
},
|
|
2259
|
+
finish_reason: "tool_calls"
|
|
2260
|
+
}
|
|
2261
|
+
],
|
|
2262
|
+
usage: {
|
|
2263
|
+
prompt_tokens: 81,
|
|
2264
|
+
completion_tokens: 19,
|
|
2265
|
+
total_tokens: 100
|
|
2266
|
+
}
|
|
2267
|
+
},
|
|
2268
|
+
IMAGE_GENERATION: {
|
|
2269
|
+
created: 1640995200,
|
|
2270
|
+
data: [
|
|
2271
|
+
{
|
|
2272
|
+
url: "https://example.com/test-image.png"
|
|
2273
|
+
}
|
|
2274
|
+
]
|
|
2275
|
+
}
|
|
2276
|
+
};
|
|
2277
|
+
function createResponseTemplate(templateType, overrides = {}) {
|
|
2278
|
+
const template = RESPONSE_TEMPLATES[templateType];
|
|
2279
|
+
if (!template) {
|
|
2280
|
+
throw new Error(`Unknown template type: ${templateType}`);
|
|
2281
|
+
}
|
|
2282
|
+
return deepMerge(template, overrides);
|
|
2283
|
+
}
|
|
2284
|
+
function deepMerge(target, source) {
|
|
2285
|
+
const result = { ...target };
|
|
2286
|
+
for (const key in source) {
|
|
2287
|
+
if (source[key] && typeof source[key] === "object" && !Array.isArray(source[key])) {
|
|
2288
|
+
result[key] = deepMerge(result[key] || {}, source[key]);
|
|
2289
|
+
} else {
|
|
2290
|
+
result[key] = source[key];
|
|
2291
|
+
}
|
|
2292
|
+
}
|
|
2293
|
+
return result;
|
|
2294
|
+
}
|
|
2189
2295
|
const OPEN_AI_BASE_URL = "https://api.openai.com";
|
|
2190
2296
|
const CHAT_COMPLETIONS_ENDPOINT = "/v1/chat/completions";
|
|
2191
2297
|
const IMAGE_GENERATIONS_ENDPOINT = "/v1/images/generations";
|
|
2192
|
-
const customScopes = [];
|
|
2193
2298
|
function mockOpenAIResponse(force = false, options = {}) {
|
|
2194
2299
|
const {
|
|
2195
2300
|
includeErrors = false,
|
|
2196
2301
|
latency = 0,
|
|
2197
|
-
logRequests = false
|
|
2302
|
+
logRequests = false,
|
|
2303
|
+
seed = null,
|
|
2304
|
+
useFixedResponses = false
|
|
2198
2305
|
} = options;
|
|
2306
|
+
if (seed !== null) {
|
|
2307
|
+
f.seed(seed);
|
|
2308
|
+
if (logRequests) {
|
|
2309
|
+
console.log(`[openai-api-mock] Using seed for consistent outputs: ${seed}`);
|
|
2310
|
+
}
|
|
2311
|
+
}
|
|
2199
2312
|
const env = process.env.NODE_ENV || "development";
|
|
2200
2313
|
if (env !== "development" && !force) {
|
|
2201
2314
|
return { isActive: false, stopMocking };
|
|
@@ -2216,12 +2329,21 @@ function mockOpenAIResponse(force = false, options = {}) {
|
|
|
2216
2329
|
const stream = createChatStream(requestBody);
|
|
2217
2330
|
return [200, stream];
|
|
2218
2331
|
}
|
|
2332
|
+
if (useFixedResponses) {
|
|
2333
|
+
if (requestBody.tools) {
|
|
2334
|
+
return [200, createResponseTemplate("TOOL_CALL")];
|
|
2335
|
+
} else if (requestBody.functions) {
|
|
2336
|
+
return [200, createResponseTemplate("FUNCTION_CALL")];
|
|
2337
|
+
} else {
|
|
2338
|
+
return [200, createResponseTemplate("SIMPLE_CHAT")];
|
|
2339
|
+
}
|
|
2340
|
+
}
|
|
2219
2341
|
return [200, getChatResponce(requestBody)];
|
|
2220
2342
|
} catch (error) {
|
|
2221
2343
|
console.error("[openai-api-mock] Error processing chat request:", error);
|
|
2222
2344
|
return [500, { error: { message: "Internal server error in mock" } }];
|
|
2223
2345
|
}
|
|
2224
|
-
});
|
|
2346
|
+
}).persist();
|
|
2225
2347
|
nock(OPEN_AI_BASE_URL).post(IMAGE_GENERATIONS_ENDPOINT).delay(latency).reply(function(uri, requestBody) {
|
|
2226
2348
|
if (logRequests) {
|
|
2227
2349
|
console.log(`[openai-api-mock] Image request:`, JSON.stringify(requestBody, null, 2));
|
|
@@ -2233,16 +2355,52 @@ function mockOpenAIResponse(force = false, options = {}) {
|
|
|
2233
2355
|
if (includeErrors && Math.random() < 0.05) {
|
|
2234
2356
|
return [400, { error: { message: "Your request was rejected as a result of our safety system." } }];
|
|
2235
2357
|
}
|
|
2358
|
+
if (useFixedResponses) {
|
|
2359
|
+
return [200, createResponseTemplate("IMAGE_GENERATION")];
|
|
2360
|
+
}
|
|
2236
2361
|
return [200, getImageResponce(requestBody)];
|
|
2237
2362
|
} catch (error) {
|
|
2238
2363
|
console.error("[openai-api-mock] Error processing image request:", error);
|
|
2239
2364
|
return [500, { error: { message: "Internal server error in mock" } }];
|
|
2240
2365
|
}
|
|
2241
|
-
});
|
|
2366
|
+
}).persist();
|
|
2242
2367
|
nock.enableNetConnect((host) => host !== "api.openai.com");
|
|
2243
2368
|
return {
|
|
2244
2369
|
isActive: true,
|
|
2245
2370
|
stopMocking,
|
|
2371
|
+
/**
|
|
2372
|
+
* Resets the faker seed to ensure consistent outputs for subsequent requests
|
|
2373
|
+
* @param {number|string} newSeed - New seed value to use
|
|
2374
|
+
*/
|
|
2375
|
+
setSeed(newSeed) {
|
|
2376
|
+
f.seed(newSeed);
|
|
2377
|
+
if (logRequests) {
|
|
2378
|
+
console.log(`[openai-api-mock] Seed updated to: ${newSeed}`);
|
|
2379
|
+
}
|
|
2380
|
+
},
|
|
2381
|
+
/**
|
|
2382
|
+
* Resets faker to use random values (removes deterministic behavior)
|
|
2383
|
+
*/
|
|
2384
|
+
resetSeed() {
|
|
2385
|
+
f.seed();
|
|
2386
|
+
if (logRequests) {
|
|
2387
|
+
console.log(`[openai-api-mock] Seed reset - using random values`);
|
|
2388
|
+
}
|
|
2389
|
+
},
|
|
2390
|
+
/**
|
|
2391
|
+
* Get available response templates
|
|
2392
|
+
* @returns {Object} Available response templates
|
|
2393
|
+
*/
|
|
2394
|
+
getResponseTemplates() {
|
|
2395
|
+
return RESPONSE_TEMPLATES;
|
|
2396
|
+
},
|
|
2397
|
+
/**
|
|
2398
|
+
* Create a custom response template
|
|
2399
|
+
* @param {string} templateType - Type of template to use
|
|
2400
|
+
* @param {Object} overrides - Values to override in the template
|
|
2401
|
+
* @returns {Object} Response template with overrides applied
|
|
2402
|
+
*/
|
|
2403
|
+
createResponseTemplate,
|
|
2246
2404
|
/**
|
|
2247
2405
|
* Adds a custom endpoint mock
|
|
2248
2406
|
* @param {string} method - HTTP method (e.g., 'GET', 'POST')
|
|
@@ -2251,14 +2409,12 @@ function mockOpenAIResponse(force = false, options = {}) {
|
|
|
2251
2409
|
*/
|
|
2252
2410
|
addCustomEndpoint(method, path, handler) {
|
|
2253
2411
|
const methodLower = method.toLowerCase();
|
|
2254
|
-
|
|
2255
|
-
customScopes.push(scope);
|
|
2412
|
+
nock(OPEN_AI_BASE_URL)[methodLower](path).reply(handler).persist();
|
|
2256
2413
|
}
|
|
2257
2414
|
};
|
|
2258
2415
|
}
|
|
2259
2416
|
function stopMocking() {
|
|
2260
2417
|
nock.cleanAll();
|
|
2261
|
-
customScopes.forEach((scope) => scope.persist(false));
|
|
2262
2418
|
}
|
|
2263
2419
|
export {
|
|
2264
2420
|
mockOpenAIResponse,
|