{"version":3,"sources":["../../../src/runtimes/external-store/external-message-converter.tsx"],"sourcesContent":["\"use client\";\n\nimport { useMemo } from \"react\";\nimport { ThreadMessageConverter } from \"./ThreadMessageConverter\";\nimport {\n  getExternalStoreMessages,\n  symbolInnerMessage,\n} from \"./getExternalStoreMessage\";\nimport { fromThreadMessageLike, ThreadMessageLike } from \"./ThreadMessageLike\";\nimport { getAutoStatus, isAutoStatus } from \"./auto-status\";\nimport { ToolCallContentPart } from \"../../types\";\n\nexport namespace useExternalMessageConverter {\n  export type Message =\n    | (ThreadMessageLike & {\n        readonly convertConfig?: {\n          readonly joinStrategy?: \"concat-content\" | \"none\";\n        };\n      })\n    | {\n        role: \"tool\";\n        toolCallId: string;\n        toolName?: string | undefined;\n        result: any;\n      };\n\n  export type Callback<T> = (message: T) => Message | Message[];\n}\n\ntype CallbackResult<T> = {\n  input: T;\n  outputs: useExternalMessageConverter.Message[];\n};\n\ntype ChunkResult<T> = {\n  inputs: T[];\n  outputs: useExternalMessageConverter.Message[];\n};\n\ntype Mutable<T> = {\n  -readonly [P in keyof T]: T[P];\n};\n\nconst joinExternalMessages = (\n  messages: readonly useExternalMessageConverter.Message[],\n): ThreadMessageLike => {\n  const assistantMessage: Mutable<Omit<ThreadMessageLike, \"metadata\">> & {\n    content: Exclude<ThreadMessageLike[\"content\"][0], string>[];\n    metadata?: Mutable<ThreadMessageLike[\"metadata\"]>;\n  } = {\n    role: \"assistant\",\n    content: [],\n  };\n  for (const output of messages) {\n    if (output.role === \"tool\") {\n      const toolCallIdx = assistantMessage.content.findIndex(\n        (c) => c.type === \"tool-call\" && c.toolCallId === output.toolCallId,\n      );\n      if (toolCallIdx !== -1) {\n        const toolCall = assistantMessage.content[\n          toolCallIdx\n        ]! as ToolCallContentPart;\n        if (output.toolName) {\n          if (toolCall.toolName !== output.toolName)\n            throw new Error(\n              `Tool call name ${output.toolCallId} ${output.toolName} does not match existing tool call ${toolCall.toolName}`,\n            );\n        }\n        assistantMessage.content[toolCallIdx] = {\n          ...toolCall,\n          ...{\n            [symbolInnerMessage]: [\n              ...((toolCall as any)[symbolInnerMessage] ?? []),\n              output,\n            ],\n          },\n          result: output.result,\n        };\n      } else {\n        throw new Error(\n          `Tool call ${output.toolCallId} ${output.toolName} not found in assistant message`,\n        );\n      }\n    } else {\n      const role = output.role;\n      const content = (\n        typeof output.content === \"string\"\n          ? [{ type: \"text\" as const, text: output.content }]\n          : output.content\n      ).map((c) => ({\n        ...c,\n        ...{ [symbolInnerMessage]: [output] },\n      }));\n      switch (role) {\n        case \"system\":\n        case \"user\":\n          return {\n            ...output,\n            content,\n          };\n        case \"assistant\":\n          if (assistantMessage.content.length === 0) {\n            assistantMessage.id = output.id;\n            assistantMessage.createdAt ??= output.createdAt;\n            assistantMessage.status ??= output.status;\n\n            if (output.attachments) {\n              assistantMessage.attachments = [\n                ...(assistantMessage.attachments ?? []),\n                ...output.attachments,\n              ];\n            }\n\n            if (output.metadata) {\n              assistantMessage.metadata ??= {};\n              if (output.metadata.unstable_annotations) {\n                assistantMessage.metadata.unstable_annotations = [\n                  ...(assistantMessage.metadata.unstable_annotations ?? []),\n                  ...output.metadata.unstable_annotations,\n                ];\n              }\n              if (output.metadata.unstable_data) {\n                assistantMessage.metadata.unstable_data = [\n                  ...(assistantMessage.metadata.unstable_data ?? []),\n                  ...output.metadata.unstable_data,\n                ];\n              }\n              if (output.metadata.steps) {\n                assistantMessage.metadata.steps = [\n                  ...(assistantMessage.metadata.steps ?? []),\n                  ...output.metadata.steps,\n                ];\n              }\n              if (output.metadata.custom) {\n                assistantMessage.metadata.custom = {\n                  ...(assistantMessage.metadata.custom ?? {}),\n                  ...output.metadata.custom,\n                };\n              }\n            }\n            // TODO keep this in sync\n          }\n\n          assistantMessage.content.push(...content);\n          break;\n        default: {\n          const unsupportedRole: never = role;\n          throw new Error(`Unknown message role: ${unsupportedRole}`);\n        }\n      }\n    }\n  }\n  return assistantMessage;\n};\n\nconst chunkExternalMessages = <T,>(\n  callbackResults: CallbackResult<T>[],\n  joinStrategy?: \"concat-content\" | \"none\",\n) => {\n  const results: ChunkResult<T>[] = [];\n  let isAssistant = false;\n  let pendingNone = false; // true if the previous assistant message had joinStrategy \"none\"\n  let inputs: T[] = [];\n  let outputs: useExternalMessageConverter.Message[] = [];\n\n  const flush = () => {\n    if (outputs.length) {\n      results.push({\n        inputs,\n        outputs,\n      });\n    }\n    inputs = [];\n    outputs = [];\n    isAssistant = false;\n    pendingNone = false;\n  };\n\n  for (const callbackResult of callbackResults) {\n    for (const output of callbackResult.outputs) {\n      if (\n        (pendingNone && output.role !== \"tool\") ||\n        !isAssistant ||\n        output.role === \"user\" ||\n        output.role === \"system\"\n      ) {\n        flush();\n      }\n      isAssistant = output.role === \"assistant\" || output.role === \"tool\";\n\n      if (inputs.at(-1) !== callbackResult.input) {\n        inputs.push(callbackResult.input);\n      }\n      outputs.push(output);\n\n      if (\n        output.role === \"assistant\" &&\n        (output.convertConfig?.joinStrategy === \"none\" ||\n          joinStrategy === \"none\")\n      ) {\n        pendingNone = true;\n      }\n    }\n  }\n  flush();\n  return results;\n};\n\nexport const convertExternalMessages = <T extends WeakKey>(\n  messages: T[],\n  callback: useExternalMessageConverter.Callback<T>,\n  isRunning: boolean,\n) => {\n  const callbackResults: CallbackResult<T>[] = [];\n  for (const message of messages) {\n    const output = callback(message);\n    const outputs = Array.isArray(output) ? output : [output];\n    const result = { input: message, outputs };\n    callbackResults.push(result);\n  }\n\n  const chunks = chunkExternalMessages(callbackResults);\n\n  return chunks.map((message, idx) => {\n    const isLast = idx === chunks.length - 1;\n    const autoStatus = getAutoStatus(isLast, isRunning);\n    const newMessage = fromThreadMessageLike(\n      joinExternalMessages(message.outputs),\n      idx.toString(),\n      autoStatus,\n    );\n    (newMessage as any)[symbolInnerMessage] = message.inputs;\n    return newMessage;\n  });\n};\n\nexport const useExternalMessageConverter = <T extends WeakKey>({\n  callback,\n  messages,\n  isRunning,\n  joinStrategy,\n}: {\n  callback: useExternalMessageConverter.Callback<T>;\n  messages: T[];\n  isRunning: boolean;\n  joinStrategy?: \"concat-content\" | \"none\" | undefined;\n}) => {\n  const state = useMemo(\n    () => ({\n      callback,\n      callbackCache: new WeakMap<T, CallbackResult<T>>(),\n      chunkCache: new WeakMap<\n        useExternalMessageConverter.Message,\n        ChunkResult<T>\n      >(),\n      converterCache: new ThreadMessageConverter(),\n    }),\n    [callback],\n  );\n\n  return useMemo(() => {\n    const callbackResults: CallbackResult<T>[] = [];\n    for (const message of messages) {\n      let result = state.callbackCache.get(message);\n      if (!result) {\n        const output = state.callback(message);\n        const outputs = Array.isArray(output) ? output : [output];\n        result = { input: message, outputs };\n        state.callbackCache.set(message, result);\n      }\n      callbackResults.push(result);\n    }\n\n    const chunks = chunkExternalMessages(callbackResults, joinStrategy).map(\n      (m) => {\n        const key = m.outputs[0];\n        if (!key) return m;\n\n        const cached = state.chunkCache.get(key);\n        if (cached && shallowArrayEqual(cached.outputs, m.outputs))\n          return cached;\n        state.chunkCache.set(key, m);\n        return m;\n      },\n    );\n\n    const threadMessages = state.converterCache.convertMessages(\n      chunks,\n      (cache, message, idx) => {\n        const isLast = idx === chunks.length - 1;\n        const autoStatus = getAutoStatus(isLast, isRunning);\n\n        if (\n          cache &&\n          (cache.role !== \"assistant\" ||\n            !isAutoStatus(cache.status) ||\n            cache.status === autoStatus)\n        ) {\n          const inputs = getExternalStoreMessages<T>(cache);\n          if (shallowArrayEqual(inputs, message.inputs)) {\n            return cache;\n          }\n        }\n\n        const newMessage = fromThreadMessageLike(\n          joinExternalMessages(message.outputs),\n          idx.toString(),\n          autoStatus,\n        );\n        (newMessage as any)[symbolInnerMessage] = message.inputs;\n        return newMessage;\n      },\n    );\n\n    (threadMessages as unknown as { [symbolInnerMessage]: T[] })[\n      symbolInnerMessage\n    ] = messages;\n\n    return threadMessages;\n  }, [state, messages, isRunning, joinStrategy]);\n};\n\nconst shallowArrayEqual = (a: unknown[], b: unknown[]) => {\n  if (a.length !== b.length) return false;\n  for (let i = 0; i < a.length; i++) {\n    if (a[i] !== b[i]) return false;\n  }\n  return true;\n};\n"],"mappings":"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","names":[]}