{"version":3,"file":"chat_models.cjs","names":["BaseChatModel","messages: BaseMessage[]","options?: this[\"ParsedCallOptions\"]","runManager?: CallbackManagerForLLMRun","AIMessage","tools: (StructuredTool | ToolSpec)[]","toJsonSchema","_options: this[\"ParsedCallOptions\"]","_runManager?: CallbackManagerForLLMRun","generation: ChatResult","_messages: BaseMessage[]","ChatGenerationChunk","AIMessageChunk","params: FakeChatInput","text: string","options: this[\"ParsedCallOptions\"]","_params:\n      | StructuredOutputMethodParams<RunOutput, boolean>\n      | InteropZodType<RunOutput>\n      // eslint-disable-next-line @typescript-eslint/no-explicit-any\n      | Record<string, any>","_config?: StructuredOutputMethodOptions<boolean>","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\n  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        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      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\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  constructor(params: FakeChatInput) {\n    super(params);\n    const { responses, sleep, emitCustomEvent } = params;\n    this.responses = responses;\n    this.sleep = sleep;\n    this.emitCustomEvent = emitCustomEvent ?? this.emitCustomEvent;\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    for await (const text of response) {\n      await this._sleepIfRequested();\n      if (options?.thrownErrorString) {\n        throw new Error(options.thrownErrorString);\n      }\n      const chunk = this._createResponseChunk(text);\n      yield chunk;\n      // eslint-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(text: string): ChatGenerationChunk {\n    return new ChatGenerationChunk({\n      message: new AIMessageChunk({ content: text }),\n      text,\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  withStructuredOutput<\n    // eslint-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      // eslint-disable-next-line @typescript-eslint/no-explicit-any\n      | Record<string, any>,\n    config?: StructuredOutputMethodOptions<false>\n  ): Runnable<BaseLanguageModelInput, RunOutput>;\n\n  withStructuredOutput<\n    // eslint-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      // eslint-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    // eslint-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      // eslint-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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"}