{"version":3,"file":"subagents.cjs","names":["#session","#messagesIterable","MultiCursorBuffer","StreamingMessageAssembler","#startProjection","#toolCallsIterable","ToolCallAssembler","toClientAssembledToolCall","#ensureMediaDispatcher","#audioBuffer","#imagesBuffer","#videoBuffer","#filesBuffer","#mediaDispatcherStarted","MediaAssembler","#subgraphsIterable","SubgraphDiscoveryHandle","#source","#queue","#waiters","#pending","#sourcePump","#processEvent","#closed","#start"],"sources":["../../../../src/client/stream/handles/subagents.ts"],"sourcesContent":["import type {\n  Channel,\n  Event,\n  MessagesEvent,\n  SubscribeParams,\n  ToolsEvent,\n} from \"@langchain/protocol\";\nimport type { SubscriptionHandle } from \"../index.js\";\nimport { MultiCursorBuffer } from \"../multi-cursor-buffer.js\";\nimport { StreamingMessageAssembler } from \"../messages.js\";\nimport type { StreamingMessage, StreamingMessageHandle } from \"../messages.js\";\nimport { ToolCallAssembler, toClientAssembledToolCall } from \"./tools.js\";\nimport type { ClientAssembledToolCall } from \"./tools.js\";\nimport { MediaAssembler } from \"../media.js\";\nimport type {\n  AudioMedia,\n  FileMedia,\n  ImageMedia,\n  VideoMedia,\n} from \"../media.js\";\nimport type {\n  EventForChannel,\n  EventForChannels,\n  SubscribeOptions,\n  YieldForChannel,\n  YieldForChannels,\n} from \"../types.js\";\nimport {\n  type Subscribable,\n  type SubgraphHandle,\n  SubgraphDiscoveryHandle,\n} from \"./subgraphs.js\";\n\n/**\n * Discovered subagent within a streaming session. Mirrors the\n * in-process `SubagentRunStream` from DeepAgent.\n *\n * Each subagent is discovered when a `tool-started` event with\n * `tool_name === \"task\"` is observed. The `taskInput` and `output`\n * promises resolve from the task tool's lifecycle events.\n *\n * Use lazy getters (`sub.messages`, `sub.toolCalls`, etc.) for\n * namespace-scoped projections.\n */\nexport class SubagentHandle {\n  readonly name: string;\n  readonly callId: string;\n  readonly taskInput: Promise<string>;\n  readonly output: Promise<unknown>;\n  readonly namespace: string[];\n  readonly #session: Subscribable;\n\n  #messagesIterable?: AsyncIterable<StreamingMessage>;\n  #toolCallsIterable?: AsyncIterable<ClientAssembledToolCall>;\n  #subgraphsIterable?: AsyncIterable<SubgraphHandle>;\n\n  #mediaDispatcherStarted = false;\n  #audioBuffer?: MultiCursorBuffer<AudioMedia>;\n  #imagesBuffer?: MultiCursorBuffer<ImageMedia>;\n  #videoBuffer?: MultiCursorBuffer<VideoMedia>;\n  #filesBuffer?: MultiCursorBuffer<FileMedia>;\n\n  constructor(\n    name: string,\n    callId: string,\n    namespace: string[],\n    taskInput: Promise<string>,\n    output: Promise<unknown>,\n    session: Subscribable\n  ) {\n    this.name = name;\n    this.callId = callId;\n    this.namespace = namespace;\n    this.taskInput = taskInput;\n    this.output = output;\n    this.#session = session;\n  }\n\n  get messages(): AsyncIterable<StreamingMessageHandle> {\n    if (this.#messagesIterable) return this.#messagesIterable;\n    const buffer = new MultiCursorBuffer<StreamingMessage>();\n    this.#messagesIterable = buffer;\n    const assembler = new StreamingMessageAssembler();\n    void this.#startProjection(\n      [\"messages\"],\n      (event) => {\n        if (event.method !== \"messages\") return;\n        const msg = assembler.consume(event as MessagesEvent);\n        if (msg) buffer.push(msg);\n      },\n      () => buffer.close()\n    );\n    return buffer;\n  }\n\n  get toolCalls(): AsyncIterable<ClientAssembledToolCall> {\n    if (this.#toolCallsIterable) return this.#toolCallsIterable;\n    const buffer = new MultiCursorBuffer<ClientAssembledToolCall>();\n    this.#toolCallsIterable = buffer;\n    const assembler = new ToolCallAssembler();\n    void this.#startProjection(\n      [\"tools\"],\n      (event) => {\n        if (event.method !== \"tools\") return;\n        const tc = assembler.consume(event as ToolsEvent);\n        if (tc) buffer.push(toClientAssembledToolCall(tc));\n      },\n      () => buffer.close()\n    );\n    return buffer;\n  }\n\n  get audio(): AsyncIterable<AudioMedia> {\n    this.#ensureMediaDispatcher();\n    return this.#audioBuffer!;\n  }\n\n  get images(): AsyncIterable<ImageMedia> {\n    this.#ensureMediaDispatcher();\n    return this.#imagesBuffer!;\n  }\n\n  get video(): AsyncIterable<VideoMedia> {\n    this.#ensureMediaDispatcher();\n    return this.#videoBuffer!;\n  }\n\n  get files(): AsyncIterable<FileMedia> {\n    this.#ensureMediaDispatcher();\n    return this.#filesBuffer!;\n  }\n\n  #ensureMediaDispatcher(): void {\n    if (this.#mediaDispatcherStarted) return;\n    this.#mediaDispatcherStarted = true;\n    const audio = new MultiCursorBuffer<AudioMedia>();\n    const images = new MultiCursorBuffer<ImageMedia>();\n    const video = new MultiCursorBuffer<VideoMedia>();\n    const files = new MultiCursorBuffer<FileMedia>();\n    this.#audioBuffer = audio;\n    this.#imagesBuffer = images;\n    this.#videoBuffer = video;\n    this.#filesBuffer = files;\n    const assembler = new MediaAssembler({\n      onAudio: (m: AudioMedia) => audio.push(m),\n      onImage: (m: ImageMedia) => images.push(m),\n      onVideo: (m: VideoMedia) => video.push(m),\n      onFile: (m: FileMedia) => files.push(m),\n    });\n    void this.#startProjection(\n      [\"messages\"],\n      (event) => {\n        if (event.method !== \"messages\") return;\n        assembler.consume(event as MessagesEvent);\n      },\n      () => {\n        assembler.close();\n        audio.close();\n        images.close();\n        video.close();\n        files.close();\n      }\n    );\n  }\n\n  get subgraphs(): AsyncIterable<SubgraphHandle> {\n    if (this.#subgraphsIterable) return this.#subgraphsIterable;\n    const buffer = new MultiCursorBuffer<SubgraphHandle>();\n    this.#subgraphsIterable = buffer;\n    void (async () => {\n      const rawHandle = await this.#session.subscribe({\n        channels: [\"lifecycle\"],\n        namespaces: [this.namespace],\n      });\n      const discovery = new SubgraphDiscoveryHandle(\n        rawHandle,\n        this.#session,\n        this.namespace\n      );\n      for await (const sub of discovery) {\n        buffer.push(sub);\n      }\n      buffer.close();\n    })();\n    return buffer;\n  }\n\n  /**\n   * Create a raw channel subscription scoped to this subagent's namespace.\n   */\n  subscribe<TChannel extends Channel>(\n    channel: TChannel,\n    options?: SubscribeOptions\n  ): Promise<\n    SubscriptionHandle<EventForChannel<TChannel>, YieldForChannel<TChannel>>\n  >;\n  subscribe<const TChannels extends readonly Channel[]>(\n    channels: TChannels,\n    options?: SubscribeOptions\n  ): Promise<\n    SubscriptionHandle<EventForChannels<TChannels>, YieldForChannels<TChannels>>\n  >;\n  subscribe(params: SubscribeParams): Promise<SubscriptionHandle<Event>>;\n  subscribe(\n    paramsOrChannels: SubscribeParams | Channel | string | readonly Channel[],\n    options: SubscribeOptions = {}\n    // eslint-disable-next-line @typescript-eslint/no-explicit-any\n  ): Promise<any> {\n    if (\n      typeof paramsOrChannels === \"object\" &&\n      !Array.isArray(paramsOrChannels) &&\n      \"channels\" in paramsOrChannels\n    ) {\n      return this.#session.subscribe({\n        ...paramsOrChannels,\n        namespaces: paramsOrChannels.namespaces ?? [this.namespace],\n      });\n    }\n\n    return this.#session.subscribe(paramsOrChannels as Channel, {\n      ...options,\n      namespaces: options.namespaces ?? [this.namespace],\n    });\n  }\n\n  async #startProjection(\n    channels: Channel[],\n    onEvent: (event: Event) => void,\n    onDone: () => void\n  ): Promise<void> {\n    try {\n      const rawHandle = await this.#session.subscribe({\n        channels,\n        namespaces: [this.namespace],\n      });\n      for await (const event of rawHandle) {\n        onEvent(event);\n      }\n    } finally {\n      onDone();\n    }\n  }\n}\n\n/**\n * Async iterable that yields {@link SubagentHandle} instances as task\n * tool calls are discovered from the `tools` channel.\n *\n * Mirrors the in-process `createSubagentTransformer` from DeepAgent:\n * watches for `tool_name === \"task\"` with `tool-started`, extracts\n * `subagent_type` and `description` from the input, and resolves\n * `output` on `tool-finished`.\n */\nexport class SubagentDiscoveryHandle implements AsyncIterable<SubagentHandle> {\n  readonly #source: SubscriptionHandle<Event>;\n  readonly #session: Subscribable;\n  readonly #queue: SubagentHandle[] = [];\n  readonly #waiters: Array<(value: IteratorResult<SubagentHandle>) => void> =\n    [];\n  readonly #pending = new Map<\n    string,\n    {\n      resolveOutput: (v: unknown) => void;\n      rejectOutput: (e: unknown) => void;\n    }\n  >();\n  #sourcePump?: Promise<void>;\n  #closed = false;\n\n  constructor(source: SubscriptionHandle<Event>, session: Subscribable) {\n    this.#source = source;\n    this.#session = session;\n  }\n\n  #processEvent(event: Event): SubagentHandle | undefined {\n    if (event.method !== \"tools\") return undefined;\n    const tools = event as ToolsEvent;\n    const data = tools.params.data;\n    const toolCallId = (data as Record<string, unknown>).tool_call_id as string;\n    const toolName = (data as Record<string, unknown>).tool_name as string;\n\n    if (toolName === \"task\" && data.event === \"tool-started\") {\n      const rawInput = (data as Record<string, unknown>).input;\n      const input: { description?: string; subagent_type?: string } =\n        typeof rawInput === \"string\"\n          ? JSON.parse(rawInput)\n          : ((rawInput as Record<string, unknown>) ?? {});\n\n      const name = input.subagent_type ?? \"unknown\";\n      const description = input.description ?? \"\";\n\n      let resolveTaskInput!: (v: string) => void;\n      let resolveOutput!: (v: unknown) => void;\n      let rejectOutput!: (e: unknown) => void;\n\n      const taskInput = new Promise<string>((r) => {\n        resolveTaskInput = r;\n      });\n      const output = new Promise<unknown>((res, rej) => {\n        resolveOutput = res;\n        rejectOutput = rej;\n      });\n\n      resolveTaskInput(description);\n      this.#pending.set(toolCallId, { resolveOutput, rejectOutput });\n\n      const namespace = [...tools.params.namespace];\n\n      return new SubagentHandle(\n        name,\n        toolCallId,\n        namespace,\n        taskInput,\n        output,\n        this.#session\n      );\n    }\n\n    if (toolCallId) {\n      const pending = this.#pending.get(toolCallId);\n      if (pending) {\n        if (data.event === \"tool-finished\") {\n          pending.resolveOutput((data as Record<string, unknown>).output);\n          this.#pending.delete(toolCallId);\n        } else if (data.event === \"tool-error\") {\n          const message =\n            ((data as Record<string, unknown>).message as string) ??\n            \"unknown error\";\n          pending.rejectOutput(new Error(message));\n          this.#pending.delete(toolCallId);\n        }\n      }\n    }\n\n    return undefined;\n  }\n\n  #start(): void {\n    if (this.#sourcePump) return;\n    this.#sourcePump = (async () => {\n      for await (const event of this.#source) {\n        const handle = this.#processEvent(event);\n        if (!handle) continue;\n\n        const waiter = this.#waiters.shift();\n        if (waiter) {\n          waiter({ done: false, value: handle });\n        } else {\n          this.#queue.push(handle);\n        }\n      }\n      this.#closed = true;\n      for (const pending of this.#pending.values()) {\n        pending.resolveOutput(undefined);\n      }\n      this.#pending.clear();\n      while (this.#waiters.length > 0) {\n        this.#waiters.shift()?.({ done: true, value: undefined });\n      }\n    })();\n  }\n\n  async close(): Promise<void> {\n    this.#closed = true;\n    await this.#source.unsubscribe();\n  }\n\n  [Symbol.asyncIterator](): AsyncIterator<SubagentHandle> {\n    this.#start();\n    return {\n      next: async () => {\n        if (this.#queue.length > 0) {\n          return { done: false, value: this.#queue.shift()! };\n        }\n        if (this.#closed) {\n          return { done: true, value: undefined };\n        }\n        return await new Promise<IteratorResult<SubagentHandle>>((resolve) => {\n          this.#waiters.push(resolve);\n        });\n      },\n      return: async () => {\n        await this.close();\n        return { done: true, value: undefined };\n      },\n    };\n  }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AA4CA,IAAa,iBAAb,MAA4B;CAC1B;CACA;CACA;CACA;CACA;CACA;CAEA;CACA;CACA;CAEA,0BAA0B;CAC1B;CACA;CACA;CACA;CAEA,YACE,MACA,QACA,WACA,WACA,QACA,SACA;AACA,OAAK,OAAO;AACZ,OAAK,SAAS;AACd,OAAK,YAAY;AACjB,OAAK,YAAY;AACjB,OAAK,SAAS;AACd,QAAA,UAAgB;;CAGlB,IAAI,WAAkD;AACpD,MAAI,MAAA,iBAAwB,QAAO,MAAA;EACnC,MAAM,SAAS,IAAIE,4BAAAA,mBAAqC;AACxD,QAAA,mBAAyB;EACzB,MAAM,YAAY,IAAIC,iBAAAA,2BAA2B;AAC5C,QAAA,gBACH,CAAC,WAAW,GACX,UAAU;AACT,OAAI,MAAM,WAAW,WAAY;GACjC,MAAM,MAAM,UAAU,QAAQ,MAAuB;AACrD,OAAI,IAAK,QAAO,KAAK,IAAI;WAErB,OAAO,OAAO,CACrB;AACD,SAAO;;CAGT,IAAI,YAAoD;AACtD,MAAI,MAAA,kBAAyB,QAAO,MAAA;EACpC,MAAM,SAAS,IAAID,4BAAAA,mBAA4C;AAC/D,QAAA,oBAA0B;EAC1B,MAAM,YAAY,IAAII,cAAAA,mBAAmB;AACpC,QAAA,gBACH,CAAC,QAAQ,GACR,UAAU;AACT,OAAI,MAAM,WAAW,QAAS;GAC9B,MAAM,KAAK,UAAU,QAAQ,MAAoB;AACjD,OAAI,GAAI,QAAO,KAAKC,cAAAA,0BAA0B,GAAG,CAAC;WAE9C,OAAO,OAAO,CACrB;AACD,SAAO;;CAGT,IAAI,QAAmC;AACrC,QAAA,uBAA6B;AAC7B,SAAO,MAAA;;CAGT,IAAI,SAAoC;AACtC,QAAA,uBAA6B;AAC7B,SAAO,MAAA;;CAGT,IAAI,QAAmC;AACrC,QAAA,uBAA6B;AAC7B,SAAO,MAAA;;CAGT,IAAI,QAAkC;AACpC,QAAA,uBAA6B;AAC7B,SAAO,MAAA;;CAGT,yBAA+B;AAC7B,MAAI,MAAA,uBAA8B;AAClC,QAAA,yBAA+B;EAC/B,MAAM,QAAQ,IAAIL,4BAAAA,mBAA+B;EACjD,MAAM,SAAS,IAAIA,4BAAAA,mBAA+B;EAClD,MAAM,QAAQ,IAAIA,4BAAAA,mBAA+B;EACjD,MAAM,QAAQ,IAAIA,4BAAAA,mBAA8B;AAChD,QAAA,cAAoB;AACpB,QAAA,eAAqB;AACrB,QAAA,cAAoB;AACpB,QAAA,cAAoB;EACpB,MAAM,YAAY,IAAIY,cAAAA,eAAe;GACnC,UAAU,MAAkB,MAAM,KAAK,EAAE;GACzC,UAAU,MAAkB,OAAO,KAAK,EAAE;GAC1C,UAAU,MAAkB,MAAM,KAAK,EAAE;GACzC,SAAS,MAAiB,MAAM,KAAK,EAAE;GACxC,CAAC;AACG,QAAA,gBACH,CAAC,WAAW,GACX,UAAU;AACT,OAAI,MAAM,WAAW,WAAY;AACjC,aAAU,QAAQ,MAAuB;WAErC;AACJ,aAAU,OAAO;AACjB,SAAM,OAAO;AACb,UAAO,OAAO;AACd,SAAM,OAAO;AACb,SAAM,OAAO;IAEhB;;CAGH,IAAI,YAA2C;AAC7C,MAAI,MAAA,kBAAyB,QAAO,MAAA;EACpC,MAAM,SAAS,IAAIZ,4BAAAA,mBAAmC;AACtD,QAAA,oBAA0B;AAC1B,GAAM,YAAY;GAKhB,MAAM,YAAY,IAAIc,kBAAAA,wBAJJ,MAAM,MAAA,QAAc,UAAU;IAC9C,UAAU,CAAC,YAAY;IACvB,YAAY,CAAC,KAAK,UAAU;IAC7B,CAAC,EAGA,MAAA,SACA,KAAK,UACN;AACD,cAAW,MAAM,OAAO,UACtB,QAAO,KAAK,IAAI;AAElB,UAAO,OAAO;MACZ;AACJ,SAAO;;CAmBT,UACE,kBACA,UAA4B,EAAE,EAEhB;AACd,MACE,OAAO,qBAAqB,YAC5B,CAAC,MAAM,QAAQ,iBAAiB,IAChC,cAAc,iBAEd,QAAO,MAAA,QAAc,UAAU;GAC7B,GAAG;GACH,YAAY,iBAAiB,cAAc,CAAC,KAAK,UAAU;GAC5D,CAAC;AAGJ,SAAO,MAAA,QAAc,UAAU,kBAA6B;GAC1D,GAAG;GACH,YAAY,QAAQ,cAAc,CAAC,KAAK,UAAU;GACnD,CAAC;;CAGJ,OAAA,gBACE,UACA,SACA,QACe;AACf,MAAI;GACF,MAAM,YAAY,MAAM,MAAA,QAAc,UAAU;IAC9C;IACA,YAAY,CAAC,KAAK,UAAU;IAC7B,CAAC;AACF,cAAW,MAAM,SAAS,UACxB,SAAQ,MAAM;YAER;AACR,WAAQ;;;;;;;;;;;;;AAcd,IAAa,0BAAb,MAA8E;CAC5E;CACA;CACA,SAAoC,EAAE;CACtC,WACE,EAAE;CACJ,2BAAoB,IAAI,KAMrB;CACH;CACA,UAAU;CAEV,YAAY,QAAmC,SAAuB;AACpE,QAAA,SAAe;AACf,QAAA,UAAgB;;CAGlB,cAAc,OAA0C;AACtD,MAAI,MAAM,WAAW,QAAS,QAAO,KAAA;EACrC,MAAM,QAAQ;EACd,MAAM,OAAO,MAAM,OAAO;EAC1B,MAAM,aAAc,KAAiC;AAGrD,MAFkB,KAAiC,cAElC,UAAU,KAAK,UAAU,gBAAgB;GACxD,MAAM,WAAY,KAAiC;GACnD,MAAM,QACJ,OAAO,aAAa,WAChB,KAAK,MAAM,SAAS,GAClB,YAAwC,EAAE;GAElD,MAAM,OAAO,MAAM,iBAAiB;GACpC,MAAM,cAAc,MAAM,eAAe;GAEzC,IAAI;GACJ,IAAI;GACJ,IAAI;GAEJ,MAAM,YAAY,IAAI,SAAiB,MAAM;AAC3C,uBAAmB;KACnB;GACF,MAAM,SAAS,IAAI,SAAkB,KAAK,QAAQ;AAChD,oBAAgB;AAChB,mBAAe;KACf;AAEF,oBAAiB,YAAY;AAC7B,SAAA,QAAc,IAAI,YAAY;IAAE;IAAe;IAAc,CAAC;AAI9D,UAAO,IAAI,eACT,MACA,YAJgB,CAAC,GAAG,MAAM,OAAO,UAAU,EAM3C,WACA,QACA,MAAA,QACD;;AAGH,MAAI,YAAY;GACd,MAAM,UAAU,MAAA,QAAc,IAAI,WAAW;AAC7C,OAAI;QACE,KAAK,UAAU,iBAAiB;AAClC,aAAQ,cAAe,KAAiC,OAAO;AAC/D,WAAA,QAAc,OAAO,WAAW;eACvB,KAAK,UAAU,cAAc;KACtC,MAAM,UACF,KAAiC,WACnC;AACF,aAAQ,aAAa,IAAI,MAAM,QAAQ,CAAC;AACxC,WAAA,QAAc,OAAO,WAAW;;;;;CAQxC,SAAe;AACb,MAAI,MAAA,WAAkB;AACtB,QAAA,cAAoB,YAAY;AAC9B,cAAW,MAAM,SAAS,MAAA,QAAc;IACtC,MAAM,SAAS,MAAA,aAAmB,MAAM;AACxC,QAAI,CAAC,OAAQ;IAEb,MAAM,SAAS,MAAA,QAAc,OAAO;AACpC,QAAI,OACF,QAAO;KAAE,MAAM;KAAO,OAAO;KAAQ,CAAC;QAEtC,OAAA,MAAY,KAAK,OAAO;;AAG5B,SAAA,SAAe;AACf,QAAK,MAAM,WAAW,MAAA,QAAc,QAAQ,CAC1C,SAAQ,cAAc,KAAA,EAAU;AAElC,SAAA,QAAc,OAAO;AACrB,UAAO,MAAA,QAAc,SAAS,EAC5B,OAAA,QAAc,OAAO,GAAG;IAAE,MAAM;IAAM,OAAO,KAAA;IAAW,CAAC;MAEzD;;CAGN,MAAM,QAAuB;AAC3B,QAAA,SAAe;AACf,QAAM,MAAA,OAAa,aAAa;;CAGlC,CAAC,OAAO,iBAAgD;AACtD,QAAA,OAAa;AACb,SAAO;GACL,MAAM,YAAY;AAChB,QAAI,MAAA,MAAY,SAAS,EACvB,QAAO;KAAE,MAAM;KAAO,OAAO,MAAA,MAAY,OAAO;KAAG;AAErD,QAAI,MAAA,OACF,QAAO;KAAE,MAAM;KAAM,OAAO,KAAA;KAAW;AAEzC,WAAO,MAAM,IAAI,SAAyC,YAAY;AACpE,WAAA,QAAc,KAAK,QAAQ;MAC3B;;GAEJ,QAAQ,YAAY;AAClB,UAAM,KAAK,OAAO;AAClB,WAAO;KAAE,MAAM;KAAM,OAAO,KAAA;KAAW;;GAE1C"}