function finalizeChatCompletion()

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);
}