{"version":3,"file":"responses.cjs","names":["BaseChatOpenAI","getChatOpenAIModelParams","isBuiltInToolChoice","formatToOpenAIToolChoice","convertMessagesToResponsesInput","convertResponsesMessageToAIMessage","convertResponsesDeltaToChatGenerationChunk","wrapOpenAIClientError","isBuiltInTool","isCustomTool","isOpenAICustomTool","convertCompletionsCustomTool"],"sources":["../../src/chat_models/responses.ts"],"sourcesContent":["import { OpenAI as OpenAIClient } from \"openai\";\nimport { CallbackManagerForLLMRun } from \"@langchain/core/callbacks/manager\";\nimport { AIMessage, type BaseMessage } from \"@langchain/core/messages\";\nimport { ChatGenerationChunk, type ChatResult } from \"@langchain/core/outputs\";\nimport { isOpenAITool as isOpenAIFunctionTool } from \"@langchain/core/language_models/base\";\nimport { wrapOpenAIClientError } from \"../utils/client.js\";\nimport {\n  ChatOpenAIToolType,\n  convertCompletionsCustomTool,\n  formatToOpenAIToolChoice,\n  isBuiltInTool,\n  isBuiltInToolChoice,\n  isCustomTool,\n  isOpenAICustomTool,\n  ResponsesTool,\n} from \"../utils/tools.js\";\nimport {\n  BaseChatOpenAI,\n  BaseChatOpenAICallOptions,\n  BaseChatOpenAIFields,\n  getChatOpenAIModelParams,\n} from \"./base.js\";\nimport {\n  convertMessagesToResponsesInput,\n  convertResponsesDeltaToChatGenerationChunk,\n  convertResponsesMessageToAIMessage,\n} from \"../converters/responses.js\";\nimport { OpenAIVerbosityParam } from \"../types.js\";\n\nexport interface ChatOpenAIResponsesCallOptions extends BaseChatOpenAICallOptions {\n  /**\n   * Configuration options for a text response from the model. Can be plain text or\n   * structured JSON data.\n   */\n  text?: OpenAIClient.Responses.ResponseCreateParams[\"text\"];\n\n  /**\n   * The truncation strategy to use for the model response.\n   */\n  truncation?: OpenAIClient.Responses.ResponseCreateParams[\"truncation\"];\n\n  /**\n   * Specify additional output data to include in the model response.\n   */\n  include?: OpenAIClient.Responses.ResponseCreateParams[\"include\"];\n\n  /**\n   * The unique ID of the previous response to the model. Use this to create multi-turn\n   * conversations.\n   */\n  previous_response_id?: OpenAIClient.Responses.ResponseCreateParams[\"previous_response_id\"];\n\n  /**\n   * The verbosity of the model's response.\n   */\n  verbosity?: OpenAIVerbosityParam;\n}\n\nexport type ChatResponsesInvocationParams = Omit<\n  OpenAIClient.Responses.ResponseCreateParams,\n  \"input\"\n>;\n\n/**\n * OpenAI Responses API implementation.\n *\n * Will be exported in a later version of @langchain/openai.\n *\n * @internal\n */\nexport class ChatOpenAIResponses<\n  CallOptions extends ChatOpenAIResponsesCallOptions =\n    ChatOpenAIResponsesCallOptions,\n> extends BaseChatOpenAI<CallOptions> {\n  constructor(model: string, fields?: Omit<BaseChatOpenAIFields, \"model\">);\n  constructor(fields?: BaseChatOpenAIFields);\n  constructor(\n    modelOrFields?: string | BaseChatOpenAIFields,\n    fieldsArg?: Omit<BaseChatOpenAIFields, \"model\">\n  ) {\n    super(getChatOpenAIModelParams(modelOrFields, fieldsArg));\n  }\n\n  override invocationParams(\n    options?: this[\"ParsedCallOptions\"]\n  ): ChatResponsesInvocationParams {\n    let strict: boolean | undefined;\n    if (options?.strict !== undefined) {\n      strict = options.strict;\n    }\n    if (strict === undefined && this.supportsStrictToolCalling !== undefined) {\n      strict = this.supportsStrictToolCalling;\n    }\n\n    const params: ChatResponsesInvocationParams = {\n      model: this.model,\n      temperature: this.temperature,\n      top_p: this.topP,\n      user: this.user,\n      service_tier: this.service_tier,\n\n      // if include_usage is set or streamUsage then stream must be set to true.\n      stream: this.streaming,\n      previous_response_id: options?.previous_response_id,\n      truncation: options?.truncation,\n      include: options?.include,\n      tools: options?.tools?.length\n        ? this._reduceChatOpenAITools(options.tools, {\n            stream: this.streaming,\n            strict,\n          })\n        : undefined,\n      tool_choice: isBuiltInToolChoice(options?.tool_choice)\n        ? options?.tool_choice\n        : (() => {\n            const formatted = formatToOpenAIToolChoice(options?.tool_choice);\n            if (typeof formatted === \"object\" && \"type\" in formatted) {\n              if (formatted.type === \"function\") {\n                return { type: \"function\", name: formatted.function.name };\n              } else if (formatted.type === \"allowed_tools\") {\n                return {\n                  type: \"allowed_tools\",\n                  mode: formatted.allowed_tools.mode,\n                  tools: formatted.allowed_tools.tools,\n                };\n              } else if (formatted.type === \"custom\") {\n                return {\n                  type: \"custom\",\n                  name: formatted.custom.name,\n                };\n              }\n            }\n            return undefined;\n          })(),\n      text: (() => {\n        if (options?.text) return options.text;\n        const format = this._getResponseFormat(options?.response_format);\n        if (format?.type === \"json_schema\") {\n          if (format.json_schema.schema != null) {\n            return {\n              format: {\n                type: \"json_schema\",\n                schema: format.json_schema.schema,\n                description: format.json_schema.description,\n                name: format.json_schema.name,\n                strict: format.json_schema.strict,\n              },\n              verbosity: options?.verbosity,\n            };\n          }\n          return undefined;\n        }\n        return { format, verbosity: options?.verbosity };\n      })(),\n      parallel_tool_calls: options?.parallel_tool_calls,\n      max_output_tokens: this.maxTokens === -1 ? undefined : this.maxTokens,\n      prompt_cache_key: options?.promptCacheKey ?? this.promptCacheKey,\n      prompt_cache_retention:\n        options?.promptCacheRetention ?? this.promptCacheRetention,\n      ...(this.zdrEnabled ? { store: false } : {}),\n      ...this.modelKwargs,\n    };\n\n    const reasoning = this._getReasoningParams(options);\n\n    if (reasoning !== undefined) {\n      params.reasoning = reasoning;\n    }\n\n    return params;\n  }\n\n  async _generate(\n    messages: BaseMessage[],\n    options: this[\"ParsedCallOptions\"],\n    runManager?: CallbackManagerForLLMRun\n  ): Promise<ChatResult> {\n    options.signal?.throwIfAborted();\n    const invocationParams = this.invocationParams(options);\n    if (invocationParams.stream) {\n      const stream = this._streamResponseChunks(messages, options, runManager);\n      let finalChunk: ChatGenerationChunk | undefined;\n      for await (const chunk of stream) {\n        chunk.message.response_metadata = {\n          ...chunk.generationInfo,\n          ...chunk.message.response_metadata,\n        };\n        finalChunk = finalChunk?.concat(chunk) ?? chunk;\n      }\n\n      return {\n        generations: finalChunk ? [finalChunk] : [],\n        llmOutput: {\n          estimatedTokenUsage: (finalChunk?.message as AIMessage | undefined)\n            ?.usage_metadata,\n        },\n      };\n    } else {\n      const data = await this.completionWithRetry(\n        {\n          input: convertMessagesToResponsesInput({\n            messages,\n            zdrEnabled: this.zdrEnabled ?? false,\n            model: this.model,\n          }),\n          ...invocationParams,\n          stream: false,\n        },\n        { signal: options?.signal, ...options?.options }\n      );\n\n      return {\n        generations: [\n          {\n            text: data.output_text,\n            message: convertResponsesMessageToAIMessage(data),\n          },\n        ],\n        llmOutput: {\n          id: data.id,\n          estimatedTokenUsage: data.usage\n            ? {\n                promptTokens: data.usage.input_tokens,\n                completionTokens: data.usage.output_tokens,\n                totalTokens: data.usage.total_tokens,\n              }\n            : undefined,\n        },\n      };\n    }\n  }\n\n  async *_streamResponseChunks(\n    messages: BaseMessage[],\n    options: this[\"ParsedCallOptions\"],\n    runManager?: CallbackManagerForLLMRun\n  ): AsyncGenerator<ChatGenerationChunk> {\n    const streamIterable = await this.completionWithRetry(\n      {\n        ...this.invocationParams(options),\n        input: convertMessagesToResponsesInput({\n          messages,\n          zdrEnabled: this.zdrEnabled ?? false,\n          model: this.model,\n        }),\n        stream: true,\n      },\n      options\n    );\n\n    for await (const data of streamIterable) {\n      if (options.signal?.aborted) {\n        return;\n      }\n      const chunk = convertResponsesDeltaToChatGenerationChunk(data);\n      if (chunk == null) continue;\n      yield chunk;\n      await runManager?.handleLLMNewToken(\n        chunk.text || \"\",\n        {\n          prompt: options.promptIndex ?? 0,\n          completion: 0,\n        },\n        undefined,\n        undefined,\n        undefined,\n        { chunk }\n      );\n    }\n  }\n\n  /**\n   * Calls the Responses API with retry logic in case of failures.\n   * @param request The request to send to the OpenAI API.\n   * @param options Optional configuration for the API call.\n   * @returns The response from the OpenAI API.\n   */\n  async completionWithRetry(\n    request: OpenAIClient.Responses.ResponseCreateParamsStreaming,\n    requestOptions?: OpenAIClient.RequestOptions\n  ): Promise<AsyncIterable<OpenAIClient.Responses.ResponseStreamEvent>>;\n\n  async completionWithRetry(\n    request: OpenAIClient.Responses.ResponseCreateParamsNonStreaming,\n    requestOptions?: OpenAIClient.RequestOptions\n  ): Promise<OpenAIClient.Responses.Response>;\n\n  async completionWithRetry(\n    request: OpenAIClient.Responses.ResponseCreateParams,\n    requestOptions?: OpenAIClient.RequestOptions\n  ): Promise<\n    | AsyncIterable<OpenAIClient.Responses.ResponseStreamEvent>\n    | OpenAIClient.Responses.Response\n  > {\n    return this.caller.call(async () => {\n      const clientOptions = this._getClientOptions(requestOptions);\n      try {\n        // use parse if dealing with json_schema\n        if (request.text?.format?.type === \"json_schema\" && !request.stream) {\n          return await this.client.responses.parse(request, clientOptions);\n        }\n        return await this.client.responses.create(request, clientOptions);\n      } catch (e) {\n        const error = wrapOpenAIClientError(e);\n        throw error;\n      }\n    });\n  }\n\n  /** @internal */\n  protected _reduceChatOpenAITools(\n    tools: ChatOpenAIToolType[],\n    fields: { stream?: boolean; strict?: boolean }\n  ): ResponsesTool[] {\n    const reducedTools: ResponsesTool[] = [];\n    for (const tool of tools) {\n      if (isBuiltInTool(tool)) {\n        if (tool.type === \"image_generation\" && fields?.stream) {\n          // OpenAI sends a 400 error if partial_images is not set and we want to stream.\n          // We also set it to 1 since we don't support partial images yet.\n          tool.partial_images = 1;\n        }\n        reducedTools.push(tool);\n      } else if (isCustomTool(tool)) {\n        const customToolData = tool.metadata.customTool;\n        reducedTools.push({\n          type: \"custom\",\n          name: customToolData.name,\n          description: customToolData.description,\n          format: customToolData.format,\n        } as ResponsesTool);\n      } else if (isOpenAIFunctionTool(tool)) {\n        const extra: Record<string, unknown> = {};\n        for (const [k, v] of Object.entries(tool)) {\n          if (k !== \"type\" && k !== \"function\") {\n            extra[k] = v;\n          }\n        }\n        reducedTools.push({\n          type: \"function\",\n          name: tool.function.name,\n          parameters: tool.function.parameters,\n          description: tool.function.description,\n          strict: fields?.strict ?? null,\n          ...extra,\n        });\n      } else if (isOpenAICustomTool(tool)) {\n        reducedTools.push(convertCompletionsCustomTool(tool));\n      }\n    }\n    return reducedTools;\n  }\n}\n"],"mappings":"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"}