{"version":3,"file":"orchestrator-custom.cjs","names":["#options","#historyValues","#threadId","MessageTupleManager","StreamManager","toMessageClass","#streamUnsub","#flushPendingHeadlessToolInterrupts","#notify","#getMessages","#listeners","#version","#disposed","#handledHeadlessToolInterruptIds","#branch","ensureMessageInstances","getToolCallsWithResults","userFacingInterruptsFromValuesArray","extractInterrupts","#setMessages"],"sources":["../../src/ui/orchestrator-custom.ts"],"sourcesContent":["import type { BaseMessage } from \"@langchain/core/messages\";\n\nimport type { ThreadState, Interrupt } from \"../schema.js\";\nimport type { StreamMode } from \"../types.stream.js\";\nimport type { Message } from \"../types.messages.js\";\nimport type { BagTemplate } from \"../types.template.js\";\nimport { StreamManager, type EventStreamEvent } from \"./manager.js\";\nimport {\n  MessageTupleManager,\n  toMessageClass,\n  ensureMessageInstances,\n} from \"./messages.js\";\nimport {\n  extractInterrupts,\n  userFacingInterruptsFromValuesArray,\n} from \"./interrupts.js\";\nimport { getToolCallsWithResults } from \"../utils/tools.js\";\nimport { flushPendingHeadlessToolInterrupts } from \"../headless-tools.js\";\nimport type {\n  AnyStreamCustomOptions,\n  CustomSubmitOptions,\n  MessageMetadata,\n  GetUpdateType,\n  GetCustomEventType,\n  GetInterruptType,\n  GetConfigurableType,\n  SubagentStreamInterface,\n} from \"./types.js\";\n\n/**\n * Create a custom transport thread state.\n * @param values - The values to use.\n * @param threadId - The ID of the thread to use.\n * @returns The custom transport thread state.\n */\nfunction createCustomTransportThreadState<\n  StateType extends Record<string, unknown>,\n>(values: StateType, threadId: string): ThreadState<StateType> {\n  return {\n    values,\n    next: [],\n    tasks: [],\n    metadata: undefined,\n    created_at: null,\n    checkpoint: {\n      thread_id: threadId,\n      checkpoint_id: null,\n      checkpoint_ns: \"\",\n      checkpoint_map: null,\n    },\n    parent_checkpoint: null,\n  };\n}\n\n/**\n * Framework-agnostic orchestrator for custom transport streams.\n *\n * Encapsulates all business logic shared across React, Vue, Svelte, and Angular\n * for custom transport (non-LGP) streaming.\n */\nexport class CustomStreamOrchestrator<\n  StateType extends Record<string, unknown> = Record<string, unknown>,\n  Bag extends BagTemplate = BagTemplate,\n> {\n  readonly stream: StreamManager<StateType, Bag>;\n\n  readonly messageManager: MessageTupleManager;\n\n  readonly #options: AnyStreamCustomOptions<StateType, Bag>;\n\n  readonly #historyValues: StateType;\n\n  #threadId: string | null;\n\n  #branch: string = \"\";\n\n  #listeners = new Set<() => void>();\n\n  #version = 0;\n\n  #streamUnsub: (() => void) | null = null;\n\n  #disposed = false;\n\n  #handledHeadlessToolInterruptIds = new Set<string>();\n\n  /**\n   * Create a new {@link CustomStreamOrchestrator} instance.\n   *\n   * @param options - Configuration options for the custom transport stream,\n   *   including thread ID, transport, callbacks, and subagent settings.\n   */\n  constructor(options: AnyStreamCustomOptions<StateType, Bag>) {\n    this.#options = options;\n\n    this.#threadId = options.threadId ?? null;\n\n    this.messageManager = new MessageTupleManager();\n    this.stream = new StreamManager<StateType, Bag>(this.messageManager, {\n      throttle: options.throttle ?? false,\n      subagentToolNames: options.subagentToolNames,\n      filterSubagentMessages: options.filterSubagentMessages,\n      toMessage: options.toMessage ?? toMessageClass,\n    });\n\n    this.#historyValues = options.initialValues ?? ({} as StateType);\n\n    this.#streamUnsub = this.stream.subscribe(() => {\n      this.#flushPendingHeadlessToolInterrupts();\n      this.#notify();\n    });\n\n    const historyMessages = this.#getMessages(this.#historyValues);\n    if (\n      options.filterSubagentMessages &&\n      !this.stream.isLoading &&\n      historyMessages.length > 0\n    ) {\n      this.stream.reconstructSubagents(historyMessages, {\n        skipIfPopulated: true,\n      });\n    }\n  }\n\n  /**\n   * Register a listener that is called whenever the orchestrator state changes.\n   *\n   * @param listener - Callback invoked on each state change.\n   * @returns An unsubscribe function that removes the listener.\n   */\n  subscribe = (listener: () => void): (() => void) => {\n    this.#listeners.add(listener);\n    return () => {\n      this.#listeners.delete(listener);\n    };\n  };\n\n  /**\n   * Return the current version number, incremented on each state change.\n   * Useful as a cache key for external sync (e.g. `useSyncExternalStore`).\n   *\n   * @returns The current version counter.\n   */\n  getSnapshot = (): number => this.#version;\n\n  /**\n   * Custom transports do not negotiate stream modes with the server the way\n   * LangGraph Platform streams do, but framework adapters call this method on\n   * both orchestrator variants. Keep the API surface aligned as a no-op.\n   */\n  trackStreamMode(..._modes: StreamMode[]): void {}\n\n  #notify(): void {\n    if (this.#disposed) return;\n    this.#version += 1;\n    for (const listener of this.#listeners) {\n      listener();\n    }\n  }\n\n  /**\n   * Synchronize the external thread ID with the orchestrator.\n   * If the ID has changed, the current stream is cleared and listeners\n   * are notified.\n   *\n   * @param newId - The new thread ID, or `null` to clear.\n   */\n  syncThreadId(newId: string | null): void {\n    if (newId !== this.#threadId) {\n      this.#threadId = newId;\n      this.#handledHeadlessToolInterruptIds.clear();\n      this.stream.clear();\n      this.#notify();\n    }\n  }\n\n  #getMessages = (value: StateType): Message[] => {\n    const messagesKey = this.#options.messagesKey ?? \"messages\";\n    return Array.isArray(value[messagesKey])\n      ? (value[messagesKey] as Message[])\n      : [];\n  };\n\n  #setMessages = (current: StateType, messages: Message[]): StateType => {\n    const messagesKey = this.#options.messagesKey ?? \"messages\";\n    return { ...current, [messagesKey]: messages };\n  };\n\n  /**\n   * The current stream state values, falling back to an empty object\n   * when no stream values are available.\n   */\n  get values(): StateType {\n    return this.stream.values ?? ({} as StateType);\n  }\n\n  /**\n   * The raw stream state values, or `null` if no stream has been started\n   * or values have not yet been received.\n   */\n  get streamValues(): StateType | null {\n    return this.stream.values;\n  }\n\n  /** The most recent stream error, or `undefined` if no error occurred. */\n  get error(): unknown {\n    return this.stream.error;\n  }\n\n  /** Whether a stream is currently in progress. */\n  get isLoading(): boolean {\n    return this.stream.isLoading;\n  }\n\n  /** The current branch identifier. */\n  get branch(): string {\n    return this.#branch;\n  }\n\n  /**\n   * Update the current branch and notify listeners.\n   *\n   * @param value - The new branch identifier.\n   */\n  setBranch(value: string): void {\n    this.#branch = value;\n    this.#notify();\n  }\n\n  /**\n   * All messages from the current stream values, converted to\n   * {@link BaseMessage} instances. Returns an empty array when no\n   * stream values are available.\n   */\n  get messages(): BaseMessage[] {\n    if (!this.stream.values) return [];\n    return ensureMessageInstances(\n      this.#getMessages(this.stream.values)\n    ) as BaseMessage[];\n  }\n\n  /**\n   * All tool calls paired with their results extracted from the\n   * current stream messages.\n   */\n  get toolCalls() {\n    if (!this.stream.values) return [];\n    return getToolCallsWithResults(this.#getMessages(this.stream.values));\n  }\n\n  /**\n   * Get tool calls (with results) that belong to a specific AI message.\n   *\n   * @param message - The AI message whose tool calls to retrieve.\n   * @returns Tool calls associated with the given message.\n   */\n  getToolCalls(message: Message) {\n    if (!this.stream.values) return [];\n    const allToolCalls = getToolCallsWithResults(\n      this.#getMessages(this.stream.values)\n    );\n    return allToolCalls.filter((tc) => tc.aiMessage.id === message.id);\n  }\n\n  /**\n   * All active interrupts from the current stream values.\n   * Returns a single breakpoint interrupt when the interrupt array is\n   * present but empty, or an empty array when no interrupts exist.\n   */\n  get interrupts(): Interrupt<GetInterruptType<Bag>>[] {\n    if (\n      this.stream.values != null &&\n      \"__interrupt__\" in this.stream.values &&\n      Array.isArray(this.stream.values.__interrupt__)\n    ) {\n      return userFacingInterruptsFromValuesArray<GetInterruptType<Bag>>(\n        this.stream.values.__interrupt__ as Interrupt<GetInterruptType<Bag>>[]\n      );\n    }\n    return [];\n  }\n\n  /**\n   * The first active interrupt extracted from the current stream values,\n   * or `undefined` if there are no interrupts.\n   */\n  get interrupt(): Interrupt<GetInterruptType<Bag>> | undefined {\n    return extractInterrupts<GetInterruptType<Bag>>(this.stream.values);\n  }\n\n  /**\n   * Retrieve stream-level metadata for a given message.\n   *\n   * @param message - The message to look up metadata for.\n   * @param index - Optional positional index used as fallback message ID.\n   * @returns The metadata associated with the message, or `undefined`\n   *   if no stream metadata is available.\n   */\n  getMessagesMetadata(\n    message: Message,\n    index?: number\n  ): MessageMetadata<StateType> | undefined {\n    const streamMetadata = this.messageManager.get(message.id)?.metadata;\n    if (streamMetadata != null) {\n      return {\n        messageId: message.id ?? String(index),\n        firstSeenState: undefined,\n        branch: undefined,\n        branchOptions: undefined,\n        streamMetadata,\n      } as MessageMetadata<StateType>;\n    }\n    return undefined;\n  }\n\n  /** A map of all tracked subagent streams, keyed by tool call ID. */\n  get subagents(): Map<string, SubagentStreamInterface> {\n    return this.stream.getSubagents();\n  }\n\n  /** The subset of subagent streams that are currently active (loading). */\n  get activeSubagents(): SubagentStreamInterface[] {\n    return this.stream.getActiveSubagents();\n  }\n\n  /**\n   * Look up a single subagent stream by its tool call ID.\n   *\n   * @param toolCallId - The tool call ID that initiated the subagent.\n   * @returns The subagent stream, or `undefined` if not found.\n   */\n  getSubagent(toolCallId: string) {\n    return this.stream.getSubagent(toolCallId);\n  }\n\n  /**\n   * Retrieve all subagent streams matching a given tool name / type.\n   *\n   * @param type - The subagent type (tool name) to filter by.\n   * @returns An array of matching subagent streams.\n   */\n  getSubagentsByType(type: string) {\n    return this.stream.getSubagentsByType(type);\n  }\n\n  /**\n   * Retrieve all subagent streams associated with a specific AI message.\n   *\n   * @param messageId - The ID of the parent AI message.\n   * @returns An array of subagent streams linked to the message.\n   */\n  getSubagentsByMessage(messageId: string) {\n    return this.stream.getSubagentsByMessage(messageId);\n  }\n\n  /**\n   * Reconstruct subagent streams from history values when subagent\n   * filtering is enabled and the stream is not currently loading.\n   * This is a no-op if subagents are already populated.\n   */\n  reconstructSubagentsIfNeeded(): void {\n    const hvMessages = this.#getMessages(this.#historyValues);\n    if (\n      this.#options.filterSubagentMessages &&\n      !this.stream.isLoading &&\n      hvMessages.length > 0\n    ) {\n      this.stream.reconstructSubagents(hvMessages, { skipIfPopulated: true });\n    }\n  }\n\n  /**\n   * Abort the current stream and invoke the `onStop` callback\n   * if one was provided in the options.\n   */\n  stop(): void {\n    void this.stream.stop(this.#historyValues, {\n      onStop: this.#options.onStop,\n    });\n  }\n\n  /**\n   * Switch to a different thread. If the thread ID actually changed,\n   * the current stream is cleared and listeners are notified.\n   *\n   * @param newThreadId - The thread ID to switch to, or `null` to clear.\n   */\n  switchThread(newThreadId: string | null): void {\n    if (newThreadId !== this.#threadId) {\n      this.#threadId = newThreadId;\n      this.#handledHeadlessToolInterruptIds.clear();\n      this.stream.clear();\n      this.#notify();\n    }\n  }\n\n  /**\n   * Start a new stream run against the custom transport.\n   *\n   * This is the low-level submit entry point that handles thread ID\n   * resolution, optimistic value merging, and transport invocation.\n   * Prefer {@link submit} unless you need to bypass higher-level wrappers.\n   *\n   * @param values - The input values to send, or `null`/`undefined` for\n   *   a resume-style invocation.\n   * @param submitOptions - Optional per-call overrides such as\n   *   `optimisticValues`, `config`, `command`, and error callbacks.\n   */\n  async submitDirect(\n    values: GetUpdateType<Bag, StateType> | null | undefined,\n    submitOptions?: CustomSubmitOptions<StateType, GetConfigurableType<Bag>>\n  ): Promise<void> {\n    type UpdateType = GetUpdateType<Bag, StateType>;\n    type CustomType = GetCustomEventType<Bag>;\n\n    const currentThreadId = this.#options.threadId ?? null;\n    if (currentThreadId !== this.#threadId) {\n      this.#threadId = currentThreadId;\n      this.stream.clear();\n    }\n\n    let usableThreadId = this.#threadId ?? submitOptions?.threadId;\n\n    this.stream.setStreamValues(() => {\n      if (submitOptions?.optimisticValues != null) {\n        return {\n          ...this.#historyValues,\n          ...(typeof submitOptions.optimisticValues === \"function\"\n            ? submitOptions.optimisticValues(this.#historyValues)\n            : submitOptions.optimisticValues),\n        };\n      }\n\n      return { ...this.#historyValues };\n    });\n\n    await this.stream.start(\n      async (signal: AbortSignal) => {\n        if (!usableThreadId) {\n          usableThreadId = crypto.randomUUID();\n          this.#threadId = usableThreadId;\n          this.#options.onThreadId?.(usableThreadId);\n        }\n\n        if (!usableThreadId) {\n          throw new Error(\"Failed to obtain valid thread ID.\");\n        }\n\n        return this.#options.transport.stream({\n          input: values,\n          context: submitOptions?.context,\n          command: submitOptions?.command,\n          streamSubgraphs: submitOptions?.streamSubgraphs,\n          signal,\n          config: {\n            ...submitOptions?.config,\n            configurable: {\n              thread_id: usableThreadId,\n              ...submitOptions?.config?.configurable,\n            } as unknown as GetConfigurableType<Bag>,\n          },\n        }) as Promise<\n          AsyncGenerator<EventStreamEvent<StateType, UpdateType, CustomType>>\n        >;\n      },\n      {\n        getMessages: this.#getMessages,\n        setMessages: this.#setMessages,\n        initialValues: {} as StateType,\n        callbacks: this.#options,\n        onSuccess: () => {\n          if (!usableThreadId) return undefined;\n\n          const finalValues = this.stream.values ?? this.#historyValues;\n          this.#options.onFinish?.(\n            createCustomTransportThreadState(finalValues, usableThreadId),\n            undefined\n          );\n\n          return undefined;\n        },\n        onError: (error) => {\n          this.#options.onError?.(error, undefined);\n          submitOptions?.onError?.(error, undefined);\n        },\n      }\n    );\n  }\n\n  /**\n   * Submit input values and start a new stream run.\n   *\n   * Delegates to {@link submitDirect}. Override or wrap this method\n   * in framework adapters to add queuing or other middleware.\n   *\n   * @param values - The input values to send, or `null`/`undefined` for\n   *   a resume-style invocation.\n   * @param submitOptions - Optional per-call overrides.\n   */\n  async submit(\n    values: GetUpdateType<Bag, StateType> | null | undefined,\n    submitOptions?: CustomSubmitOptions<StateType, GetConfigurableType<Bag>>\n  ): Promise<void> {\n    await this.submitDirect(values, submitOptions);\n  }\n\n  /**\n   * Tear down the orchestrator. Marks the instance as disposed,\n   * unsubscribes from the stream, and aborts any in-progress stream.\n   * After calling this method, no further notifications will be emitted.\n   */\n  dispose(): void {\n    this.#disposed = true;\n    this.#streamUnsub?.();\n    this.#streamUnsub = null;\n    void this.stream.stop(this.#historyValues, {\n      onStop: this.#options.onStop,\n    });\n  }\n\n  #flushPendingHeadlessToolInterrupts(): void {\n    flushPendingHeadlessToolInterrupts(\n      this.stream.values as Record<string, unknown> | null,\n      this.#options.tools,\n      this.#handledHeadlessToolInterruptIds,\n      {\n        onTool: this.#options.onTool,\n        defer: (run) => {\n          void Promise.resolve().then(run);\n        },\n        resumeSubmit: (command) =>\n          this.submit(null, {\n            command,\n          }),\n      }\n    );\n  }\n}\n"],"mappings":"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"}