mock-openai-api
Version:
A mock OpenAI Compatible Provider API server
794 lines • 32.2 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.getModels = getModels;
exports.createChatCompletion = createChatCompletion;
exports.createChatCompletionStream = createChatCompletionStream;
exports.createToolCallResponseStream = createToolCallResponseStream;
exports.generateImage = generateImage;
const mockData_1 = require("../data/mockData");
const helpers_1 = require("../utils/helpers");
/**
* Get model list
*/
function getModels() {
const models = mockData_1.mockModels.map((mockModel) => ({
id: mockModel.id,
object: "model",
created: (0, helpers_1.getCurrentTimestamp)(),
owned_by: "mock-openai",
}));
return {
object: "list",
data: models,
};
}
/**
* Create chat completion (non-streaming)
*/
function createChatCompletion(request) {
// Validate model
const model = (0, helpers_1.findModelById)(request.model);
if (!model) {
return (0, helpers_1.formatErrorResponse)(`Model '${request.model}' does not exist`);
}
// Get last user message
const lastUserMessage = request.messages
.slice()
.reverse()
.find((msg) => msg.role === "user");
if (!lastUserMessage) {
return (0, helpers_1.formatErrorResponse)("No user message found");
}
// Select test case
const testCase = (0, helpers_1.selectTestCase)(model, lastUserMessage.content || "");
const id = (0, helpers_1.generateChatCompletionId)();
const timestamp = (0, helpers_1.getCurrentTimestamp)();
// Build response message
let content = testCase.response;
// If it's a thinking-tag model and has reasoning_content, wrap it in <think> tags
if (model.type === "thinking-tag" && testCase.reasoning_content) {
content = `<think>\n${testCase.reasoning_content}\n</think>\n\n${testCase.response}`;
}
let responseMessage = {
role: "assistant",
content,
};
// If it's a tool calls model, add tool calls
if (model.type === "tool-calls" && testCase.toolCall) {
responseMessage.content = null;
responseMessage.tool_calls = [
{
id: testCase.toolCall.id || `call_${Date.now()}`,
type: "function",
function: {
name: testCase.toolCall.name,
arguments: JSON.stringify(testCase.toolCall.arguments),
},
},
];
}
const promptTokens = (0, helpers_1.calculateTokens)(lastUserMessage.content || "");
const completionTokens = (0, helpers_1.calculateTokens)(testCase.response || "");
const reasoningTokens = testCase.reasoning_content
? (0, helpers_1.calculateTokens)(testCase.reasoning_content)
: 0;
let finishReason = "stop";
if (testCase.toolCall) {
finishReason = "tool_calls";
}
const response = {
id,
object: "chat.completion",
created: timestamp,
model: request.model,
choices: [
{
index: 0,
message: responseMessage,
finish_reason: finishReason,
},
],
usage: {
prompt_tokens: promptTokens,
completion_tokens: completionTokens,
total_tokens: promptTokens + completionTokens + reasoningTokens,
completion_tokens_details: {
reasoning_tokens: reasoningTokens,
},
},
};
return response;
}
/**
* Create chat completion (streaming)
*/
function* createChatCompletionStream(request) {
// Validate model
const model = (0, helpers_1.findModelById)(request.model);
if (!model) {
const errorChunk = `data: ${JSON.stringify((0, helpers_1.formatErrorResponse)(`Model '${request.model}' does not exist`))}\n\n`;
yield errorChunk;
return;
}
// Get last user message
const lastUserMessage = request.messages
.slice()
.reverse()
.find((msg) => msg.role === "user");
if (!lastUserMessage) {
const errorChunk = `data: ${JSON.stringify((0, helpers_1.formatErrorResponse)("No user message found"))}\n\n`;
yield errorChunk;
return;
}
// Select test case
const testCase = (0, helpers_1.selectTestCase)(model, lastUserMessage.content || "");
const id = (0, helpers_1.generateChatCompletionId)();
const timestamp = (0, helpers_1.getCurrentTimestamp)();
const systemFingerprint = `fp_${Math.random()
.toString(36)
.substr(2, 10)}_prod0425fp8`;
let completionTokens = 0;
let reasoningTokens = 0;
// Handle tool calls first (tool-calls model type)
if (model.type === "tool-calls" && testCase.toolCall) {
// 第一阶段:发送tool call
// Send first chunk - role and empty content
const firstChunk = {
id,
object: "chat.completion.chunk",
created: timestamp,
model: request.model,
system_fingerprint: systemFingerprint,
choices: [
{
index: 0,
delta: {
role: "assistant",
content: "",
},
logprobs: null,
finish_reason: null,
},
],
usage: null,
};
yield `data: ${JSON.stringify(firstChunk)}\n\n`;
// Send tool call chunk with basic info
const toolCallChunk = {
id,
object: "chat.completion.chunk",
created: timestamp,
model: request.model,
system_fingerprint: systemFingerprint,
choices: [
{
index: 0,
delta: {
tool_calls: [
{
index: 0,
id: testCase.toolCall.id || `call_0_${Date.now()}`,
type: "function",
function: {
name: testCase.toolCall.name,
arguments: "",
},
},
],
},
logprobs: null,
finish_reason: null,
},
],
usage: null,
};
yield `data: ${JSON.stringify(toolCallChunk)}\n\n`;
// Send arguments chunk
const argumentsChunk = {
id,
object: "chat.completion.chunk",
created: timestamp,
model: request.model,
system_fingerprint: systemFingerprint,
choices: [
{
index: 0,
delta: {
tool_calls: [
{
index: 0,
function: {
arguments: JSON.stringify(testCase.toolCall.arguments),
},
},
],
},
logprobs: null,
finish_reason: null,
},
],
usage: null,
};
yield `data: ${JSON.stringify(argumentsChunk)}\n\n`;
// Send final chunk for first phase with tool_calls finish_reason
const promptTokens = (0, helpers_1.calculateTokens)(lastUserMessage.content || "");
const firstPhaseEndChunk = {
id,
object: "chat.completion.chunk",
created: timestamp,
model: request.model,
system_fingerprint: systemFingerprint,
choices: [
{
index: 0,
delta: {
content: "",
},
logprobs: null,
finish_reason: "tool_calls",
},
],
usage: {
prompt_tokens: promptTokens,
completion_tokens: 19, // Based on real log
total_tokens: promptTokens + 19,
prompt_tokens_details: {
cached_tokens: 768, // Based on real log
},
prompt_cache_hit_tokens: 768,
prompt_cache_miss_tokens: 60,
},
};
yield `data: ${JSON.stringify(firstPhaseEndChunk)}\n\n`;
// Send end marker for first phase
yield `data: [DONE]\n\n`;
// 这里应该停止,等待外部系统调用工具并发起第二阶段请求
// 在实际应用中,这里会是一个新的请求周期
return;
}
if (model.type === "thinking") {
// Thinking mode: output reasoning_content first, then content
// Send first chunk - role and empty reasoning_content
const firstChunk = {
id,
object: "chat.completion.chunk",
created: timestamp,
model: request.model,
system_fingerprint: systemFingerprint,
choices: [
{
index: 0,
delta: {
role: "assistant",
content: null,
reasoning_content: testCase.reasoning_content || "",
},
finish_reason: null,
},
],
};
yield `data: ${JSON.stringify(firstChunk)}\n\n`;
// Output reasoning_content chunks
if (testCase.reasoning_content && testCase.reasoning_chunks) {
for (const chunk of testCase.reasoning_chunks) {
const reasoningChunk = {
id,
object: "chat.completion.chunk",
created: timestamp,
model: request.model,
system_fingerprint: systemFingerprint,
choices: [
{
index: 0,
delta: {
reasoning_content: chunk,
},
finish_reason: null,
},
],
};
yield `data: ${JSON.stringify(reasoningChunk)}\n\n`;
reasoningTokens += (0, helpers_1.calculateTokens)(chunk);
}
}
// Start outputting content, set reasoning_content to null
const contentStartChunk = {
id,
object: "chat.completion.chunk",
created: timestamp,
model: request.model,
system_fingerprint: systemFingerprint,
choices: [
{
index: 0,
delta: {
reasoning_content: null,
content: "",
},
finish_reason: null,
},
],
};
yield `data: ${JSON.stringify(contentStartChunk)}\n\n`;
// Use predefined stream chunks if available
if (testCase.streamChunks && testCase.streamChunks.length > 0) {
for (const chunk of testCase.streamChunks) {
const streamChunk = {
id,
object: "chat.completion.chunk",
created: timestamp,
model: request.model,
system_fingerprint: systemFingerprint,
choices: [
{
index: 0,
delta: {
content: chunk,
},
finish_reason: null,
},
],
};
yield `data: ${JSON.stringify(streamChunk)}\n\n`;
completionTokens += (0, helpers_1.calculateTokens)(chunk);
}
}
else {
// Otherwise split the complete response into chunks
const words = testCase.response.split(" ");
for (let i = 0; i < words.length; i += 2) {
const chunkText = words.slice(i, i + 2).join(" ") + (i + 2 < words.length ? " " : "");
const streamChunk = {
id,
object: "chat.completion.chunk",
created: timestamp,
model: request.model,
system_fingerprint: systemFingerprint,
choices: [
{
index: 0,
delta: {
content: chunkText,
},
finish_reason: null,
},
],
};
yield `data: ${JSON.stringify(streamChunk)}\n\n`;
completionTokens += (0, helpers_1.calculateTokens)(chunkText);
}
}
}
else if (model.type === "thinking-tag") {
// thinking-tag mode: surround reasoning_content with <think> tags in content
// Send first chunk - role and empty content
const firstChunk = {
id,
object: "chat.completion.chunk",
created: timestamp,
model: request.model,
system_fingerprint: systemFingerprint,
choices: [
{
index: 0,
delta: {
role: "assistant",
content: "",
},
finish_reason: null,
},
],
};
yield `data: ${JSON.stringify(firstChunk)}\n\n`;
if (testCase.reasoning_content) {
// First output <think> start tag
const thinkStartChunk = {
id,
object: "chat.completion.chunk",
created: timestamp,
model: request.model,
system_fingerprint: systemFingerprint,
choices: [
{
index: 0,
delta: {
content: "<think>\n",
},
finish_reason: null,
},
],
};
yield `data: ${JSON.stringify(thinkStartChunk)}\n\n`;
// Output reasoning_content chunks
if (testCase.reasoning_chunks && testCase.reasoning_chunks.length > 0) {
for (const chunk of testCase.reasoning_chunks) {
const reasoningChunk = {
id,
object: "chat.completion.chunk",
created: timestamp,
model: request.model,
system_fingerprint: systemFingerprint,
choices: [
{
index: 0,
delta: {
content: chunk,
},
finish_reason: null,
},
],
};
yield `data: ${JSON.stringify(reasoningChunk)}\n\n`;
reasoningTokens += (0, helpers_1.calculateTokens)(chunk);
}
}
else {
// Output complete reasoning_content
const reasoningChunk = {
id,
object: "chat.completion.chunk",
created: timestamp,
model: request.model,
system_fingerprint: systemFingerprint,
choices: [
{
index: 0,
delta: {
content: testCase.reasoning_content,
},
finish_reason: null,
},
],
};
yield `data: ${JSON.stringify(reasoningChunk)}\n\n`;
reasoningTokens += (0, helpers_1.calculateTokens)(testCase.reasoning_content);
}
// Output </think> end tag and newline
const thinkEndChunk = {
id,
object: "chat.completion.chunk",
created: timestamp,
model: request.model,
system_fingerprint: systemFingerprint,
choices: [
{
index: 0,
delta: {
content: "\n</think>\n\n",
},
finish_reason: null,
},
],
};
yield `data: ${JSON.stringify(thinkEndChunk)}\n\n`;
}
// Output normal response content
if (testCase.streamChunks && testCase.streamChunks.length > 0) {
for (const chunk of testCase.streamChunks) {
const streamChunk = {
id,
object: "chat.completion.chunk",
created: timestamp,
model: request.model,
system_fingerprint: systemFingerprint,
choices: [
{
index: 0,
delta: {
content: chunk,
},
finish_reason: null,
},
],
};
yield `data: ${JSON.stringify(streamChunk)}\n\n`;
completionTokens += (0, helpers_1.calculateTokens)(chunk);
}
}
else {
// Otherwise split the complete response into chunks
const words = testCase.response.split(" ");
for (let i = 0; i < words.length; i += 2) {
const chunkText = words.slice(i, i + 2).join(" ") + (i + 2 < words.length ? " " : "");
const streamChunk = {
id,
object: "chat.completion.chunk",
created: timestamp,
model: request.model,
system_fingerprint: systemFingerprint,
choices: [
{
index: 0,
delta: {
content: chunkText,
},
finish_reason: null,
},
],
};
yield `data: ${JSON.stringify(streamChunk)}\n\n`;
completionTokens += (0, helpers_1.calculateTokens)(chunkText);
}
}
}
else {
// Non-thinking mode: normal output
// Send first chunk - role and empty content
const firstChunk = {
id,
object: "chat.completion.chunk",
created: timestamp,
model: request.model,
system_fingerprint: systemFingerprint,
choices: [
{
index: 0,
delta: {
role: "assistant",
content: "",
},
finish_reason: null,
},
],
};
yield `data: ${JSON.stringify(firstChunk)}\n\n`;
// If there are predefined streaming chunks, use them
if (testCase.streamChunks && testCase.streamChunks.length > 0) {
for (const chunk of testCase.streamChunks) {
const streamChunk = {
id,
object: "chat.completion.chunk",
created: timestamp,
model: request.model,
system_fingerprint: systemFingerprint,
choices: [
{
index: 0,
delta: {
content: chunk,
},
finish_reason: null,
},
],
};
yield `data: ${JSON.stringify(streamChunk)}\n\n`;
completionTokens += (0, helpers_1.calculateTokens)(chunk);
}
}
else {
// Otherwise split the complete response into chunks
const words = testCase.response.split(" ");
for (let i = 0; i < words.length; i += 2) {
const chunkText = words.slice(i, i + 2).join(" ") + (i + 2 < words.length ? " " : "");
const streamChunk = {
id,
object: "chat.completion.chunk",
created: timestamp,
model: request.model,
system_fingerprint: systemFingerprint,
choices: [
{
index: 0,
delta: {
content: chunkText,
},
finish_reason: null,
},
],
};
yield `data: ${JSON.stringify(streamChunk)}\n\n`;
completionTokens += (0, helpers_1.calculateTokens)(chunkText);
}
}
}
// Calculate token usage
const promptTokens = (0, helpers_1.calculateTokens)(lastUserMessage.content || "");
// Send last chunk - contains finish_reason and usage
const lastChunk = {
id,
object: "chat.completion.chunk",
created: timestamp,
model: request.model,
system_fingerprint: systemFingerprint,
choices: [
{
index: 0,
delta: {},
finish_reason: "stop",
},
],
usage: {
prompt_tokens: promptTokens,
completion_tokens: completionTokens,
total_tokens: promptTokens + completionTokens + reasoningTokens,
completion_tokens_details: {
reasoning_tokens: reasoningTokens,
},
},
};
yield `data: ${JSON.stringify(lastChunk)}\n\n`;
// Send end marker
yield `data: [DONE]\n\n`;
}
/**
* Create tool call response stream (second phase)
* 这个函数处理tool call执行后的第二阶段流式响应
*/
function* createToolCallResponseStream(request, toolMessageId, toolMessageContent) {
console.log("createToolCallResponseStream", request, toolMessageId, toolMessageContent);
// Validate model
const model = (0, helpers_1.findModelById)(request.model);
if (!model || model.type !== "tool-calls") {
const errorChunk = `data: ${JSON.stringify((0, helpers_1.formatErrorResponse)(`Invalid model for tool call response`))}\n\n`;
yield errorChunk;
return;
}
// Get last user message
const lastUserMessage = request.messages
.slice()
.reverse()
.find((msg) => msg.role === "user");
if (!lastUserMessage) {
const errorChunk = `data: ${JSON.stringify((0, helpers_1.formatErrorResponse)("No user message found"))}\n\n`;
yield errorChunk;
return;
}
// Select test case
const testCase = (0, helpers_1.selectTestCase)(model, lastUserMessage.content || "");
const id = (0, helpers_1.generateChatCompletionId)();
const timestamp = (0, helpers_1.getCurrentTimestamp)();
const systemFingerprint = `fp_${Math.random()
.toString(36)
.substr(2, 10)}_prod0425fp8`;
// Send first chunk - role and empty content for second phase
const firstChunk = {
id,
object: "chat.completion.chunk",
created: timestamp,
model: request.model,
system_fingerprint: systemFingerprint,
choices: [
{
index: 0,
delta: {
role: "assistant",
content: "",
},
logprobs: null,
finish_reason: null,
},
],
usage: null,
};
yield `data: ${JSON.stringify(firstChunk)}\n\n`;
let completionTokens = 0;
// Use tool call response chunks if available
if (testCase.toolCallResponseChunks &&
testCase.toolCallResponseChunks.length > 0) {
for (const chunk of testCase.toolCallResponseChunks) {
const streamChunk = {
id,
object: "chat.completion.chunk",
created: timestamp,
model: request.model,
system_fingerprint: systemFingerprint,
choices: [
{
index: 0,
delta: {
content: chunk,
},
logprobs: null,
finish_reason: null,
},
],
usage: null,
};
yield `data: ${JSON.stringify(streamChunk)}\n\n`;
completionTokens += (0, helpers_1.calculateTokens)(chunk);
}
}
else if (testCase.toolCallResponse) {
// Split the tool call response into chunks
const words = testCase.toolCallResponse.split(" ");
for (let i = 0; i < words.length; i++) {
const chunkText = words[i] + (i < words.length - 1 ? " " : "");
const streamChunk = {
id,
object: "chat.completion.chunk",
created: timestamp,
model: request.model,
system_fingerprint: systemFingerprint,
choices: [
{
index: 0,
delta: {
content: chunkText,
},
logprobs: null,
finish_reason: null,
},
],
usage: null,
};
yield `data: ${JSON.stringify(streamChunk)}\n\n`;
completionTokens += (0, helpers_1.calculateTokens)(chunkText);
}
}
// Calculate token usage for second phase
const promptTokens = (0, helpers_1.calculateTokens)(lastUserMessage.content || "") + 39; // Add some for tool call context
// Send last chunk with usage information
const lastChunk = {
id,
object: "chat.completion.chunk",
created: timestamp,
model: request.model,
system_fingerprint: systemFingerprint,
choices: [
{
index: 0,
delta: {
content: "",
},
logprobs: null,
finish_reason: "stop",
},
],
usage: {
prompt_tokens: promptTokens,
completion_tokens: completionTokens,
total_tokens: promptTokens + completionTokens,
prompt_tokens_details: {
cached_tokens: 768, // Based on real log
},
prompt_cache_hit_tokens: 768,
prompt_cache_miss_tokens: 99,
},
};
yield `data: ${JSON.stringify(lastChunk)}\n\n`;
// Send end marker
yield `data: [DONE]\n\n`;
}
/**
* Generate image
*/
function generateImage(request) {
const n = request.n || 1;
const timestamp = (0, helpers_1.getCurrentTimestamp)();
const size = request.size || "1024x1024";
// Choose different images based on model
const model = request.model || "gpt-4o-image";
let imageUrls = mockData_1.mockImageUrls;
// If gpt-4o-image model is specified, use higher quality placeholder images
if (model === "gpt-4o-image") {
imageUrls = [
`https://placehold.co/${size}/FF6B6B/FFFFFF?text=GPT-4O+Image+1`,
`https://placehold.co/${size}/4ECDC4/FFFFFF?text=GPT-4O+Image+2`,
`https://placehold.co/${size}/45B7D1/FFFFFF?text=GPT-4O+Image+3`,
`https://placehold.co/${size}/96CEB4/FFFFFF?text=GPT-4O+Image+4`,
`https://placehold.co/${size}/FFEAA7/000000?text=GPT-4O+Image+5`,
`https://placehold.co/${size}/DDA0DD/000000?text=GPT-4O+Image+6`,
`https://placehold.co/${size}/F0E68C/000000?text=GPT-4O+Image+7`,
`https://placehold.co/${size}/FFA07A/000000?text=GPT-4O+Image+8`,
];
}
const data = Array.from({ length: n }, () => {
const imageUrl = (0, helpers_1.randomChoice)(imageUrls);
if (request.response_format === "b64_json") {
// Simulate base64 encoded image (in actual applications this would be real base64)
return {
b64_json: "data:image/png;base64,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",
};
}
else {
return {
url: imageUrl,
};
}
});
return {
created: timestamp,
data,
};
}
//# sourceMappingURL=openaiService.js.map