{"version":3,"file":"responses.cjs","names":["BaseChatModel","convertMessagesToResponsesInput","convertResponseToAIMessage","extractTextFromOutput","convertStreamEventToChunk"],"sources":["../../src/chat_models/responses.ts"],"sourcesContent":["import { CallbackManagerForLLMRun } from \"@langchain/core/callbacks/manager\";\nimport { AIMessage, BaseMessage } from \"@langchain/core/messages\";\nimport {\n  BaseChatModel,\n  type LangSmithParams,\n} from \"@langchain/core/language_models/chat_models\";\nimport { ChatGenerationChunk, type ChatResult } from \"@langchain/core/outputs\";\nimport { getEnvironmentVariable } from \"@langchain/core/utils/env\";\nimport { Serialized } from \"@langchain/core/load/serializable\";\n\nimport type {\n  ChatXAIResponsesCallOptions,\n  ChatXAIResponsesInput,\n  ChatXAIResponsesInvocationParams,\n  XAIResponse,\n  XAIResponsesCreateParams,\n  XAIResponsesCreateParamsNonStreaming,\n  XAIResponsesCreateParamsStreaming,\n  XAIResponsesReasoning,\n  XAIResponsesSearchParameters,\n  XAIResponsesStreamEvent,\n  XAIResponsesTool,\n} from \"./responses-types.js\";\n\nimport {\n  convertMessagesToResponsesInput,\n  convertResponseToAIMessage,\n  convertStreamEventToChunk,\n  extractTextFromOutput,\n} from \"../converters/responses.js\";\n\n// Re-export types for convenience\nexport type {\n  ChatXAIResponsesCallOptions,\n  ChatXAIResponsesInput,\n  ChatXAIResponsesInvocationParams,\n};\n\n// ============================================================================\n// Main Class\n// ============================================================================\n\n/**\n * xAI Responses API chat model integration.\n *\n * This class provides access to xAI's Responses API, which offers enhanced\n * capabilities including built-in tools, reasoning, and search.\n *\n * @example\n * ```typescript\n * import { ChatXAIResponses } from \"@langchain/xai\";\n *\n * const llm = new ChatXAIResponses({\n *   model: \"grok-3\",\n *   temperature: 0.7,\n * });\n *\n * const result = await llm.invoke(\"What is the capital of France?\");\n * console.log(result.content);\n * ```\n */\nexport class ChatXAIResponses<\n  CallOptions extends ChatXAIResponsesCallOptions = ChatXAIResponsesCallOptions,\n> extends BaseChatModel<CallOptions> {\n  static lc_name() {\n    return \"ChatXAIResponses\";\n  }\n\n  lc_serializable = true;\n\n  lc_namespace = [\"langchain\", \"chat_models\", \"xai\"];\n\n  get lc_secrets(): { [key: string]: string } | undefined {\n    return {\n      apiKey: \"XAI_API_KEY\",\n    };\n  }\n\n  get lc_aliases(): { [key: string]: string } | undefined {\n    return {\n      apiKey: \"xai_api_key\",\n    };\n  }\n\n  // -------------------------------------------------------------------------\n  // Instance Properties\n  // -------------------------------------------------------------------------\n\n  apiKey: string;\n\n  model: string;\n\n  streaming: boolean;\n\n  temperature?: number;\n\n  topP?: number;\n\n  maxOutputTokens?: number;\n\n  store?: boolean;\n\n  user?: string;\n\n  baseURL: string;\n\n  searchParameters?: XAIResponsesSearchParameters;\n\n  reasoning?: XAIResponsesReasoning;\n\n  tools?: XAIResponsesTool[];\n\n  // -------------------------------------------------------------------------\n  // Constructor\n  // -------------------------------------------------------------------------\n\n  constructor(model: string, fields?: Omit<ChatXAIResponsesInput, \"model\">);\n  constructor(fields?: ChatXAIResponsesInput);\n  constructor(\n    modelOrFields?: string | ChatXAIResponsesInput,\n    fieldsArg?: Omit<ChatXAIResponsesInput, \"model\">\n  ) {\n    const fields =\n      typeof modelOrFields === \"string\"\n        ? { ...(fieldsArg ?? {}), model: modelOrFields }\n        : (modelOrFields ?? {});\n    super(fields);\n\n    this._addVersion(\"@langchain/xai\", __PKG_VERSION__);\n\n    const apiKey = fields?.apiKey ?? getEnvironmentVariable(\"XAI_API_KEY\");\n    if (!apiKey) {\n      throw new Error(\n        `xAI API key not found. Please set the XAI_API_KEY environment variable or provide the key in the \"apiKey\" field.`\n      );\n    }\n\n    this.apiKey = apiKey;\n    this.model = fields?.model ?? \"grok-3\";\n    this.streaming = fields?.streaming ?? false;\n    this.temperature = fields?.temperature;\n    this.topP = fields?.topP;\n    this.maxOutputTokens = fields?.maxOutputTokens;\n    this.store = fields?.store;\n    this.user = fields?.user;\n    this.baseURL = fields?.baseURL ?? \"https://api.x.ai/v1\";\n    this.searchParameters = fields?.searchParameters;\n    this.reasoning = fields?.reasoning;\n    this.tools = fields?.tools;\n  }\n\n  // -------------------------------------------------------------------------\n  // Metadata Methods\n  // -------------------------------------------------------------------------\n\n  _llmType(): string {\n    return \"xai-responses\";\n  }\n\n  override getLsParams(options: this[\"ParsedCallOptions\"]): LangSmithParams {\n    const params = super.getLsParams(options);\n    params.ls_provider = \"xai\";\n    params.ls_model_name = this.model;\n    params.ls_model_type = \"chat\";\n    params.ls_temperature = this.temperature;\n    params.ls_max_tokens = this.maxOutputTokens;\n    return params;\n  }\n\n  override toJSON(): Serialized {\n    const result = super.toJSON();\n\n    if (\n      \"kwargs\" in result &&\n      typeof result.kwargs === \"object\" &&\n      result.kwargs != null\n    ) {\n      delete (result.kwargs as Record<string, unknown>).apiKey;\n    }\n\n    return result;\n  }\n\n  // -------------------------------------------------------------------------\n  // Invocation Params\n  // -------------------------------------------------------------------------\n\n  invocationParams(\n    options?: this[\"ParsedCallOptions\"]\n  ): ChatXAIResponsesInvocationParams {\n    return {\n      model: this.model,\n      temperature: this.temperature,\n      top_p: this.topP,\n      max_output_tokens: this.maxOutputTokens,\n      store: this.store,\n      user: this.user,\n      stream: this.streaming,\n      previous_response_id: options?.previous_response_id,\n      include: options?.include,\n      text: options?.text,\n      search_parameters: options?.search_parameters ?? this.searchParameters,\n      reasoning: options?.reasoning ?? this.reasoning,\n      tools: options?.tools ?? this.tools,\n      tool_choice: options?.tool_choice,\n      parallel_tool_calls: options?.parallel_tool_calls,\n    };\n  }\n\n  // -------------------------------------------------------------------------\n  // API Call Methods\n  // -------------------------------------------------------------------------\n\n  /**\n   * Makes a request to the xAI Responses API.\n   */\n  protected async _makeRequest(\n    request: XAIResponsesCreateParamsNonStreaming\n  ): Promise<XAIResponse>;\n\n  protected async _makeRequest(\n    request: XAIResponsesCreateParamsStreaming\n  ): Promise<AsyncIterable<XAIResponsesStreamEvent>>;\n\n  protected async _makeRequest(\n    request: XAIResponsesCreateParams\n  ): Promise<XAIResponse | AsyncIterable<XAIResponsesStreamEvent>> {\n    const url = `${this.baseURL}/responses`;\n\n    const headers: Record<string, string> = {\n      \"Content-Type\": \"application/json\",\n      Authorization: `Bearer ${this.apiKey}`,\n    };\n\n    if (request.stream) {\n      return this._makeStreamingRequest(url, headers, request);\n    }\n\n    const response = await this.caller.call(async () => {\n      const res = await fetch(url, {\n        method: \"POST\",\n        headers,\n        body: JSON.stringify(request),\n      });\n\n      if (!res.ok) {\n        const errorBody = await res.text();\n        throw new Error(\n          `xAI API error: ${res.status} ${res.statusText} - ${errorBody}`\n        );\n      }\n\n      return res.json();\n    });\n\n    return response as XAIResponse;\n  }\n\n  /**\n   * Makes a streaming request to the xAI Responses API.\n   */\n  protected async *_makeStreamingRequest(\n    url: string,\n    headers: Record<string, string>,\n    request: XAIResponsesCreateParams\n  ): AsyncIterable<XAIResponsesStreamEvent> {\n    const response = await this.caller.call(async () => {\n      const res = await fetch(url, {\n        method: \"POST\",\n        headers,\n        body: JSON.stringify(request),\n      });\n\n      if (!res.ok) {\n        const errorBody = await res.text();\n        throw new Error(\n          `xAI API error: ${res.status} ${res.statusText} - ${errorBody}`\n        );\n      }\n\n      return res;\n    });\n\n    const reader = response.body?.getReader();\n    if (!reader) {\n      throw new Error(\"No response body\");\n    }\n\n    const decoder = new TextDecoder();\n    let buffer = \"\";\n\n    try {\n      while (true) {\n        const { done, value } = await reader.read();\n        if (done) break;\n\n        buffer += decoder.decode(value, { stream: true });\n        const lines = buffer.split(\"\\n\");\n        buffer = lines.pop() ?? \"\";\n\n        for (const line of lines) {\n          const trimmed = line.trim();\n          if (!trimmed || trimmed === \"data: [DONE]\") continue;\n\n          if (trimmed.startsWith(\"data: \")) {\n            try {\n              const data = JSON.parse(trimmed.slice(6));\n              yield data as XAIResponsesStreamEvent;\n            } catch {\n              // Skip invalid JSON\n            }\n          }\n        }\n      }\n    } finally {\n      reader.releaseLock();\n    }\n  }\n\n  // -------------------------------------------------------------------------\n  // Generation Methods\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    const input = convertMessagesToResponsesInput(messages);\n\n    if (invocationParams.stream) {\n      const stream = this._streamResponseChunks(messages, options, runManager);\n      let finalChunk: ChatGenerationChunk | undefined;\n\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    }\n\n    const response = await this._makeRequest({\n      input,\n      ...invocationParams,\n      stream: false,\n    } as XAIResponsesCreateParamsNonStreaming);\n\n    const aiMessage = convertResponseToAIMessage(response);\n    const text = extractTextFromOutput(response.output);\n\n    return {\n      generations: [\n        {\n          text,\n          message: aiMessage,\n        },\n      ],\n      llmOutput: {\n        id: response.id,\n        estimatedTokenUsage: response.usage\n          ? {\n              promptTokens: response.usage.input_tokens,\n              completionTokens: response.usage.output_tokens,\n              totalTokens: response.usage.total_tokens,\n            }\n          : undefined,\n      },\n    };\n  }\n\n  async *_streamResponseChunks(\n    messages: BaseMessage[],\n    options: this[\"ParsedCallOptions\"],\n    runManager?: CallbackManagerForLLMRun\n  ): AsyncGenerator<ChatGenerationChunk> {\n    const invocationParams = this.invocationParams(options);\n    const input = convertMessagesToResponsesInput(messages);\n\n    const streamIterable = await this._makeRequest({\n      input,\n      ...invocationParams,\n      stream: true,\n    } as XAIResponsesCreateParamsStreaming);\n\n    for await (const event of streamIterable) {\n      if (options.signal?.aborted) {\n        return;\n      }\n      const chunk = convertStreamEventToChunk(event);\n      if (chunk) {\n        yield chunk;\n        await runManager?.handleLLMNewToken(chunk.text || \"\", {\n          prompt: 0,\n          completion: 0,\n        });\n      }\n    }\n  }\n}\n"],"mappings":"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"}