in lib/ChatCompletionStream.ts [690:815]
function finalizeChatCompletion<ParsedT>(
snapshot: ChatCompletionSnapshot,
params: ChatCompletionCreateParams | null,
): ParsedChatCompletion<ParsedT> {
const { id, choices, created, model, system_fingerprint, ...rest } = snapshot;
const completion: ChatCompletion = {
...rest,
id,
choices: choices.map(
(
{ message, finish_reason, index, logprobs, ...choiceRest },
): ChatCompletion.Choice => {
if (!finish_reason) {
throw new OpenAIError(`missing finish_reason for choice ${index}`);
}
const { content = null, function_call, tool_calls, ...messageRest } =
message;
const role = message.role as "assistant"; // this is what we expect; in theory it could be different which would make our types a slight lie but would be fine.
if (!role) {
throw new OpenAIError(`missing role for choice ${index}`);
}
if (function_call) {
const { arguments: args, name } = function_call;
if (args == null) {
throw new OpenAIError(
`missing function_call.arguments for choice ${index}`,
);
}
if (!name) {
throw new OpenAIError(
`missing function_call.name for choice ${index}`,
);
}
return {
...choiceRest,
message: {
content,
function_call: { arguments: args, name },
role,
refusal: message.refusal ?? null,
},
finish_reason,
index,
logprobs,
};
}
if (tool_calls) {
return {
...choiceRest,
index,
finish_reason,
logprobs,
message: {
...messageRest,
role,
content,
refusal: message.refusal ?? null,
tool_calls: tool_calls.map((tool_call, i) => {
const { function: fn, type, id, ...toolRest } = tool_call;
const { arguments: args, name, ...fnRest } = fn || {};
if (id == null) {
throw new OpenAIError(
`missing choices[${index}].tool_calls[${i}].id\n${
str(snapshot)
}`,
);
}
if (type == null) {
throw new OpenAIError(
`missing choices[${index}].tool_calls[${i}].type\n${
str(snapshot)
}`,
);
}
if (name == null) {
throw new OpenAIError(
`missing choices[${index}].tool_calls[${i}].function.name\n${
str(snapshot)
}`,
);
}
if (args == null) {
throw new OpenAIError(
`missing choices[${index}].tool_calls[${i}].function.arguments\n${
str(snapshot)
}`,
);
}
return {
...toolRest,
id,
type,
function: { ...fnRest, name, arguments: args },
};
}),
},
};
}
return {
...choiceRest,
message: {
...messageRest,
content,
role,
refusal: message.refusal ?? null,
},
finish_reason,
index,
logprobs,
};
},
),
created,
model,
object: "chat.completion",
...(system_fingerprint ? { system_fingerprint } : {}),
};
return maybeParseChatCompletion(completion, params);
}