{"version":3,"file":"stream.cjs","names":["StreamChannel"],"sources":["../../src/agents/stream.ts"],"sourcesContent":["/* oxlint-disable @typescript-eslint/no-explicit-any */\n\n/**\n * Agent-level streaming support (experimental).\n *\n * Provides native stream transformer factories for tool calls and\n * middleware events.  When marked `__native: true`, their projections\n * are assigned directly onto the `GraphRunStream` instance by\n * `createGraphRunStream` in langgraph-core — no subclass or wrapper\n * needed.\n *\n * See protocol proposal §15 (In-Process Streaming Interface) and §16\n * (Native Stream Transformers).\n */\n\nimport {\n  GraphRunStream,\n  StreamChannel,\n  type NativeStreamTransformer,\n  type ProtocolEvent,\n  type StreamTransformer,\n  type ToolCallStream,\n  type ToolCallStatus,\n  type ToolsEventData,\n  type Namespace,\n} from \"@langchain/langgraph\";\nimport type {\n  ClientTool,\n  ServerTool,\n  DynamicStructuredTool,\n  StructuredToolInterface,\n} from \"@langchain/core/tools\";\n\n/**\n * Infers the merged extensions shape from a tuple of stream transformer\n * factories. Mirrors `InferExtensions` from `@langchain/langgraph`, which\n * is not exported from the package's public surface.\n *\n * Given `[() => StreamTransformer<{ a: number }>, () => StreamTransformer<{ b: string }>]`,\n * produces `{ a: number } & { b: string }`.\n */\nexport type InferStreamExtensions<\n  T extends ReadonlyArray<() => StreamTransformer<any>>,\n> = T extends readonly []\n  ? Record<string, never>\n  : T extends readonly [\n        () => StreamTransformer<infer P>,\n        ...infer Rest extends ReadonlyArray<() => StreamTransformer<any>>,\n      ]\n    ? P & InferStreamExtensions<Rest>\n    : Record<string, unknown>;\n\n/** Extract the literal `name` string from a tool type. */\ntype ToolNameOf<T> = T extends { name: infer N extends string } ? N : string;\n\n/** Extract the parsed input type from a tool type. */\ntype ToolInputOf<T> =\n  T extends DynamicStructuredTool<any, any, infer SchemaInputT, any, any, any>\n    ? SchemaInputT\n    : T extends StructuredToolInterface<any, infer SchemaInputT, any>\n      ? SchemaInputT\n      : unknown;\n\n/** Extract the return/output type from a tool type. */\ntype ToolOutputOf<T> =\n  T extends DynamicStructuredTool<any, any, any, infer ToolOutputT, any, any>\n    ? ToolOutputT\n    : T extends StructuredToolInterface<any, any, infer ToolOutputT>\n      ? ToolOutputT\n      : unknown;\n\n/**\n * Discriminated union of {@link ToolCallStream} variants, one per tool\n * in `TTools`.  Enables TypeScript to narrow `.input` and `.output`\n * when the consumer checks `call.name === \"someToolName\"`.\n *\n * Falls back to `ToolCallStream` (untyped) when the tools tuple is a\n * plain `(ClientTool | ServerTool)[]` without literal name types.\n */\nexport type ToolCallStreamUnion<\n  TTools extends readonly (ClientTool | ServerTool)[],\n> = {\n  [K in keyof TTools]: ToolCallStream<\n    ToolNameOf<TTools[K]>,\n    ToolInputOf<TTools[K]>,\n    ToolOutputOf<TTools[K]>\n  >;\n}[number];\n\n/**\n * A {@link GraphRunStream} with native agent-level projections assigned\n * directly on the instance by `createGraphRunStream` (via `__native`\n * transformers).\n *\n * This is a pure type overlay — no runtime subclass exists.  Use the\n * `AgentRunStream` type when you need to describe the return type of\n * `streamEvents(..., { version: \"v3\" })`.\n *\n * @typeParam TValues - Shape of the graph's state values.\n * @typeParam TTools - Tuple of tools registered on the agent, used to type\n *   the per-tool `toolCalls` discriminated union.\n * @typeParam TMiddleware - Tuple of middleware registered on the agent, used\n *   to type the per-middleware `middleware` event union.\n * @typeParam TExtensions - Shape of `run.extensions` produced by user-supplied\n *   stream transformer factories. Derived via\n *   `InferExtensions<TStreamTransformers>`.\n */\nexport type AgentRunStream<\n  TValues = Record<string, unknown>,\n  TTools extends readonly (ClientTool | ServerTool)[] = readonly (\n    | ClientTool\n    | ServerTool\n  )[],\n  TExtensions extends Record<string, unknown> = Record<string, unknown>,\n> = GraphRunStream<TValues, TExtensions> & {\n  /** Tool call streams from the native ToolCallTransformer. */\n  toolCalls: AsyncIterable<ToolCallStreamUnion<TTools>>;\n};\n\ninterface ToolCallProjection {\n  toolCalls: AsyncIterable<ToolCallStream>;\n}\n\n/**\n * Returns true when `ns` belongs to the agent's own graph — i.e. it\n * starts with `path` and is at most one level deeper (the agent's\n * internal nodes like `tools`, `model_request`, etc.).\n *\n * Events from subagent subgraphs (two or more levels deeper) are\n * excluded, so `run.toolCalls` / `run.middleware` only show events\n * from the agent itself, not from its subagents.\n */\nfunction isOwnEvent(ns: Namespace, path: Namespace): boolean {\n  if (ns.length < path.length || ns.length > path.length + 1) return false;\n  for (let i = 0; i < path.length; i += 1) {\n    if (ns[i] !== path[i]) return false;\n  }\n  return true;\n}\n\nfunction isHeadlessToolInterruptError(\n  message: string,\n  toolCallId: string | undefined\n): boolean {\n  try {\n    const parsed = JSON.parse(message) as unknown;\n    if (!Array.isArray(parsed)) return false;\n    return parsed.some((entry) => {\n      if (entry == null || typeof entry !== \"object\") return false;\n      const value = (entry as { value?: unknown }).value;\n      if (value == null || typeof value !== \"object\") return false;\n      const payload = value as {\n        type?: unknown;\n        toolCall?: { id?: unknown };\n      };\n      return (\n        payload.type === \"tool\" &&\n        (toolCallId == null ||\n          payload.toolCall?.id == null ||\n          payload.toolCall.id === toolCallId)\n      );\n    });\n  } catch {\n    return false;\n  }\n}\n\n/**\n * Creates a native transformer that correlates `tools` channel events\n * into per-call {@link ToolCallStream} objects.\n *\n * Marked `__native: true` — projection keys land directly on the\n * `GraphRunStream` instance as `run.toolCalls`.\n */\nexport function createToolCallTransformer(\n  path: Namespace\n): () => NativeStreamTransformer<ToolCallProjection> {\n  return () => {\n    const toolCallsLog = StreamChannel.local<ToolCallStream>();\n\n    const pendingCalls = new Map<\n      string,\n      {\n        resolveOutput: (v: unknown) => void;\n        rejectOutput: (e: unknown) => void;\n        resolveStatus: (v: ToolCallStatus) => void;\n        resolveError: (v: string | undefined) => void;\n      }\n    >();\n\n    function createToolCallEntry(\n      callId: string,\n      name: string,\n      rawInput: unknown\n    ): void {\n      if (pendingCalls.has(callId)) return;\n      const input =\n        typeof rawInput === \"string\" ? JSON.parse(rawInput) : rawInput;\n\n      let resolveOutput!: (v: unknown) => void;\n      let rejectOutput!: (e: unknown) => void;\n      let resolveStatus!: (v: ToolCallStatus) => void;\n      let resolveError!: (v: string | undefined) => void;\n\n      const output = new Promise<unknown>((res, rej) => {\n        resolveOutput = res;\n        rejectOutput = rej;\n      });\n      const status = new Promise<ToolCallStatus>((res) => {\n        resolveStatus = res;\n      });\n      const error = new Promise<string | undefined>((res) => {\n        resolveError = res;\n      });\n\n      pendingCalls.set(callId, {\n        resolveOutput,\n        rejectOutput,\n        resolveStatus,\n        resolveError,\n      });\n\n      toolCallsLog.push({\n        name,\n        callId,\n        input,\n        output,\n        status,\n        error,\n      } as ToolCallStream);\n    }\n\n    return {\n      __native: true as const,\n\n      init: () => ({\n        toolCalls: toolCallsLog,\n      }),\n\n      process(event: ProtocolEvent): boolean {\n        /**\n         * Only process events that are at the same depth as the agent's graph.\n         */\n        if (!isOwnEvent(event.params.namespace, path)) return true;\n\n        if (event.method === \"messages\") {\n          const data = event.params.data as Record<string, unknown>;\n          if (data.event === \"content-block-finish\") {\n            const cb = (data.contentBlock ?? data.content_block) as\n              | Record<string, unknown>\n              | undefined;\n            if (cb?.type === \"tool_call\") {\n              createToolCallEntry(\n                String(cb.id ?? \"\"),\n                String(cb.name ?? \"\"),\n                cb.args ?? cb.input\n              );\n            }\n          }\n        }\n\n        if (event.method === \"tools\") {\n          const data = event.params.data as ToolsEventData;\n          const toolCallId = (data as Record<string, unknown>)\n            .tool_call_id as string;\n\n          if (data.event === \"tool-started\") {\n            createToolCallEntry(\n              toolCallId,\n              ((data as Record<string, unknown>).tool_name as string) ??\n                \"unknown\",\n              (data as Record<string, unknown>).input\n            );\n          }\n\n          const pending = toolCallId ? pendingCalls.get(toolCallId) : undefined;\n\n          if (pending) {\n            if (data.event === \"tool-finished\") {\n              pending.resolveOutput((data as Record<string, unknown>).output);\n              pending.resolveStatus(\"finished\");\n              pending.resolveError(undefined);\n              pendingCalls.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              if (isHeadlessToolInterruptError(message, toolCallId)) {\n                return true;\n              }\n              pending.rejectOutput(new Error(message));\n              pending.resolveStatus(\"error\");\n              pending.resolveError(message);\n              pendingCalls.delete(toolCallId);\n            }\n          }\n        }\n\n        return true;\n      },\n\n      finalize(): void {\n        for (const pending of pendingCalls.values()) {\n          pending.resolveStatus(\"finished\");\n          pending.resolveError(undefined);\n          pending.resolveOutput(undefined);\n        }\n        pendingCalls.clear();\n        toolCallsLog.close();\n      },\n\n      fail(err: unknown): void {\n        for (const pending of pendingCalls.values()) {\n          pending.resolveStatus(\"error\");\n          pending.resolveError(\n            err instanceof Error ? err.message : String(err)\n          );\n          pending.rejectOutput(err);\n        }\n        pendingCalls.clear();\n        toolCallsLog.fail(err);\n      },\n    };\n  };\n}\n"],"mappings":"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"}