{"version":3,"file":"index.mjs","names":["extractTextContent"],"sources":["../src/store/ArtifactContext.ts","../src/hooks/useActiveArtifact.ts","../src/hooks/useArtifact.ts","../src/hooks/useArtifactPortalTarget.ts","../src/hooks/useMessage.tsx","../src/store/ChatContext.ts","../src/hooks/useThread.ts","../src/store/createArtifactStore.ts","../src/types/messageFormat.ts","../src/stream/adapters/ag-ui.ts","../src/stream/adapters/langgraph.ts","../src/stream/adapters/openai-completions.ts","../src/stream/adapters/openai-readable-stream.ts","../src/stream/adapters/openai-responses.ts","../src/stream/processStreamedMessage.ts","../src/store/createChatStore.ts","../src/store/ChatProvider.tsx","../src/stream/formats/langgraph-message-format.ts","../src/stream/formats/openai-conversation-message-format.ts","../src/stream/formats/openai-message-format.ts"],"sourcesContent":["import { createContext, useContext } from \"react\";\nimport type { StoreApi } from \"zustand\";\nimport type { ArtifactStore } from \"./artifactTypes\";\n\n/** @internal React context holding the artifact Zustand store. Provided by `ChatProvider`. */\nexport const ArtifactContext = createContext<StoreApi<ArtifactStore> | null>(null);\n\n/**\n * Returns the raw artifact Zustand store for advanced use cases.\n *\n * Prefer {@link useArtifact} or {@link useActiveArtifact} for most cases —\n * this hook is an escape hatch when you need direct store access.\n *\n * @category Hooks\n * @returns The Zustand `StoreApi<ArtifactStore>` instance\n * @throws Error if called outside a `<ChatProvider>`\n */\nexport const useArtifactStore = (): StoreApi<ArtifactStore> => {\n  const store = useContext(ArtifactContext);\n  if (!store) {\n    throw new Error(\"useArtifactStore must be used within a <ChatProvider>\");\n  }\n  return store;\n};\n","import { useCallback } from \"react\";\nimport { useStore } from \"zustand\";\nimport { useArtifactStore } from \"../store/ArtifactContext\";\n\n/**\n * Return type for {@link useActiveArtifact}.\n *\n * @category Hooks\n */\ntype UseActiveArtifactReturn = {\n  /** Whether any artifact is currently active (panel is open). */\n  isArtifactActive: boolean;\n  /** The ID of the currently active artifact, or `null` if none. */\n  activeArtifactId: string | null;\n  /** Closes whichever artifact is currently active. No-op if none is active. */\n  closeArtifact: () => void;\n};\n\n/**\n * Returns global artifact activation state — whether *any* artifact is open,\n * and a close action that dismisses it.\n *\n * Use this in layout components that react to artifact presence (resizing panels,\n * showing overlays) without needing to know *which* artifact is active.\n * For per-artifact state and actions, use {@link useArtifact} instead.\n *\n * Must be called within a `<ChatProvider>`.\n *\n * @category Hooks\n * @returns {@link UseActiveArtifactReturn}\n */\nexport function useActiveArtifact(): UseActiveArtifactReturn {\n  const store = useArtifactStore();\n\n  const activeArtifactId = useStore(store, (s) => s.activeArtifactId);\n  const isArtifactActive = activeArtifactId !== null;\n\n  const closeArtifact = useCallback(() => {\n    const state = store.getState();\n    if (state.activeArtifactId) {\n      state.closeArtifact(state.activeArtifactId);\n    }\n  }, [store]);\n\n  return { isArtifactActive, activeArtifactId, closeArtifact };\n}\n","import { useCallback } from \"react\";\nimport { useStore } from \"zustand\";\nimport { useArtifactStore } from \"../store/ArtifactContext\";\n\n/**\n * Return type for {@link useArtifact}.\n *\n * @category Hooks\n */\ntype UseArtifactReturn = {\n  /** Whether this artifact is the currently active (visible) one. */\n  isActive: boolean;\n  /** Activates this artifact. */\n  open: () => void;\n  /** Deactivates this artifact. */\n  close: () => void;\n  /** Toggles this artifact: opens if closed, closes if open. */\n  toggle: () => void;\n};\n\n/**\n * Binds a component to a specific artifact by ID, providing activation state\n * and actions (open, close, toggle).\n *\n * Multiple `useArtifact` hooks with different IDs can coexist —\n * only one artifact is active at a time.\n *\n * Must be called within a `<ChatProvider>`.\n *\n * @category Hooks\n * @param artifactId - Unique identifier for the artifact\n * @returns {@link UseArtifactReturn}\n *\n * @example\n * ```tsx\n * function PreviewButton({ id }: { id: string }) {\n *   const { isActive, toggle } = useArtifact(id);\n *   return (\n *     <button onClick={() => toggle()}>\n *       {isActive ? \"Hide\" : \"Show\"} Preview\n *     </button>\n *   );\n * }\n * ```\n */\nexport function useArtifact(artifactId: string): UseArtifactReturn {\n  const store = useArtifactStore();\n\n  const isActive = useStore(store, (s) => s.activeArtifactId === artifactId);\n\n  const open = useCallback(() => {\n    store.getState().openArtifact(artifactId);\n  }, [store, artifactId]);\n\n  const close = useCallback(() => {\n    store.getState().closeArtifact(artifactId);\n  }, [store, artifactId]);\n\n  const toggle = useCallback(() => {\n    const state = store.getState();\n    if (state.activeArtifactId === artifactId) {\n      state.closeArtifact(artifactId);\n    } else {\n      state.openArtifact(artifactId);\n    }\n  }, [store, artifactId]);\n\n  return { isActive, open, close, toggle };\n}\n","import { useCallback } from \"react\";\nimport { useStore } from \"zustand\";\nimport { useArtifactStore } from \"../store/ArtifactContext\";\n\n/**\n * Provides access to the artifact portal target DOM node.\n *\n * This hook serves two roles:\n * - **Registering a portal target:** Call `setNode` from a ref callback to\n *   designate a DOM element as the render target for artifact content.\n *   Only one target should be registered at a time.\n * - **Reading the portal target:** Read `node` to get the current target\n *   element for use with `createPortal()`.\n *\n * Must be called within a `<ChatProvider>`.\n *\n * @category Hooks\n * @returns `{ setNode, node }` — setter for registration, getter for portal rendering\n *\n * @example\n * ```tsx\n * // Registering a portal target\n * function MyPortalTarget() {\n *   const { setNode } = useArtifactPortalTarget();\n *   return <div ref={setNode} />;\n * }\n *\n * // Building a custom artifact panel\n * function MyArtifactPanel({ artifactId, children }) {\n *   const { isActive } = useArtifact(artifactId);\n *   const { node } = useArtifactPortalTarget();\n *   if (!isActive || !node) return null;\n *   return createPortal(<div>{children}</div>, node);\n * }\n * ```\n */\nexport function useArtifactPortalTarget() {\n  const store = useArtifactStore();\n  const node = useStore(store, (s) => s._artifactPanelNode);\n\n  const setNode = useCallback(\n    (node: HTMLElement | null) => {\n      store.getState()._setArtifactPanelNode(node);\n    },\n    [store],\n  );\n\n  return { setNode, node };\n}\n","import { createContext, useContext } from \"react\";\nimport { useShallow } from \"zustand/react/shallow\";\nimport { Message } from \"../types\";\n\n/**\n * @category Contexts\n */\nexport const MessageContext = createContext<{ message: Message } | null>(null);\n\n/**\n * @category Hooks\n * @returns The current message. See {@link Message} for more information.\n */\nexport const useMessage = () => {\n  const context = useContext(MessageContext);\n  if (!context) {\n    throw new Error(\"useMessage must be used within a MessageProvider\");\n  }\n  return context;\n};\n\n/**\n * @category Components\n */\nexport const MessageProvider = ({\n  message,\n  children,\n}: {\n  message: Message;\n  children: React.ReactNode;\n}) => {\n  const ctxValue = useShallow((_s: void) => ({ message }))();\n\n  return <MessageContext.Provider value={ctxValue}>{children}</MessageContext.Provider>;\n};\n","import { createContext, useContext } from \"react\";\nimport type { StoreApi } from \"zustand\";\nimport type { ChatStore } from \"./types\";\n\nexport const ChatContext = createContext<StoreApi<ChatStore> | null>(null);\n\nexport const useChatStore = (): StoreApi<ChatStore> => {\n  const store = useContext(ChatContext);\n  if (!store) {\n    throw new Error(\"useChatStore must be used within a <ChatProvider>\");\n  }\n  return store;\n};\n","import { useStore } from \"zustand\";\nimport { useShallow } from \"zustand/react/shallow\";\nimport { useChatStore } from \"../store/ChatContext\";\nimport type {\n  ChatStore,\n  ThreadActions,\n  ThreadListActions,\n  ThreadListState,\n  ThreadState,\n} from \"../store/types\";\n\ntype ThreadSlice = ThreadState & ThreadActions;\ntype ThreadListSlice = ThreadListState & ThreadListActions;\n\nconst threadSelector = (s: ChatStore): ThreadSlice => ({\n  messages: s.messages,\n  isRunning: s.isRunning,\n  isLoadingMessages: s.isLoadingMessages,\n  threadError: s.threadError,\n  processMessage: s.processMessage,\n  appendMessages: s.appendMessages,\n  updateMessage: s.updateMessage,\n  setMessages: s.setMessages,\n  deleteMessage: s.deleteMessage,\n  cancelMessage: s.cancelMessage,\n});\n\nconst threadListSelector = (s: ChatStore): ThreadListSlice => ({\n  threads: s.threads,\n  isLoadingThreads: s.isLoadingThreads,\n  threadListError: s.threadListError,\n  selectedThreadId: s.selectedThreadId,\n  hasMoreThreads: s.hasMoreThreads,\n  loadThreads: s.loadThreads,\n  loadMoreThreads: s.loadMoreThreads,\n  switchToNewThread: s.switchToNewThread,\n  createThread: s.createThread,\n  selectThread: s.selectThread,\n  updateThread: s.updateThread,\n  deleteThread: s.deleteThread,\n});\n\nexport function useThread(): ThreadSlice;\nexport function useThread<T>(selector: (state: ThreadSlice) => T): T;\nexport function useThread<T>(selector?: (state: ThreadSlice) => T) {\n  const store = useChatStore();\n  if (selector) {\n    return useStore(store, (s) => selector(threadSelector(s)));\n  }\n  return useStore(store, useShallow(threadSelector));\n}\n\nexport function useThreadList(): ThreadListSlice;\nexport function useThreadList<T>(selector: (state: ThreadListSlice) => T): T;\nexport function useThreadList<T>(selector?: (state: ThreadListSlice) => T) {\n  const store = useChatStore();\n  if (selector) {\n    return useStore(store, (s) => selector(threadListSelector(s)));\n  }\n  return useStore(store, useShallow(threadListSelector));\n}\n","import { createStore } from \"zustand\";\nimport { subscribeWithSelector } from \"zustand/middleware\";\nimport type { ArtifactStore } from \"./artifactTypes\";\n\n/**\n * Creates a Zustand store managing artifact state.\n * Instantiated once by `ChatProvider` — consumers should not call this directly.\n *\n * @internal\n */\nexport const createArtifactStore = () => {\n  return createStore<ArtifactStore>()(\n    subscribeWithSelector((set, get) => ({\n      activeArtifactId: null,\n\n      openArtifact: (id) => {\n        set({ activeArtifactId: id });\n      },\n\n      closeArtifact: (id) => {\n        if (get().activeArtifactId === id) {\n          set({ activeArtifactId: null });\n        }\n      },\n\n      resetArtifacts: () => {\n        set({ activeArtifactId: null });\n      },\n\n      _artifactPanelNode: null,\n      _setArtifactPanelNode: (node) => {\n        if (\n          process.env[\"NODE_ENV\"] !== \"production\" &&\n          node &&\n          get()._artifactPanelNode &&\n          get()._artifactPanelNode !== node\n        ) {\n          console.warn(\n            \"[OpenUI] Multiple ArtifactPortalTarget instances detected. \" +\n              \"Only one should be mounted at a time.\",\n          );\n        }\n        set({ _artifactPanelNode: node });\n      },\n    })),\n  );\n};\n","import type { Message } from \"./message\";\n\n/**\n * Converts messages between AG-UI format (used internally) and the\n * format your backend / storage layer expects.\n *\n * Both methods operate on **arrays** so that formats where a single\n * AG-UI message maps to multiple backend items (e.g. OpenAI Responses\n * API) work seamlessly alongside 1-to-1 formats (e.g. Completions).\n *\n * @example\n * // Identity (default) — no conversion\n * const identity: MessageFormat = {\n *   toApi: (messages) => messages,\n *   fromApi: (data) => data as Message[],\n * };\n */\nexport interface MessageFormat {\n  /** Convert AG-UI messages to the format your backend expects (outbound). */\n  toApi(messages: Message[]): unknown;\n  /** Convert messages from your backend/storage format to AG-UI (inbound). */\n  fromApi(data: unknown): Message[];\n}\n\n/**\n * Default identity message format — no conversion.\n * Messages are sent and received as-is in AG-UI format.\n */\nexport const identityMessageFormat: MessageFormat = {\n  toApi: (messages) => messages,\n  fromApi: (data) => data as Message[],\n};\n","import { AGUIEvent, StreamProtocolAdapter } from \"../../types\";\n\nexport const agUIAdapter = (): StreamProtocolAdapter => ({\n  async *parse(response: Response): AsyncIterable<AGUIEvent> {\n    const reader = response.body?.getReader();\n    if (!reader) throw new Error(\"No response body\");\n\n    const decoder = new TextDecoder();\n\n    while (true) {\n      const { done, value } = await reader.read();\n      if (done) break;\n\n      const chunk = decoder.decode(value, { stream: true });\n      const lines = chunk.split(\"\\n\");\n\n      for (const line of lines) {\n        if (!line.startsWith(\"data: \")) continue;\n        const data = line.slice(6).trim();\n        if (!data || data === \"[DONE]\") continue;\n\n        try {\n          const event = JSON.parse(data);\n          yield event as AGUIEvent;\n        } catch (e) {\n          console.error(\"Failed to parse SSE event\", e);\n        }\n      }\n    }\n  },\n});\n","import { AGUIEvent, EventType, StreamProtocolAdapter } from \"../../types\";\n\n/**\n * Represents a LangGraph AI message (or chunk) as received in the\n * `messages` stream mode.\n */\ninterface LangGraphAIMessage {\n  id?: string;\n  type: \"ai\" | \"AIMessageChunk\" | \"AIMessage\";\n  content: string | Array<{ type: string; text?: string }>;\n  tool_calls?: Array<{\n    id: string;\n    name: string;\n    args: Record<string, unknown>;\n  }>;\n  tool_call_chunks?: Array<{\n    id?: string;\n    name?: string;\n    args?: string;\n    index?: number;\n  }>;\n}\n\n/**\n * Metadata attached to each message tuple in the `messages` stream mode.\n */\ninterface LangGraphMessageMetadata {\n  langgraph_node?: string;\n  langgraph_step?: number;\n  langgraph_triggers?: string[];\n  langgraph_checkpoint_ns?: string;\n  tags?: string[];\n  ls_model_name?: string;\n}\n\n/**\n * Options for the LangGraph adapter.\n */\nexport interface LangGraphAdapterOptions {\n  /**\n   * Called when a LangGraph interrupt is encountered in an `updates` event.\n   * The interrupt payload is the value of the `__interrupt__` key.\n   */\n  onInterrupt?: (interrupt: unknown) => void;\n}\n\n/**\n * Adapter for LangGraph streaming responses.\n *\n * LangGraph uses named SSE events (`event: <type>\\ndata: <json>\\n\\n`)\n * rather than the `data:`-only format used by OpenAI. The adapter handles\n * the `messages`, `metadata`, `updates`, and `error` event types and maps\n * them to AG-UI events.\n *\n * Usage:\n * ```tsx\n * <ChatProvider\n *   apiUrl=\"/api/langgraph\"\n *   streamProtocol={langGraphAdapter()}\n * />\n * ```\n */\nexport const langGraphAdapter = (options?: LangGraphAdapterOptions): StreamProtocolAdapter => ({\n  async *parse(response: Response): AsyncIterable<AGUIEvent> {\n    const reader = response.body?.getReader();\n    if (!reader) throw new Error(\"No response body\");\n\n    const decoder = new TextDecoder();\n    const messageId = crypto.randomUUID();\n    const toolCallIds: Record<number, string> = {};\n    let messageStarted = false;\n    let buffer = \"\";\n\n    while (true) {\n      const { done, value } = await reader.read();\n      if (done) break;\n\n      buffer += decoder.decode(value, { stream: true });\n\n      // SSE events are separated by double newlines.\n      // Split on \\n\\n to get complete event blocks, keeping the last\n      // (possibly incomplete) block in the buffer.\n      const blocks = buffer.split(\"\\n\\n\");\n      buffer = blocks.pop() ?? \"\";\n\n      for (const block of blocks) {\n        const trimmed = block.trim();\n        if (!trimmed) continue;\n\n        const { event, data } = parseSSEBlock(trimmed);\n        if (!data) continue;\n\n        let parsed: unknown;\n        try {\n          parsed = JSON.parse(data);\n        } catch (e) {\n          console.error(\"Failed to parse LangGraph SSE data\", e);\n          continue;\n        }\n\n        switch (event) {\n          case \"metadata\": {\n            // Metadata event signals the run has started.\n            // Payload: { run_id: string, thread_id: string }\n            // We don't emit RUN_STARTED because processStreamedMessage\n            // doesn't handle it — it's informational only.\n            break;\n          }\n\n          case \"messages\": {\n            // Payload is a tuple: [message_chunk, metadata]\n            // or just a message object depending on the stream version.\n            const tuple = parsed as\n              | [LangGraphAIMessage, LangGraphMessageMetadata]\n              | LangGraphAIMessage;\n\n            const msg: LangGraphAIMessage = Array.isArray(tuple) ? tuple[0] : tuple;\n\n            // Only handle AI messages\n            if (msg.type !== \"ai\" && msg.type !== \"AIMessageChunk\" && msg.type !== \"AIMessage\") {\n              break;\n            }\n\n            // Emit TEXT_MESSAGE_START on first AI message chunk\n            if (!messageStarted) {\n              yield {\n                type: EventType.TEXT_MESSAGE_START,\n                messageId,\n                role: \"assistant\",\n              };\n              messageStarted = true;\n            }\n\n            // Handle text content\n            const textContent = extractTextContent(msg.content);\n            if (textContent) {\n              yield {\n                type: EventType.TEXT_MESSAGE_CONTENT,\n                messageId,\n                delta: textContent,\n              };\n            }\n\n            // Handle streaming tool call chunks (partial arguments)\n            if (msg.tool_call_chunks) {\n              for (const chunk of msg.tool_call_chunks) {\n                const index = chunk.index ?? 0;\n\n                if (chunk.id && !toolCallIds[index]) {\n                  toolCallIds[index] = chunk.id;\n                  yield {\n                    type: EventType.TOOL_CALL_START,\n                    toolCallId: chunk.id,\n                    toolCallName: chunk.name || \"\",\n                  };\n                }\n\n                if (chunk.args) {\n                  const toolCallId = toolCallIds[index];\n                  if (toolCallId) {\n                    yield {\n                      type: EventType.TOOL_CALL_ARGS,\n                      toolCallId,\n                      delta: chunk.args,\n                    };\n                  }\n                }\n              }\n            }\n\n            // Handle complete tool calls (non-streaming, full args at once)\n            if (msg.tool_calls && msg.tool_calls.length > 0) {\n              for (let i = 0; i < msg.tool_calls.length; i++) {\n                const tc = msg.tool_calls[i];\n                if (!tc) continue;\n\n                const toolCallId = tc.id || crypto.randomUUID();\n\n                // Only emit if we haven't already started this tool call\n                // via tool_call_chunks\n                if (!Object.values(toolCallIds).includes(toolCallId)) {\n                  yield {\n                    type: EventType.TOOL_CALL_START,\n                    toolCallId,\n                    toolCallName: tc.name,\n                  };\n\n                  const argsStr = typeof tc.args === \"string\" ? tc.args : JSON.stringify(tc.args);\n                  yield {\n                    type: EventType.TOOL_CALL_ARGS,\n                    toolCallId,\n                    delta: argsStr,\n                  };\n\n                  yield {\n                    type: EventType.TOOL_CALL_END,\n                    toolCallId,\n                  };\n                }\n              }\n            }\n\n            break;\n          }\n\n          case \"updates\": {\n            // Payload: { [node_name]: node_output }\n            // Check for interrupts\n            const updates = parsed as Record<string, unknown>;\n            if (\"__interrupt__\" in updates && options?.onInterrupt) {\n              options.onInterrupt(updates[\"__interrupt__\"]);\n            }\n            break;\n          }\n\n          case \"error\": {\n            // Payload: { error: string, message: string }\n            const err = parsed as { error?: string; message?: string };\n            yield {\n              type: EventType.RUN_ERROR,\n              message: err.message || err.error || \"Unknown error\",\n              code: err.error ?? undefined,\n            };\n            break;\n          }\n\n          case \"end\": {\n            // Stream has ended — close out any open message/tool calls.\n            if (messageStarted) {\n              // End any open streaming tool calls\n              for (const toolCallId of Object.values(toolCallIds)) {\n                yield {\n                  type: EventType.TOOL_CALL_END,\n                  toolCallId,\n                };\n              }\n\n              yield {\n                type: EventType.TEXT_MESSAGE_END,\n                messageId,\n              };\n              messageStarted = false; // Prevent duplicate end in fallback\n            }\n            break;\n          }\n\n          // Intentionally unhandled: values, debug, tasks, checkpoints, custom\n          default:\n            break;\n        }\n      }\n    }\n\n    // If stream ended without an explicit \"end\" event, close out.\n    if (messageStarted) {\n      for (const toolCallId of Object.values(toolCallIds)) {\n        yield {\n          type: EventType.TOOL_CALL_END,\n          toolCallId,\n        };\n      }\n      yield {\n        type: EventType.TEXT_MESSAGE_END,\n        messageId,\n      };\n    }\n  },\n});\n\n/**\n * Parse an SSE block into its event name and data payload.\n *\n * LangGraph SSE format:\n * ```\n * event: messages\n * data: [{\"content\": \"Hello\", ...}, {\"langgraph_node\": \"agent\"}]\n * ```\n */\nfunction parseSSEBlock(block: string): { event: string; data: string } {\n  let event = \"\";\n  const dataLines: string[] = [];\n\n  for (const line of block.split(\"\\n\")) {\n    if (line.startsWith(\"event:\")) {\n      event = line.slice(6).trim();\n    } else if (line.startsWith(\"data:\")) {\n      dataLines.push(line.slice(5).trim());\n    }\n    // Ignore id:, retry:, and comment lines\n  }\n\n  return { event, data: dataLines.join(\"\\n\") };\n}\n\n/**\n * Extract text content from a LangGraph message content field.\n * Content can be a plain string or an array of typed content blocks.\n */\nfunction extractTextContent(content: string | Array<{ type: string; text?: string }>): string {\n  if (typeof content === \"string\") return content;\n\n  return content\n    .filter((block) => block.type === \"text\" && block.text)\n    .map((block) => block.text!)\n    .join(\"\");\n}\n","import type { ChatCompletionChunk } from \"openai/resources/chat/completions\";\nimport { AGUIEvent, EventType, StreamProtocolAdapter } from \"../../types\";\n\nexport const openAIAdapter = (): StreamProtocolAdapter => ({\n  async *parse(response: Response): AsyncIterable<AGUIEvent> {\n    const reader = response.body?.getReader();\n    if (!reader) throw new Error(\"No response body\");\n\n    const decoder = new TextDecoder();\n    const messageId = crypto.randomUUID();\n    const toolCallIds: Record<number, string> = {};\n    let messageStarted = false;\n\n    while (true) {\n      const { done, value } = await reader.read();\n      if (done) break;\n\n      const chunk = decoder.decode(value, { stream: true });\n      const lines = chunk.split(\"\\n\");\n\n      for (const line of lines) {\n        if (!line.startsWith(\"data: \")) continue;\n        const data = line.slice(6).trim();\n        if (!data || data === \"[DONE]\") continue;\n\n        try {\n          const json = JSON.parse(data) as ChatCompletionChunk;\n          const choice = json.choices?.[0];\n          const delta = choice?.delta;\n\n          if (!delta) continue;\n\n          // Emit TEXT_MESSAGE_START on first meaningful delta\n          if (!messageStarted && (delta.content || delta.role)) {\n            yield {\n              type: EventType.TEXT_MESSAGE_START,\n              messageId,\n              role: \"assistant\",\n            };\n            messageStarted = true;\n          }\n\n          if (delta.content) {\n            yield {\n              type: EventType.TEXT_MESSAGE_CONTENT,\n              messageId,\n              delta: delta.content,\n            };\n          }\n\n          if (delta.tool_calls) {\n            for (const toolCall of delta.tool_calls) {\n              const index = toolCall.index;\n\n              if (toolCall.id) {\n                toolCallIds[index] = toolCall.id;\n                yield {\n                  type: EventType.TOOL_CALL_START,\n                  toolCallId: toolCall.id,\n                  toolCallName: toolCall.function?.name || \"\",\n                };\n              }\n\n              if (toolCall.function?.arguments) {\n                const toolCallId = toolCallIds[index];\n                if (toolCallId) {\n                  yield {\n                    type: EventType.TOOL_CALL_ARGS,\n                    toolCallId,\n                    delta: toolCall.function.arguments,\n                  };\n                }\n              }\n            }\n          }\n\n          // Emit end events based on finish_reason\n          if (choice?.finish_reason === \"stop\") {\n            yield {\n              type: EventType.TEXT_MESSAGE_END,\n              messageId,\n            };\n          } else if (choice?.finish_reason === \"tool_calls\") {\n            for (const toolCallId of Object.values(toolCallIds)) {\n              yield {\n                type: EventType.TOOL_CALL_END,\n                toolCallId,\n              };\n            }\n          }\n        } catch (e) {\n          console.error(\"Failed to parse OpenAI SSE event\", e);\n        }\n      }\n    }\n  },\n});\n","import type { ChatCompletionChunk } from \"openai/resources/chat/completions\";\nimport { AGUIEvent, EventType, StreamProtocolAdapter } from \"../../types\";\n\n/**\n * Adapter for streams produced by the OpenAI SDK's `Stream.toReadableStream()`.\n * That method emits NDJSON (one JSON object per line, no `data: ` SSE prefix),\n * which differs from the raw SSE format that `openAIAdapter` expects.\n */\nexport const openAIReadableStreamAdapter = (): StreamProtocolAdapter => ({\n  async *parse(response: Response): AsyncIterable<AGUIEvent> {\n    const reader = response.body?.getReader();\n    if (!reader) throw new Error(\"No response body\");\n\n    const decoder = new TextDecoder();\n    const messageId = crypto.randomUUID();\n    const toolCallIds: Record<number, string> = {};\n    let messageStarted = false;\n    let buffer = \"\";\n\n    while (true) {\n      const { done, value } = await reader.read();\n      if (done) break;\n\n      buffer += decoder.decode(value, { stream: true });\n      const lines = buffer.split(\"\\n\");\n      buffer = lines.pop() ?? \"\";\n\n      for (const line of lines) {\n        const data = line.trim();\n        if (!data) continue;\n\n        try {\n          const json = JSON.parse(data) as ChatCompletionChunk;\n          const choice = json.choices?.[0];\n          const delta = choice?.delta;\n\n          if (!delta) continue;\n\n          if (!messageStarted && (delta.content || delta.role)) {\n            yield {\n              type: EventType.TEXT_MESSAGE_START,\n              messageId,\n              role: \"assistant\",\n            };\n            messageStarted = true;\n          }\n\n          if (delta.content) {\n            yield {\n              type: EventType.TEXT_MESSAGE_CONTENT,\n              messageId,\n              delta: delta.content,\n            };\n          }\n\n          if (delta.tool_calls) {\n            for (const toolCall of delta.tool_calls) {\n              const index = toolCall.index;\n\n              if (toolCall.id) {\n                toolCallIds[index] = toolCall.id;\n                yield {\n                  type: EventType.TOOL_CALL_START,\n                  toolCallId: toolCall.id,\n                  toolCallName: toolCall.function?.name || \"\",\n                };\n              }\n\n              if (toolCall.function?.arguments) {\n                const toolCallId = toolCallIds[index];\n                if (toolCallId) {\n                  yield {\n                    type: EventType.TOOL_CALL_ARGS,\n                    toolCallId,\n                    delta: toolCall.function.arguments,\n                  };\n                }\n              }\n            }\n          }\n\n          if (choice?.finish_reason === \"stop\") {\n            yield {\n              type: EventType.TEXT_MESSAGE_END,\n              messageId,\n            };\n          } else if (choice?.finish_reason === \"tool_calls\") {\n            for (const toolCallId of Object.values(toolCallIds)) {\n              yield {\n                type: EventType.TOOL_CALL_END,\n                toolCallId,\n              };\n            }\n          }\n        } catch (e) {\n          console.error(\"Failed to parse OpenAI NDJSON chunk\", e);\n        }\n      }\n    }\n  },\n});\n","import type { ResponseStreamEvent } from \"openai/resources/responses/responses\";\nimport { AGUIEvent, EventType, StreamProtocolAdapter } from \"../../types\";\n\nexport const openAIResponsesAdapter = (): StreamProtocolAdapter => ({\n  async *parse(response: Response): AsyncIterable<AGUIEvent> {\n    const reader = response.body?.getReader();\n    if (!reader) throw new Error(\"No response body\");\n\n    const decoder = new TextDecoder();\n    // Map item_id → call_id so TOOL_CALL_ARGS can reference the correct toolCallId\n    const itemIdToCallId: Record<string, string> = {};\n\n    while (true) {\n      const { done, value } = await reader.read();\n      if (done) break;\n\n      const chunk = decoder.decode(value, { stream: true });\n      const lines = chunk.split(\"\\n\");\n\n      for (const line of lines) {\n        if (!line.startsWith(\"data: \")) continue;\n        const data = line.slice(6).trim();\n        if (!data || data === \"[DONE]\") continue;\n\n        try {\n          const event = JSON.parse(data) as ResponseStreamEvent;\n\n          switch (event.type) {\n            case \"response.output_item.added\": {\n              const item = event.item;\n              if (item.type === \"message\" && item.role === \"assistant\") {\n                yield {\n                  type: EventType.TEXT_MESSAGE_START,\n                  messageId: item.id,\n                  role: \"assistant\",\n                };\n              } else if (item.type === \"function_call\") {\n                // Store the mapping so we can resolve it in arguments.delta\n                itemIdToCallId[item.id ?? item.call_id] = item.call_id;\n                yield {\n                  type: EventType.TOOL_CALL_START,\n                  toolCallId: item.call_id,\n                  toolCallName: item.name,\n                };\n              }\n              break;\n            }\n\n            case \"response.output_text.delta\":\n              yield {\n                type: EventType.TEXT_MESSAGE_CONTENT,\n                messageId: event.item_id,\n                delta: event.delta,\n              };\n              break;\n\n            case \"response.output_text.done\":\n              yield {\n                type: EventType.TEXT_MESSAGE_END,\n                messageId: event.item_id,\n              };\n              break;\n\n            case \"response.function_call_arguments.delta\": {\n              const callId = itemIdToCallId[event.item_id] ?? event.item_id;\n              yield {\n                type: EventType.TOOL_CALL_ARGS,\n                toolCallId: callId,\n                delta: event.delta,\n              };\n              break;\n            }\n\n            case \"response.function_call_arguments.done\": {\n              const callId = itemIdToCallId[event.item_id] ?? event.item_id;\n              yield {\n                type: EventType.TOOL_CALL_END,\n                toolCallId: callId,\n              };\n              break;\n            }\n\n            case \"error\":\n              yield {\n                type: EventType.RUN_ERROR,\n                message: event.message,\n                code: event.code ?? undefined,\n              };\n              break;\n\n            case \"response.failed\":\n              yield {\n                type: EventType.RUN_ERROR,\n                message: event.response?.error?.message ?? \"Response failed\",\n                code: event.response?.error?.code ?? undefined,\n              };\n              break;\n\n            // Intentionally unhandled — these are lifecycle/metadata events:\n            // response.created, response.in_progress, response.completed,\n            // response.content_part.added, response.content_part.done,\n            // response.output_item.done, etc.\n            default:\n              break;\n          }\n        } catch (e) {\n          console.error(\"Failed to parse OpenAI Responses SSE event\", e);\n        }\n      }\n    }\n  },\n});\n","import { AssistantMessage, EventType, StreamProtocolAdapter } from \"../types\";\nimport { agUIAdapter } from \"./adapters\";\n\n/**\n * @inline\n */\ninterface Parameters {\n  response: Response;\n  /** A function that creates a new assistant message in the thread */\n  createMessage: (message: AssistantMessage) => void;\n  /** A function that updates an existing assistant message in the thread */\n  updateMessage: (message: AssistantMessage) => void;\n  /** A function that deletes an assistant message from the thread */\n  deleteMessage: (messageId: string) => void;\n  /** The adapter to use for parsing the stream */\n  adapter?: StreamProtocolAdapter;\n}\n\n/**\n * @category Utilities\n */\nexport const processStreamedMessage = async ({\n  response,\n  createMessage,\n  updateMessage,\n  deleteMessage,\n  adapter = agUIAdapter(),\n}: Parameters): Promise<AssistantMessage | void> => {\n  let currentMessage: AssistantMessage = {\n    id: crypto.randomUUID(),\n    role: \"assistant\",\n    content: \"\",\n    toolCalls: [],\n  };\n\n  let isFirst = true;\n\n  let rafId: number | null = null;\n  const debouncedUpdate = (msg: AssistantMessage) => {\n    if (rafId !== null) cancelAnimationFrame(rafId);\n    rafId = requestAnimationFrame(() => {\n      updateMessage(msg);\n      rafId = null;\n    });\n  };\n\n  for await (const event of adapter.parse(response)) {\n    switch (event.type) {\n      // TEXT_MESSAGE_CHUNK and TEXT_MESSAGE_CONTENT are very similar events but TEXT_MESSAGE_CHUNK\n      // optionally allows for a role change. Since we don't support role changes in processMessage\n      // right now, we treat both the same.\n      case EventType.TEXT_MESSAGE_CHUNK:\n      case EventType.TEXT_MESSAGE_CONTENT:\n        currentMessage = {\n          ...currentMessage,\n          content: (currentMessage.content || \"\") + event.delta,\n        };\n        break;\n\n      case EventType.TOOL_CALL_START:\n        currentMessage = {\n          ...currentMessage,\n          toolCalls: [\n            ...(currentMessage.toolCalls || []),\n            {\n              id: event.toolCallId,\n              type: \"function\",\n              function: {\n                name: event.toolCallName,\n                arguments: \"\",\n              },\n            },\n          ],\n        };\n        break;\n\n      case EventType.TOOL_CALL_ARGS:\n        if (currentMessage.toolCalls) {\n          const toolCalls = [...currentMessage.toolCalls];\n          const toolCallIndex = toolCalls.findIndex((tc) => tc.id === event.toolCallId);\n          if (toolCallIndex !== -1) {\n            const currentToolCall = toolCalls[toolCallIndex];\n            if (currentToolCall) {\n              toolCalls[toolCallIndex] = {\n                id: currentToolCall.id,\n                type: \"function\",\n                function: {\n                  name: currentToolCall.function.name,\n                  arguments: currentToolCall.function.arguments + event.delta,\n                },\n              };\n              currentMessage = { ...currentMessage, toolCalls };\n            }\n          }\n        }\n        break;\n\n      case EventType.TEXT_MESSAGE_START:\n        // Use the ID from the event if it differs from our optimistic ID\n        if (event.messageId !== currentMessage.id) {\n          deleteMessage(currentMessage.id);\n          currentMessage = { ...currentMessage, id: event.messageId };\n          isFirst = true; // Will trigger createMessage with new ID\n        }\n        break;\n\n      case EventType.RUN_ERROR: {\n        const msg = (event as any).message || (event as any).error || \"Stream error\";\n        throw new Error(typeof msg === \"string\" ? msg : JSON.stringify(msg));\n      }\n    }\n\n    if (isFirst) {\n      createMessage(currentMessage);\n      isFirst = false;\n    } else {\n      // debounce the message update using raf\n      debouncedUpdate(currentMessage);\n    }\n  }\n\n  if (rafId !== null) {\n    // flush any update\n    cancelAnimationFrame(rafId);\n    updateMessage(currentMessage);\n  }\n\n  return currentMessage;\n};\n","import { createStore } from \"zustand\";\nimport { subscribeWithSelector } from \"zustand/middleware\";\nimport { processStreamedMessage } from \"../stream/processStreamedMessage\";\nimport { identityMessageFormat } from \"../types/messageFormat\";\nimport type { ChatProviderProps, ChatStore, Message, Thread, UserMessage } from \"./types\";\n\ntype StoreConfig = Omit<ChatProviderProps, \"children\">;\n\nconst mergeThreadList = (existing: Thread[], incoming: Thread[]): Thread[] =>\n  Array.from(new Map([...existing, ...incoming].map((t) => [t.id, t])).values()).sort(\n    (a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime(),\n  );\n\nexport const createChatStore = (config: StoreConfig) => {\n  const {\n    apiUrl,\n    threadApiUrl,\n    processMessage: userProcessMessage,\n    fetchThreadList: userFetchThreadList,\n    createThread: userCreateThread,\n    deleteThread: userDeleteThread,\n    updateThread: userUpdateThread,\n    loadThread: userLoadThread,\n    streamProtocol,\n    messageFormat = identityMessageFormat,\n  } = config;\n\n  // ── Default implementations (when threadApiUrl is provided) ──\n\n  const fetchThreadList =\n    userFetchThreadList ??\n    (async (cursor?: any) => {\n      if (!threadApiUrl) return { threads: [] };\n      const url = cursor ? `${threadApiUrl}/get?cursor=${cursor}` : `${threadApiUrl}/get`;\n      const res = await fetch(url);\n      return res.json();\n    });\n\n  const createThread =\n    userCreateThread ??\n    (async (firstMessage: UserMessage) => {\n      if (!threadApiUrl) throw new Error(\"threadApiUrl or createThread required\");\n      const res = await fetch(`${threadApiUrl}/create`, {\n        method: \"POST\",\n        headers: { \"Content-Type\": \"application/json\" },\n        body: JSON.stringify({ messages: messageFormat.toApi([firstMessage]) }),\n      });\n      return res.json();\n    });\n\n  const deleteThreadFn =\n    userDeleteThread ??\n    (async (id: string) => {\n      if (!threadApiUrl) return;\n      await fetch(`${threadApiUrl}/delete/${id}`, { method: \"DELETE\" });\n    });\n\n  const updateThreadFn =\n    userUpdateThread ??\n    (async (updated: Thread) => {\n      if (!threadApiUrl) return updated;\n      const res = await fetch(`${threadApiUrl}/update/${updated.id}`, {\n        method: \"PATCH\",\n        headers: { \"Content-Type\": \"application/json\" },\n        body: JSON.stringify(updated),\n      });\n      return res.json();\n    });\n\n  const loadThread =\n    userLoadThread ??\n    (async (threadId: string): Promise<Message[]> => {\n      if (!threadApiUrl) return [];\n      const res = await fetch(`${threadApiUrl}/get/${threadId}`);\n      const raw: unknown = await res.json();\n      return messageFormat.fromApi(raw);\n    });\n\n  const sendMessage =\n    userProcessMessage ??\n    (async ({\n      threadId,\n      messages,\n      abortController,\n    }: {\n      threadId: string;\n      messages: Message[];\n      abortController: AbortController;\n    }) => {\n      if (!apiUrl) throw new Error(\"apiUrl or processMessage required\");\n      return fetch(apiUrl, {\n        method: \"POST\",\n        headers: { \"Content-Type\": \"application/json\" },\n        body: JSON.stringify({\n          threadId,\n          messages: messageFormat.toApi(messages),\n        }),\n        signal: abortController.signal,\n      });\n    });\n\n  // ── Store ──\n\n  const store = createStore<ChatStore>()(\n    subscribeWithSelector((set, get) => ({\n      // Thread List State\n      threads: [],\n      isLoadingThreads: false,\n      threadListError: null,\n      selectedThreadId: null,\n      hasMoreThreads: false,\n      _nextCursor: undefined,\n\n      // Thread State\n      messages: [],\n      isRunning: false,\n      isLoadingMessages: false,\n      threadError: null,\n      _abortController: null,\n\n      // ── Thread List Actions ──\n\n      loadThreads: () => {\n        set({ isLoadingThreads: true, threadListError: null });\n        fetchThreadList(undefined)\n          .then(({ threads = [], nextCursor }) => {\n            set({\n              threads,\n              isLoadingThreads: false,\n              _nextCursor: nextCursor,\n              hasMoreThreads: nextCursor !== undefined,\n            });\n          })\n          .catch((e) => {\n            set({ isLoadingThreads: false, threadListError: e });\n          });\n      },\n\n      loadMoreThreads: () => {\n        const cursor = get()._nextCursor;\n        if (cursor === undefined) return;\n        fetchThreadList(cursor)\n          .then(({ threads = [], nextCursor }) => {\n            set((s) => ({\n              threads: mergeThreadList(s.threads, threads),\n              _nextCursor: nextCursor,\n              hasMoreThreads: nextCursor !== undefined,\n            }));\n          })\n          .catch((e) => {\n            set({ threadListError: e });\n          });\n      },\n\n      switchToNewThread: () => {\n        get().cancelMessage();\n        set({ selectedThreadId: null, messages: [], threadError: null });\n      },\n\n      createThread: async (firstMessage: UserMessage) => {\n        const thread = await createThread(firstMessage);\n        set((s) => ({ threads: mergeThreadList(s.threads, [thread]) }));\n        return thread;\n      },\n\n      selectThread: (threadId: string) => {\n        get().cancelMessage();\n        set({\n          selectedThreadId: threadId,\n          messages: [],\n          isLoadingMessages: true,\n          threadError: null,\n        });\n        loadThread(threadId)\n          .then((messages) => set({ messages, isLoadingMessages: false }))\n          .catch((e) => set({ threadError: e, isLoadingMessages: false }));\n      },\n\n      updateThread: (thread: Thread) => {\n        const setPending = (id: string, isPending: boolean) =>\n          set((s) => ({ threads: s.threads.map((t) => (t.id === id ? { ...t, isPending } : t)) }));\n        setPending(thread.id, true);\n        updateThreadFn(thread)\n          .then((updated) => {\n            set((s) => ({\n              threads: s.threads.map((t) => (t.id === updated.id ? updated : t)),\n            }));\n          })\n          .catch(() => setPending(thread.id, false));\n      },\n\n      deleteThread: (threadId: string) => {\n        const setPending = (id: string, isPending: boolean) =>\n          set((s) => ({ threads: s.threads.map((t) => (t.id === id ? { ...t, isPending } : t)) }));\n        setPending(threadId, true);\n        deleteThreadFn(threadId)\n          .then(() => {\n            const state = get();\n            set({ threads: state.threads.filter((t) => t.id !== threadId) });\n            if (state.selectedThreadId === threadId) {\n              state.switchToNewThread();\n            }\n          })\n          .catch(() => setPending(threadId, false));\n      },\n\n      // ── Thread Actions ──\n\n      processMessage: async (message) => {\n        const state = get();\n        if (state.isRunning) return;\n\n        const abortController = new AbortController();\n        const optimisticMessage: UserMessage = {\n          ...message,\n          id: crypto.randomUUID(),\n          role: \"user\",\n        };\n\n        set({ _abortController: abortController, isRunning: true, threadError: null });\n        set((s) => ({ messages: [...s.messages, optimisticMessage] }));\n\n        abortController.signal.addEventListener(\"abort\", () => {\n          set({ _abortController: null, isRunning: false });\n        });\n\n        try {\n          let threadId = get().selectedThreadId;\n\n          if (!threadId) {\n            if (userCreateThread || threadApiUrl) {\n              const created = await get().createThread(optimisticMessage);\n              threadId = created.id;\n              set({ selectedThreadId: threadId });\n            } else {\n              threadId = \"ephemeral\";\n            }\n          }\n\n          const response = await sendMessage({\n            threadId,\n            messages: get().messages,\n            abortController,\n          });\n\n          if (response instanceof Response && !response.ok) {\n            throw new Error(`Request failed: ${response.status} ${response.statusText}`);\n          }\n\n          await processStreamedMessage({\n            response,\n            createMessage: (msg) => set((s) => ({ messages: [...s.messages, msg] })),\n            updateMessage: (msg) =>\n              set((s) => ({\n                messages: s.messages.map((m) => (m.id === msg.id ? msg : m)),\n              })),\n            deleteMessage: (id) =>\n              set((s) => ({ messages: s.messages.filter((m) => m.id !== id) })),\n            adapter: streamProtocol,\n          });\n        } catch (e) {\n          if (!abortController.signal.aborted) {\n            set({ threadError: e instanceof Error ? e : new Error(String(e)) });\n          }\n        } finally {\n          set({ _abortController: null, isRunning: false });\n        }\n      },\n\n      appendMessages: (...newMessages: Message[]) => {\n        set((s) => ({ messages: [...s.messages, ...newMessages] }));\n      },\n\n      updateMessage: (message: Message) => {\n        set((s) => ({\n          messages: s.messages.map((m) => (m.id === message.id ? message : m)),\n        }));\n      },\n\n      setMessages: (messages: Message[]) => {\n        set({ messages });\n      },\n\n      deleteMessage: (messageId: string) => {\n        set((s) => ({ messages: s.messages.filter((m) => m.id !== messageId) }));\n      },\n\n      cancelMessage: () => {\n        get()._abortController?.abort();\n      },\n    })),\n  );\n\n  return store;\n};\n","import { useEffect, useState, type FC } from \"react\";\nimport { ArtifactContext } from \"./ArtifactContext\";\nimport { ChatContext } from \"./ChatContext\";\nimport { createArtifactStore } from \"./createArtifactStore\";\nimport { createChatStore } from \"./createChatStore\";\nimport type { ChatProviderProps } from \"./types\";\n\nexport const ChatProvider: FC<ChatProviderProps> = ({ children, ...config }) => {\n  const [chatStore] = useState(() => createChatStore(config));\n  const [artifactStore] = useState(() => createArtifactStore());\n\n  // Cross-store subscription: reset artifacts when the active thread changes.\n  // useEffect (not inline) so the cleanup function unsubscribes on unmount.\n  useEffect(() => {\n    const unsubscribe = chatStore.subscribe(\n      (state) => state.selectedThreadId,\n      () => artifactStore.getState().resetArtifacts(),\n    );\n    return unsubscribe;\n  }, [chatStore, artifactStore]);\n\n  return (\n    <ChatContext.Provider value={chatStore}>\n      <ArtifactContext.Provider value={artifactStore}>{children}</ArtifactContext.Provider>\n    </ChatContext.Provider>\n  );\n};\n","import type { AssistantMessage, Message, ToolMessage, UserMessage } from \"../../types\";\nimport type { MessageFormat } from \"../../types/messageFormat\";\n\n// ── LangGraph / LangChain message types ──────────────────────────\n\n/**\n * LangChain-style message as returned by the LangGraph thread state API.\n * Each message carries a `type` discriminator (`\"human\"`, `\"ai\"`, `\"tool\"`,\n * `\"system\"`) and uses snake_case field names.\n */\ninterface LangChainMessage {\n  id?: string;\n  type: \"human\" | \"ai\" | \"tool\" | \"system\" | \"developer\" | (string & {});\n  content: string | Array<{ type: string; text?: string }>;\n  name?: string;\n  tool_calls?: Array<{\n    id: string;\n    name: string;\n    args: Record<string, unknown> | string;\n  }>;\n  tool_call_id?: string;\n}\n\n// ── Outbound (AG-UI → LangGraph) ────────────────────────────────\n\nfunction toLangChainMessage(message: Message): LangChainMessage {\n  switch (message.role) {\n    case \"user\":\n      return { type: \"human\", content: message.content ?? \"\" };\n\n    case \"assistant\": {\n      const result: LangChainMessage = { type: \"ai\", content: message.content ?? \"\" };\n      if (message.toolCalls?.length) {\n        result.tool_calls = message.toolCalls.map((tc) => ({\n          id: tc.id,\n          name: tc.function.name,\n          args: safeParseArgs(tc.function.arguments),\n        }));\n      }\n      return result;\n    }\n\n    case \"tool\":\n      return {\n        type: \"tool\",\n        content: message.content,\n        tool_call_id: message.toolCallId,\n      };\n\n    case \"system\":\n      return { type: \"system\", content: message.content };\n\n    case \"developer\":\n      return { type: \"system\", content: message.content };\n\n    default:\n      return { type: \"system\", content: \"\" };\n  }\n}\n\n// ── Inbound (LangGraph → AG-UI) ────────────────────────────────\n\nfunction fromLangChainMessage(msg: LangChainMessage): Message {\n  const id = msg.id ?? crypto.randomUUID();\n\n  switch (msg.type) {\n    case \"human\":\n      return { id, role: \"user\", content: extractContent(msg.content) } satisfies UserMessage;\n\n    case \"ai\": {\n      const result: AssistantMessage = {\n        id,\n        role: \"assistant\",\n        content: extractContent(msg.content),\n      };\n      if (msg.tool_calls?.length) {\n        result.toolCalls = msg.tool_calls.map((tc) => ({\n          id: tc.id,\n          type: \"function\" as const,\n          function: {\n            name: tc.name,\n            arguments: typeof tc.args === \"string\" ? tc.args : JSON.stringify(tc.args),\n          },\n        }));\n      }\n      return result;\n    }\n\n    case \"tool\":\n      return {\n        id,\n        role: \"tool\",\n        content: extractContent(msg.content),\n        toolCallId: msg.tool_call_id ?? \"\",\n      } satisfies ToolMessage;\n\n    case \"system\":\n    case \"developer\":\n      return { id, role: \"system\", content: extractContent(msg.content) };\n\n    default:\n      return { id, role: \"system\", content: extractContent(msg.content) };\n  }\n}\n\n// ── Helpers ──────────────────────────────────────────────────────\n\nfunction extractContent(content: string | Array<{ type: string; text?: string }>): string {\n  if (typeof content === \"string\") return content;\n  return content\n    .filter((block) => block.type === \"text\" && block.text)\n    .map((block) => block.text!)\n    .join(\"\");\n}\n\nfunction safeParseArgs(args: string): Record<string, unknown> | string {\n  try {\n    return JSON.parse(args) as Record<string, unknown>;\n  } catch {\n    return args;\n  }\n}\n\n// ── MessageFormat implementation ─────────────────────────────────\n\n/**\n * Converts between AG-UI message format and LangGraph's LangChain-style\n * message format.\n *\n * LangGraph uses `type` discriminators (`\"human\"`, `\"ai\"`, `\"tool\"`,\n * `\"system\"`) instead of `role`, and tool call arguments are objects\n * rather than JSON strings.\n *\n * AG-UI → LangGraph (toApi):\n *   - Maps `role` to `type` (`\"user\"` → `\"human\"`, `\"assistant\"` → `\"ai\"`)\n *   - Converts `toolCalls[].function.arguments` from JSON string to object\n *   - Converts `toolCallId` → `tool_call_id`\n *\n * LangGraph → AG-UI (fromApi):\n *   - Maps `type` to `role` (`\"human\"` → `\"user\"`, `\"ai\"` → `\"assistant\"`)\n *   - Converts tool call `args` object to JSON string\n *   - Generates `id` via `crypto.randomUUID()` if not present\n */\nexport const langGraphMessageFormat: MessageFormat = {\n  toApi(messages: Message[]): LangChainMessage[] {\n    return messages.map(toLangChainMessage);\n  },\n\n  fromApi(data: unknown): Message[] {\n    return (data as LangChainMessage[]).map(fromLangChainMessage);\n  },\n};\n\nexport type { LangChainMessage as LangGraphMessageFormat };\n","import type { Message as ConversationMessage } from \"openai/resources/conversations/conversations\";\nimport type { ConversationItem } from \"openai/resources/conversations/items\";\nimport type {\n  EasyInputMessage,\n  ResponseFunctionToolCall,\n  ResponseFunctionToolCallOutputItem,\n  ResponseInputItem,\n  ResponseInputMessageContentList,\n} from \"openai/resources/responses/responses\";\nimport type { AssistantMessage, Message, ToolMessage, UserMessage } from \"../../types\";\nimport type { MessageFormat } from \"../../types/messageFormat\";\n\n// ── Outbound (AG-UI → OpenAI Responses/Conversations input) ─────\n\n/**\n * Both the Responses API and the Conversations API accept\n * `ResponseInputItem[]` as input, so a single outbound conversion\n * works for both.\n *\n * Tool calls are *sibling items* of the assistant message, not nested\n * inside it.  We flatten each AG-UI assistant message into:\n *   1. An `EasyInputMessage` with `role: \"assistant\"` (text part)\n *   2. One `ResponseFunctionToolCall` per tool call\n *\n * Tool result messages become `FunctionCallOutput` items.\n */\nfunction toItems(message: Message): ResponseInputItem[] {\n  switch (message.role) {\n    case \"user\":\n      return [toInputMessage(message)];\n\n    case \"assistant\": {\n      const items: ResponseInputItem[] = [];\n\n      if (message.content) {\n        items.push({\n          role: \"assistant\",\n          content: message.content,\n          type: \"message\",\n        } satisfies EasyInputMessage);\n      }\n\n      if (message.toolCalls?.length) {\n        for (const tc of message.toolCalls) {\n          items.push({\n            type: \"function_call\",\n            call_id: tc.id,\n            name: tc.function.name,\n            arguments: tc.function.arguments,\n          } satisfies ResponseFunctionToolCall);\n        }\n      }\n\n      return items;\n    }\n\n    case \"tool\":\n      return [\n        {\n          type: \"function_call_output\",\n          call_id: message.toolCallId,\n          output: message.content,\n        } as ResponseInputItem,\n      ];\n\n    case \"system\":\n      return [\n        { role: \"system\", content: message.content, type: \"message\" } satisfies EasyInputMessage,\n      ];\n\n    case \"developer\":\n      return [\n        { role: \"developer\", content: message.content, type: \"message\" } satisfies EasyInputMessage,\n      ];\n\n    default:\n      return [];\n  }\n}\n\nfunction toInputMessage(message: UserMessage): EasyInputMessage {\n  const content = message.content;\n\n  if (typeof content === \"string\") {\n    return { role: \"user\", content, type: \"message\" };\n  }\n\n  const parts: ResponseInputMessageContentList =\n    content?.map((part) => {\n      if (part.type === \"text\") {\n        return { type: \"input_text\" as const, text: part.text };\n      }\n      if (part.type === \"binary\") {\n        const url = part.url ?? `data:${part.mimeType};base64,${part.data ?? \"\"}`;\n        return { type: \"input_image\" as const, image_url: url, detail: \"auto\" as const };\n      }\n      return { type: \"input_text\" as const, text: \"\" };\n    }) ?? [];\n\n  return { role: \"user\", content: parts, type: \"message\" };\n}\n\n// ── Inbound (OpenAI Conversations/Responses → AG-UI) ────────────\n\n/**\n * Converts `ConversationItem[]` (from the Conversations API) or\n * `ResponseItem[]` (from the Responses API) into AG-UI `Message[]`.\n *\n * Both APIs return items as a flat list with `type` discriminator:\n *   - `\"message\"` → user / assistant / system / developer / tool message\n *   - `\"function_call\"` → tool call (grouped into the preceding assistant)\n *   - `\"function_call_output\"` → tool result\n *\n * The Conversations API `Message` type is a superset that also handles\n * `reasoning_text`, `summary_text`, and `text` content parts, as well\n * as additional roles like `tool` and `critic`.\n */\nfunction fromItems(items: ConversationItem[]): Message[] {\n  const messages: Message[] = [];\n  let currentAssistant: AssistantMessage | null = null;\n\n  for (const item of items) {\n    switch (item.type) {\n      case \"message\": {\n        // Flush any pending assistant message\n        if (currentAssistant) {\n          messages.push(currentAssistant);\n          currentAssistant = null;\n        }\n\n        const msg = item as ConversationMessage;\n\n        if (msg.role === \"assistant\") {\n          currentAssistant = {\n            id: msg.id,\n            role: \"assistant\",\n            content: extractTextContent(msg) || undefined,\n          };\n        } else if (msg.role === \"tool\") {\n          // Conversations API can have tool messages with type: \"message\"\n          messages.push({\n            id: msg.id,\n            role: \"tool\",\n            content: extractTextContent(msg),\n            toolCallId: \"\",\n          } as ToolMessage);\n        } else if (msg.role === \"user\") {\n          messages.push(fromUserMessage(msg));\n        } else {\n          // system / developer / unknown / critic / discriminator\n          const role = msg.role === \"developer\" ? \"developer\" : \"system\";\n          messages.push({\n            id: msg.id,\n            role,\n            content: extractTextContent(msg),\n          } as Message);\n        }\n        break;\n      }\n\n      case \"function_call\": {\n        const tc = item as { id?: string; call_id: string; name: string; arguments: string };\n\n        if (!currentAssistant) {\n          currentAssistant = { id: crypto.randomUUID(), role: \"assistant\" };\n        }\n\n        currentAssistant = {\n          ...currentAssistant,\n          toolCalls: [\n            ...(currentAssistant.toolCalls ?? []),\n            {\n              id: tc.call_id,\n              type: \"function\" as const,\n              function: { name: tc.name, arguments: tc.arguments },\n            },\n          ],\n        };\n        break;\n      }\n\n      case \"function_call_output\": {\n        if (currentAssistant) {\n          messages.push(currentAssistant);\n          currentAssistant = null;\n        }\n\n        const output = item as ResponseFunctionToolCallOutputItem;\n        messages.push({\n          id: output.id,\n          role: \"tool\",\n          content:\n            typeof output.output === \"string\" ? output.output : JSON.stringify(output.output),\n          toolCallId: output.call_id,\n        } as ToolMessage);\n        break;\n      }\n\n      default:\n        // file_search, web_search, computer_call, reasoning, etc. — skip\n        break;\n    }\n  }\n\n  if (currentAssistant) {\n    messages.push(currentAssistant);\n  }\n\n  return messages;\n}\n\n/**\n * Extract text content from a Conversations API `Message`.\n *\n * Handles the full content union:\n *   - `output_text` (assistant output)\n *   - `input_text` (user/system/developer input)\n *   - `text` (generic text)\n *   - `summary_text`, `reasoning_text` (appended)\n *   - `refusal` (mapped to text)\n */\nfunction extractTextContent(msg: ConversationMessage): string {\n  return msg.content\n    .map((part) => {\n      switch (part.type) {\n        case \"output_text\":\n          return part.text;\n        case \"input_text\":\n          return part.text;\n        case \"text\":\n          return part.text;\n        case \"summary_text\":\n          return part.text;\n        case \"reasoning_text\":\n          return part.text;\n        case \"refusal\":\n          return `[Refusal]: ${part.refusal}`;\n        default:\n          return \"\";\n      }\n    })\n    .filter(Boolean)\n    .join(\"\");\n}\n\nfunction fromUserMessage(msg: ConversationMessage): UserMessage {\n  // Check if content has images/files — if so, use multipart\n  const hasMedia = msg.content.some(\n    (part) => part.type === \"input_image\" || part.type === \"input_file\",\n  );\n\n  if (!hasMedia) {\n    return { id: msg.id, role: \"user\", content: extractTextContent(msg) };\n  }\n\n  const parts = msg.content.map(\n    (part): { type: \"text\"; text: string } | { type: \"binary\"; url: string; mimeType: string } => {\n      if (part.type === \"input_text\" || part.type === \"text\") {\n        return { type: \"text\", text: part.text };\n      }\n      if (part.type === \"input_image\" && part.image_url) {\n        return { type: \"binary\", url: part.image_url, mimeType: \"image/*\" };\n      }\n      return { type: \"text\", text: \"\" };\n    },\n  );\n\n  return { id: msg.id, role: \"user\", content: parts };\n}\n\n// ── MessageFormat implementation ─────────────────────────────────\n\n/**\n * Converts between AG-UI message format and OpenAI's item-based format,\n * compatible with both the **Responses API** and **Conversations API**.\n *\n * AG-UI → OpenAI (toApi):\n *   - Returns `ResponseInputItem[]` — works for both `responses.create({ input })`\n *     and `conversations.items.create({ items })`\n *   - Flattens assistant messages: text → `EasyInputMessage`, tool calls → `ResponseFunctionToolCall`\n *\n * OpenAI → AG-UI (fromApi):\n *   - Accepts `ConversationItem[]` (or `ResponseItem[]`, which is a subset)\n *   - Groups adjacent assistant messages + function_calls into `AssistantMessage`\n *   - Handles Conversations-specific content types (`reasoning_text`, `summary_text`, etc.)\n */\nexport const openAIConversationMessageFormat: MessageFormat = {\n  toApi(messages: Message[]): ResponseInputItem[] {\n    return messages.flatMap(toItems);\n  },\n\n  fromApi(data: unknown): Message[] {\n    return fromItems(data as ConversationItem[]);\n  },\n};\n","import type {\n  ChatCompletionAssistantMessageParam,\n  ChatCompletionMessageParam,\n  ChatCompletionToolMessageParam,\n  ChatCompletionUserMessageParam,\n} from \"openai/resources/chat/completions\";\nimport type { AssistantMessage, Message, ToolMessage, UserMessage } from \"../../types\";\nimport type { MessageFormat } from \"../../types/messageFormat\";\n\n// ── Outbound (AG-UI → OpenAI Completions) ───────────────────────\n\nfunction toOpenAIUserMessage(message: UserMessage): ChatCompletionUserMessageParam {\n  const content = message.content;\n\n  if (typeof content === \"string\") {\n    return { role: \"user\", content };\n  }\n\n  const parts: ChatCompletionUserMessageParam[\"content\"] =\n    content?.map((part) => {\n      if (part.type === \"text\") {\n        return { type: \"text\" as const, text: part.text };\n      }\n      if (part.type === \"binary\") {\n        const url = part.url ?? `data:${part.mimeType};base64,${part.data ?? \"\"}`;\n        return { type: \"image_url\" as const, image_url: { url } };\n      }\n      return { type: \"text\" as const, text: \"\" };\n    }) ?? [];\n\n  return { role: \"user\", content: parts };\n}\n\nfunction toOpenAIAssistantMessage(message: AssistantMessage): ChatCompletionAssistantMessageParam {\n  const result: ChatCompletionAssistantMessageParam = {\n    role: \"assistant\",\n    content: message.content ?? null,\n  };\n\n  if (message.toolCalls?.length) {\n    result.tool_calls = message.toolCalls.map((tc) => ({\n      id: tc.id,\n      type: \"function\" as const,\n      function: {\n        name: tc.function.name,\n        arguments: tc.function.arguments,\n      },\n    }));\n  }\n\n  return result;\n}\n\nfunction toOpenAIToolMessage(message: ToolMessage): ChatCompletionToolMessageParam {\n  return {\n    role: \"tool\",\n    content: message.content,\n    tool_call_id: message.toolCallId,\n  };\n}\n\nfunction toOpenAI(message: Message): ChatCompletionMessageParam {\n  switch (message.role) {\n    case \"user\":\n      return toOpenAIUserMessage(message);\n    case \"assistant\":\n      return toOpenAIAssistantMessage(message);\n    case \"tool\":\n      return toOpenAIToolMessage(message);\n    case \"system\":\n      return { role: \"system\", content: message.content };\n    case \"developer\":\n      return { role: \"developer\", content: message.content };\n    default:\n      // reasoning, activity — map to system as fallback\n      return { role: \"system\", content: \"\" };\n  }\n}\n\n// ── Inbound (OpenAI Completions → AG-UI) ────────────────────────\n\nfunction fromOpenAIAssistant(msg: ChatCompletionAssistantMessageParam): AssistantMessage {\n  const content = typeof msg.content === \"string\" ? msg.content : undefined;\n\n  const result: AssistantMessage = {\n    id: crypto.randomUUID(),\n    role: \"assistant\",\n    content,\n  };\n\n  if (msg.tool_calls?.length) {\n    result.toolCalls = msg.tool_calls\n      .filter((tc): tc is Extract<typeof tc, { type: \"function\" }> => tc.type === \"function\")\n      .map((tc) => ({\n        id: tc.id,\n        type: \"function\" as const,\n        function: {\n          name: tc.function.name,\n          arguments: tc.function.arguments,\n        },\n      }));\n  }\n\n  return result;\n}\n\nfunction fromOpenAIUser(msg: ChatCompletionUserMessageParam): UserMessage {\n  if (typeof msg.content === \"string\") {\n    return { id: crypto.randomUUID(), role: \"user\", content: msg.content };\n  }\n\n  const content = msg.content.map((part): { type: \"text\"; text: string } => {\n    if (part.type === \"text\") return { type: \"text\", text: part.text };\n    return { type: \"text\", text: \"\" };\n  });\n\n  return { id: crypto.randomUUID(), role: \"user\", content };\n}\n\nfunction fromOpenAITool(msg: ChatCompletionToolMessageParam): ToolMessage {\n  const content =\n    typeof msg.content === \"string\" ? msg.content : msg.content.map((p) => p.text).join(\"\");\n\n  return {\n    id: crypto.randomUUID(),\n    role: \"tool\",\n    content,\n    toolCallId: msg.tool_call_id,\n  };\n}\n\nfunction fromOpenAI(data: ChatCompletionMessageParam): Message {\n  switch (data.role) {\n    case \"user\":\n      return fromOpenAIUser(data);\n    case \"assistant\":\n      return fromOpenAIAssistant(data);\n    case \"tool\":\n      return fromOpenAITool(data);\n    case \"system\":\n      return {\n        id: crypto.randomUUID(),\n        role: \"system\",\n        content: typeof data.content === \"string\" ? data.content : \"\",\n      };\n    case \"developer\":\n      return {\n        id: crypto.randomUUID(),\n        role: \"developer\",\n        content: typeof data.content === \"string\" ? data.content : \"\",\n      };\n    default:\n      return { id: crypto.randomUUID(), role: \"system\", content: \"\" };\n  }\n}\n\n// ── MessageFormat implementation ─────────────────────────────────\n\n/**\n * Converts between AG-UI message format and OpenAI **Chat Completions**\n * message format (`ChatCompletionMessageParam`).\n *\n * This is a 1-to-1 mapping — each AG-UI message becomes exactly one\n * `ChatCompletionMessageParam` and vice versa.\n *\n * AG-UI → OpenAI (toApi):\n *   - Strips `id` (OpenAI doesn't use message IDs)\n *   - Converts `toolCalls` → `tool_calls`\n *   - Converts `toolCallId` → `tool_call_id`\n *   - Converts multipart `content` arrays to OpenAI content format\n *\n * OpenAI → AG-UI (fromApi):\n *   - Generates `id` via `crypto.randomUUID()`\n *   - Converts `tool_calls` → `toolCalls`\n *   - Converts `tool_call_id` → `toolCallId`\n */\nexport const openAIMessageFormat: MessageFormat = {\n  toApi(messages: Message[]): ChatCompletionMessageParam[] {\n    return messages.map(toOpenAI);\n  },\n\n  fromApi(data: unknown): Message[] {\n    return (data as ChatCompletionMessageParam[]).map(fromOpenAI);\n  },\n};\n"],"mappings":"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"}