export function formatResponseBody()

in src/formatters.ts [23:84]


export function formatResponseBody({
  res,
  allResponseChunks,
  cliOptions,
}: {
  res: express.Response;
  allResponseChunks: string;
  cliOptions: CliOptions;
}) {
  if (cliOptions.raw) {
    return allResponseChunks;
  }

  const isStreamedResponse =
    res.getHeader('content-type') === 'text/event-stream' ||
    res.getHeader('transfer-encoding') === 'chunked';
  if (!isStreamedResponse) {
    try {
      return JSON.stringify(JSON.parse(allResponseChunks), null, 2);
    } catch (e) {
      return allResponseChunks;
    }
  }

  const lines = allResponseChunks
    .split(/\r?\n/) // Handle both \n and \r\n
    .map((line) => line.trim());

  const hasSSEChunks = lines.some((line) => line.startsWith('data:'));

  console.log(`Chunks: ${allResponseChunks.length}`);
  console.log(`Lines: ${lines.length}`);
  console.log(`Server-sent events (SSE): ${hasSSEChunks.valueOf()}`);
  console.log(`-----\n`);

  if (!hasSSEChunks) {
    return lines
      .map((line) => {
        try {
          const parsedLine = JSON.parse(line);
          return parsedLine.message.content;
        } catch (e) {
          return line;
        }
      })
      .join('');
  }

  const parsedSSEChunks = lines
    .filter((line) => line.startsWith('data:') && line !== 'data: [DONE]') // Filter out non-data and [DONE]
    .map((line) => JSON.parse(line.slice(5).trim()));

  const isOpenAIChunk = parsedSSEChunks.some(
    (chunk) => chunk.object === 'chat.completion.chunk' && chunk.choices,
  );
  if (!isOpenAIChunk) {
    return JSON.stringify(parsedSSEChunks, null, 2);
  }

  const mergedMessage = mergeOpenAIChunks(parsedSSEChunks);
  return JSON.stringify(mergedMessage, null, 2);
}