{"version":3,"sources":["../../src/openai/streaming.ts","../../src/openai/mergeChunks.ts"],"sourcesContent":["import type { ChatCompletion, ChatCompletionChunk } from \"openai/resources/chat\";\nimport { Stream } from \"openai/streaming\";\n\nimport { OpenPipeMeta } from \"../shared\";\nimport mergeChunks from \"./mergeChunks\";\n\nexport class WrappedStream extends Stream<ChatCompletionChunk> {\n  openpipe: OpenPipeMeta;\n\n  private resolveReportingFinished: () => void = () => {};\n  private report: (response: unknown) => Promise<void>;\n\n  constructor(stream: Stream<ChatCompletionChunk>, report: (response: unknown) => Promise<void>) {\n    // @ts-expect-error - This is a private property but we need to access it\n    super(stream.iterator, stream.controller);\n    this.report = report;\n\n    const reportingFinished = new Promise<void>((resolve) => {\n      this.resolveReportingFinished = resolve;\n    });\n\n    this.openpipe = {\n      reportingFinished,\n    };\n  }\n\n  async *[Symbol.asyncIterator](): AsyncIterator<ChatCompletionChunk, any, undefined> {\n    const iterator = super[Symbol.asyncIterator]();\n\n    let combinedResponse: ChatCompletion | null = null;\n    while (true) {\n      const result = await iterator.next();\n      if (result.done) break;\n      combinedResponse = mergeChunks(combinedResponse, result.value);\n\n      yield result.value;\n    }\n\n    await this.report(combinedResponse);\n\n    // Resolve the promise here\n    this.resolveReportingFinished();\n  }\n}\n","import type { ChatCompletion, ChatCompletionChunk } from \"openai/resources/chat\";\nimport { CompletionUsage } from \"openai/resources/completions\";\n\nconst omit = <T extends Record<string, unknown>, K extends keyof T>(\n  obj: T,\n  ...keys: K[]\n): Omit<T, K> => {\n  const ret = { ...obj };\n  for (const key of keys) {\n    delete ret[key];\n  }\n  return ret;\n};\n\nexport default function mergeChunks(\n  base: ChatCompletion | null,\n  chunk: ChatCompletionChunk,\n): ChatCompletion {\n  if (base === null) {\n    return mergeChunks(\n      { ...chunk, object: \"chat.completion\", choices: [], usage: chunk.usage ?? undefined },\n      // Prevent function call and tool call arguments from being double-merged\n      {\n        ...chunk,\n        choices: chunk.choices.map((c) => ({\n          ...c,\n          delta: {\n            ...c.delta,\n            function_call: c.delta.function_call\n              ? {\n                  ...c.delta.function_call,\n                }\n              : undefined,\n            tool_calls: c.delta.tool_calls?.map((tc) => ({\n              ...tc,\n              function: {\n                ...tc.function,\n              },\n            })),\n          },\n        })),\n      },\n    );\n  }\n\n  const choices = [...base.choices];\n  for (const choice of chunk.choices) {\n    const baseChoice = choices.find((c) => c.index === choice.index);\n    if (baseChoice) {\n      baseChoice.finish_reason = choice.finish_reason ?? baseChoice.finish_reason;\n      baseChoice.message = { ...baseChoice.message, refusal: null };\n\n      if (choice.delta?.content)\n        baseChoice.message.content =\n          (baseChoice.message.content ?? \"\") + (choice.delta.content ?? \"\");\n      if (choice.delta?.function_call) {\n        const fnCall = baseChoice.message.function_call ?? {\n          name: \"\",\n          arguments: \"\",\n        };\n        fnCall.name = fnCall.name + (choice.delta.function_call.name ?? \"\");\n        fnCall.arguments = fnCall.arguments + (choice.delta.function_call.arguments ?? \"\");\n      }\n      if (choice.delta?.tool_calls) {\n        const toolCalls = baseChoice.message.tool_calls ?? [];\n        const toolCallDelta = { ...choice.delta.tool_calls[0] };\n        if (toolCallDelta?.function?.name) {\n          toolCalls.push({\n            id: toolCallDelta.id as string,\n            type: \"function\",\n            function: {\n              name: toolCallDelta.function.name ?? \"\",\n              arguments: toolCallDelta.function.arguments ?? \"\",\n            },\n          });\n        } else if (toolCalls[toolCalls.length - 1] && toolCallDelta) {\n          toolCalls[toolCalls.length - 1]!.function.arguments +=\n            toolCallDelta.function?.arguments ?? \"\";\n        }\n        baseChoice.message.tool_calls = toolCalls;\n      }\n    } else {\n      // @ts-expect-error the types are correctly telling us that finish_reason\n      // could be null, but don't want to fix it right now.\n      choices.push({ ...omit(choice, \"delta\"), message: { role: \"assistant\", ...choice.delta } });\n    }\n  }\n\n  const merged: ChatCompletion = {\n    ...base,\n    choices,\n    usage: chunk.usage ?? undefined,\n  };\n\n  return merged;\n}\n"],"mappings":"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","names":[]}