{"version":3,"file":"chat_models.cjs","names":["BaseChatModel","AIMessage","toJsonSchema","ChatGenerationChunk","AIMessageChunk","RunnableLambda"],"sources":["../../../src/utils/testing/chat_models.ts"],"sourcesContent":["import { CallbackManagerForLLMRun } from \"../../callbacks/manager.js\";\nimport {\n  BaseChatModel,\n  BaseChatModelCallOptions,\n  BaseChatModelParams,\n} from \"../../language_models/chat_models.js\";\nimport { BaseLLMParams } from \"../../language_models/llms.js\";\nimport {\n  BaseMessage,\n  AIMessage,\n  AIMessageChunk,\n} from \"../../messages/index.js\";\nimport { type ChatResult, ChatGenerationChunk } from \"../../outputs.js\";\nimport { Runnable, RunnableLambda } from \"../../runnables/base.js\";\nimport { StructuredTool } from \"../../tools/index.js\";\nimport {\n  StructuredOutputMethodParams,\n  BaseLanguageModelInput,\n  StructuredOutputMethodOptions,\n} from \"../../language_models/base.js\";\n\nimport { toJsonSchema } from \"../json_schema.js\";\nimport { InteropZodType } from \"../types/zod.js\";\n\n/** Minimal shape actually needed by `bindTools` */\nexport interface ToolSpec {\n  name: string;\n  description?: string;\n  schema: InteropZodType | Record<string, unknown>; // Either a Zod schema *or* a plain JSON-Schema object\n}\n\n/**\n * Interface specific to the Fake Streaming Chat model.\n */\nexport interface FakeStreamingChatModelCallOptions extends BaseChatModelCallOptions {}\n/**\n * Interface for the Constructor-field specific to the Fake Streaming Chat model (all optional because we fill in defaults).\n */\nexport interface FakeStreamingChatModelFields extends BaseChatModelParams {\n  /** Milliseconds to pause between fallback char-by-char chunks */\n  sleep?: number;\n\n  /** Full AI messages to fall back to when no `chunks` supplied */\n  responses?: BaseMessage[];\n\n  /** Exact chunks to emit (can include tool-call deltas) */\n  chunks?: AIMessageChunk[];\n\n  /** How tool specs are formatted in `bindTools` */\n  toolStyle?: \"openai\" | \"anthropic\" | \"bedrock\" | \"google\";\n\n  /** Throw this error instead of streaming (useful in tests) */\n  thrownErrorString?: string;\n}\n\nexport class FakeChatModel extends BaseChatModel {\n  _combineLLMOutput() {\n    return [];\n  }\n\n  _llmType(): string {\n    return \"fake\";\n  }\n\n  async _generate(\n    messages: BaseMessage[],\n    options?: this[\"ParsedCallOptions\"],\n    runManager?: CallbackManagerForLLMRun\n  ): Promise<ChatResult> {\n    if (options?.stop?.length) {\n      return {\n        generations: [\n          {\n            message: new AIMessage(options.stop[0]),\n            text: options.stop[0],\n          },\n        ],\n      };\n    }\n    const text = messages\n      .map((m) => {\n        if (typeof m.content === \"string\") {\n          return m.content;\n        }\n        return JSON.stringify(m.content, null, 2);\n      })\n      .join(\"\\n\");\n    await runManager?.handleLLMNewToken(text);\n    return {\n      generations: [\n        {\n          message: new AIMessage(text),\n          text,\n        },\n      ],\n      llmOutput: {},\n    };\n  }\n}\n\nexport class FakeStreamingChatModel extends BaseChatModel<FakeStreamingChatModelCallOptions> {\n  sleep = 50;\n\n  responses: BaseMessage[] = [];\n\n  chunks: AIMessageChunk[] = [];\n\n  toolStyle: \"openai\" | \"anthropic\" | \"bedrock\" | \"google\" = \"openai\";\n\n  thrownErrorString?: string;\n\n  private tools: (StructuredTool | ToolSpec)[] = [];\n\n  constructor({\n    sleep = 50,\n    responses = [],\n    chunks = [],\n    toolStyle = \"openai\",\n    thrownErrorString,\n    ...rest\n  }: FakeStreamingChatModelFields & BaseLLMParams) {\n    super(rest);\n    this.sleep = sleep;\n    this.responses = responses;\n    this.chunks = chunks;\n    this.toolStyle = toolStyle;\n    this.thrownErrorString = thrownErrorString;\n  }\n\n  _llmType() {\n    return \"fake\";\n  }\n\n  bindTools(tools: (StructuredTool | ToolSpec)[]) {\n    const merged = [...this.tools, ...tools];\n\n    const toolDicts = merged.map((t) => {\n      switch (this.toolStyle) {\n        case \"openai\":\n          return {\n            type: \"function\",\n            function: {\n              name: t.name,\n              description: t.description,\n              parameters: toJsonSchema(t.schema),\n            },\n          };\n        case \"anthropic\":\n          return {\n            name: t.name,\n            description: t.description,\n            input_schema: toJsonSchema(t.schema),\n          };\n        case \"bedrock\":\n          return {\n            toolSpec: {\n              name: t.name,\n              description: t.description,\n              inputSchema: toJsonSchema(t.schema),\n            },\n          };\n        case \"google\":\n          return {\n            name: t.name,\n            description: t.description,\n            parameters: toJsonSchema(t.schema),\n          };\n        default:\n          throw new Error(`Unsupported tool style: ${this.toolStyle}`);\n      }\n    });\n\n    const wrapped =\n      this.toolStyle === \"google\"\n        ? [{ functionDeclarations: toolDicts }]\n        : toolDicts;\n\n    /* creating a *new* instance – mirrors LangChain .bind semantics for type-safety and avoiding noise */\n    const next = new FakeStreamingChatModel({\n      sleep: this.sleep,\n      responses: this.responses,\n      chunks: this.chunks,\n      toolStyle: this.toolStyle,\n      thrownErrorString: this.thrownErrorString,\n    });\n    next.tools = merged;\n\n    return next.withConfig({ tools: wrapped } as BaseChatModelCallOptions);\n  }\n\n  async _generate(\n    messages: BaseMessage[],\n    _options: this[\"ParsedCallOptions\"],\n    _runManager?: CallbackManagerForLLMRun\n  ): Promise<ChatResult> {\n    if (this.thrownErrorString) {\n      throw new Error(this.thrownErrorString);\n    }\n\n    const content = this.responses?.[0]?.content ?? messages[0].content ?? \"\";\n\n    const generation: ChatResult = {\n      generations: [\n        {\n          text: \"\",\n          message: new AIMessage({\n            content,\n            tool_calls: this.chunks?.[0]?.tool_calls,\n          }),\n        },\n      ],\n    };\n\n    return generation;\n  }\n\n  async *_streamResponseChunks(\n    _messages: BaseMessage[],\n    options: this[\"ParsedCallOptions\"],\n    runManager?: CallbackManagerForLLMRun\n  ): AsyncGenerator<ChatGenerationChunk> {\n    if (this.thrownErrorString) {\n      throw new Error(this.thrownErrorString);\n    }\n    if (this.chunks?.length) {\n      for (const msgChunk of this.chunks) {\n        const cg = new ChatGenerationChunk({\n          message: new AIMessageChunk({\n            content: msgChunk.content,\n            tool_calls: msgChunk.tool_calls,\n            additional_kwargs: msgChunk.additional_kwargs ?? {},\n          }),\n          text: msgChunk.content?.toString() ?? \"\",\n        });\n\n        if (options.signal?.aborted) break;\n        yield cg;\n        await runManager?.handleLLMNewToken(\n          msgChunk.content as string,\n          undefined,\n          undefined,\n          undefined,\n          undefined,\n          { chunk: cg }\n        );\n      }\n      return;\n    }\n\n    const fallback =\n      this.responses?.[0] ??\n      new AIMessage(\n        typeof _messages[0].content === \"string\" ? _messages[0].content : \"\"\n      );\n    const text = typeof fallback.content === \"string\" ? fallback.content : \"\";\n\n    for (const ch of text) {\n      await new Promise((r) => setTimeout(r, this.sleep));\n      const cg = new ChatGenerationChunk({\n        message: new AIMessageChunk({ content: ch }),\n        text: ch,\n      });\n      if (options.signal?.aborted) break;\n      yield cg;\n      await runManager?.handleLLMNewToken(\n        ch,\n        undefined,\n        undefined,\n        undefined,\n        undefined,\n        { chunk: cg }\n      );\n    }\n  }\n}\n\n/**\n * Interface for the input parameters specific to the Fake List Chat model.\n */\nexport interface FakeChatInput extends BaseChatModelParams {\n  /** Responses to return */\n  responses: string[];\n\n  /** Time to sleep in milliseconds between responses */\n  sleep?: number;\n\n  emitCustomEvent?: boolean;\n\n  /**\n   * Generation info to include on the last chunk during streaming.\n   * This gets merged into response_metadata by the base chat model.\n   * Useful for testing response_metadata propagation (e.g., finish_reason).\n   */\n  generationInfo?: Record<string, unknown>;\n}\n\nexport interface FakeListChatModelCallOptions extends BaseChatModelCallOptions {\n  thrownErrorString?: string;\n}\n\n/**\n * A fake Chat Model that returns a predefined list of responses. It can be used\n * for testing purposes.\n * @example\n * ```typescript\n * const chat = new FakeListChatModel({\n *   responses: [\"I'll callback later.\", \"You 'console' them!\"]\n * });\n *\n * const firstMessage = new HumanMessage(\"You want to hear a JavaScript joke?\");\n * const secondMessage = new HumanMessage(\"How do you cheer up a JavaScript developer?\");\n *\n * // Call the chat model with a message and log the response\n * const firstResponse = await chat.call([firstMessage]);\n * console.log({ firstResponse });\n *\n * const secondResponse = await chat.call([secondMessage]);\n * console.log({ secondResponse });\n * ```\n */\nexport class FakeListChatModel extends BaseChatModel<FakeListChatModelCallOptions> {\n  static lc_name() {\n    return \"FakeListChatModel\";\n  }\n\n  lc_serializable = true;\n\n  responses: string[];\n\n  i = 0;\n\n  sleep?: number;\n\n  emitCustomEvent = false;\n\n  generationInfo?: Record<string, unknown>;\n\n  private tools: (StructuredTool | ToolSpec)[] = [];\n\n  toolStyle: \"openai\" | \"anthropic\" | \"bedrock\" | \"google\" = \"openai\";\n\n  constructor(params: FakeChatInput) {\n    super(params);\n    const { responses, sleep, emitCustomEvent, generationInfo } = params;\n    this.responses = responses;\n    this.sleep = sleep;\n    this.emitCustomEvent = emitCustomEvent ?? this.emitCustomEvent;\n    this.generationInfo = generationInfo;\n  }\n\n  _combineLLMOutput() {\n    return [];\n  }\n\n  _llmType(): string {\n    return \"fake-list\";\n  }\n\n  async _generate(\n    _messages: BaseMessage[],\n    options?: this[\"ParsedCallOptions\"],\n    runManager?: CallbackManagerForLLMRun\n  ): Promise<ChatResult> {\n    await this._sleepIfRequested();\n    if (options?.thrownErrorString) {\n      throw new Error(options.thrownErrorString);\n    }\n    if (this.emitCustomEvent) {\n      await runManager?.handleCustomEvent(\"some_test_event\", {\n        someval: true,\n      });\n    }\n\n    if (options?.stop?.length) {\n      return {\n        generations: [this._formatGeneration(options.stop[0])],\n      };\n    } else {\n      const response = this._currentResponse();\n      this._incrementResponse();\n\n      return {\n        generations: [this._formatGeneration(response)],\n        llmOutput: {},\n      };\n    }\n  }\n\n  _formatGeneration(text: string) {\n    return {\n      message: new AIMessage(text),\n      text,\n    };\n  }\n\n  async *_streamResponseChunks(\n    _messages: BaseMessage[],\n    options: this[\"ParsedCallOptions\"],\n    runManager?: CallbackManagerForLLMRun\n  ): AsyncGenerator<ChatGenerationChunk> {\n    const response = this._currentResponse();\n    this._incrementResponse();\n    if (this.emitCustomEvent) {\n      await runManager?.handleCustomEvent(\"some_test_event\", {\n        someval: true,\n      });\n    }\n\n    const responseChars = [...response];\n    for (let i = 0; i < responseChars.length; i++) {\n      const text = responseChars[i];\n      const isLastChunk = i === responseChars.length - 1;\n      await this._sleepIfRequested();\n      if (options?.thrownErrorString) {\n        throw new Error(options.thrownErrorString);\n      }\n      // Include generationInfo on the last chunk (like real providers do)\n      // This gets merged into response_metadata by the base chat model\n      const chunk = this._createResponseChunk(\n        text,\n        isLastChunk ? this.generationInfo : undefined\n      );\n      if (options.signal?.aborted) break;\n      yield chunk;\n      // oxlint-disable-next-line no-void\n      void runManager?.handleLLMNewToken(text);\n    }\n  }\n\n  async _sleepIfRequested() {\n    if (this.sleep !== undefined) {\n      await this._sleep();\n    }\n  }\n\n  async _sleep() {\n    return new Promise<void>((resolve) => {\n      setTimeout(() => resolve(), this.sleep);\n    });\n  }\n\n  _createResponseChunk(\n    text: string,\n    // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n    generationInfo?: Record<string, any>\n  ): ChatGenerationChunk {\n    return new ChatGenerationChunk({\n      message: new AIMessageChunk({ content: text }),\n      text,\n      generationInfo,\n    });\n  }\n\n  _currentResponse() {\n    return this.responses[this.i];\n  }\n\n  _incrementResponse() {\n    if (this.i < this.responses.length - 1) {\n      this.i += 1;\n    } else {\n      this.i = 0;\n    }\n  }\n\n  bindTools(tools: (StructuredTool | ToolSpec)[]) {\n    const merged = [...this.tools, ...tools];\n\n    const toolDicts = merged.map((t) => {\n      switch (this.toolStyle) {\n        case \"openai\":\n          return {\n            type: \"function\",\n            function: {\n              name: t.name,\n              description: t.description,\n              parameters: toJsonSchema(t.schema),\n            },\n          };\n        case \"anthropic\":\n          return {\n            name: t.name,\n            description: t.description,\n            input_schema: toJsonSchema(t.schema),\n          };\n        case \"bedrock\":\n          return {\n            toolSpec: {\n              name: t.name,\n              description: t.description,\n              inputSchema: toJsonSchema(t.schema),\n            },\n          };\n        case \"google\":\n          return {\n            name: t.name,\n            description: t.description,\n            parameters: toJsonSchema(t.schema),\n          };\n        default:\n          throw new Error(`Unsupported tool style: ${this.toolStyle}`);\n      }\n    });\n\n    const wrapped =\n      this.toolStyle === \"google\"\n        ? [{ functionDeclarations: toolDicts }]\n        : toolDicts;\n\n    const next = new FakeListChatModel({\n      responses: this.responses,\n      sleep: this.sleep,\n      emitCustomEvent: this.emitCustomEvent,\n      generationInfo: this.generationInfo,\n    });\n    next.tools = merged;\n    next.toolStyle = this.toolStyle;\n    next.i = this.i;\n\n    return next.withConfig({ tools: wrapped } as BaseChatModelCallOptions);\n  }\n\n  withStructuredOutput<\n    // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n    RunOutput extends Record<string, any> = Record<string, any>,\n  >(\n    _params:\n      | StructuredOutputMethodParams<RunOutput, false>\n      | InteropZodType<RunOutput>\n      // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n      | Record<string, any>,\n    config?: StructuredOutputMethodOptions<false>\n  ): Runnable<BaseLanguageModelInput, RunOutput>;\n\n  withStructuredOutput<\n    // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n    RunOutput extends Record<string, any> = Record<string, any>,\n  >(\n    _params:\n      | StructuredOutputMethodParams<RunOutput, true>\n      | InteropZodType<RunOutput>\n      // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n      | Record<string, any>,\n    config?: StructuredOutputMethodOptions<true>\n  ): Runnable<BaseLanguageModelInput, { raw: BaseMessage; parsed: RunOutput }>;\n\n  withStructuredOutput<\n    // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n    RunOutput extends Record<string, any> = Record<string, any>,\n  >(\n    _params:\n      | StructuredOutputMethodParams<RunOutput, boolean>\n      | InteropZodType<RunOutput>\n      // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n      | Record<string, any>,\n    _config?: StructuredOutputMethodOptions<boolean>\n  ):\n    | Runnable<BaseLanguageModelInput, RunOutput>\n    | Runnable<\n        BaseLanguageModelInput,\n        { raw: BaseMessage; parsed: RunOutput }\n      > {\n    return RunnableLambda.from(async (input) => {\n      const message = await this.invoke(input);\n      if (message.tool_calls?.[0]?.args) {\n        return message.tool_calls[0].args as RunOutput;\n      }\n      if (typeof message.content === \"string\") {\n        return JSON.parse(message.content);\n      }\n      throw new Error(\"No structured output found\");\n    }) as Runnable;\n  }\n}\n"],"mappings":"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"}