What format data does AIMessage has to have to give contentBlock with {type:"reasoning"} #388

Open
opened 2026-02-15 18:16:23 -05:00 by yindo · 0 comments
Owner

Originally created by @DevDeepakBhattarai on GitHub (Dec 29, 2025).

Checked other resources

  • I added a very descriptive title to this issue.
  • I searched the LangGraph.js documentation with the integrated search.
  • I used the GitHub search to find a similar question and didn't find it.
  • I am sure that this is a bug in LangGraph.js rather than my code.
  • The bug is not resolved by updating to the latest stable version of LangGraph (or the specific integration package).

Example Code

/**
 * ChatOpenRouter - Extends ChatOpenAI with OpenRouter + reasoning support
 *
 * @requires @langchain/openai
 * @requires @langchain/core
 */

import { getEnvironmentVariable } from "@langchain/core/utils/env";
import {
  ChatOpenAICallOptions,
  ChatOpenAICompletions,
  ChatOpenAIFields,
  OpenAIClient,
} from "@langchain/openai";

// ============================================================================
// TYPES
// ============================================================================

export interface OpenRouterReasoningConfig {
  effort?: "high" | "medium" | "low";
  max_tokens?: number;
  exclude?: boolean;
}

export interface OpenRouterProviderConfig {
  order?: string[];
  allow_fallbacks?: boolean;
  require_parameters?: boolean;
  only?: string[];
  ignore?: string[];
  data_collection?: "allow" | "deny";
  sort?: "throughput";
  quantizations?: string[];
}

export interface ChatOpenRouterCallOptions extends ChatOpenAICallOptions {
  /** OpenRouter reasoning configuration */
  reasoning?: OpenRouterReasoningConfig;
  /** OpenRouter provider routing */
  provider?: OpenRouterProviderConfig;
  /** Extra headers for this request */
  headers?: Record<string, string>;
}

export interface ChatOpenRouterInput
  extends Omit<ChatOpenAIFields, "openAIApiKey" | "configuration"> {
  /**
   * OpenRouter API key
   * @default process.env.OPENROUTER_API_KEY
   */
  apiKey?: string;
  /**
   * Model to use (e.g., "openai/gpt-4o", "anthropic/claude-sonnet-4", "deepseek/deepseek-r1")
   */
  model?: string;
  /**
   * Your site URL for OpenRouter rankings
   */
  siteUrl?: string;
  /**
   * Your site/app name for OpenRouter rankings
   */
  siteName?: string;
  /**
   * Default reasoning configuration
   */
  reasoning?: OpenRouterReasoningConfig;
  /**
   * Default provider routing configuration
   */
  provider?: OpenRouterProviderConfig;
}

// ============================================================================
// MAIN CLASS
// ============================================================================

/**
 * OpenRouter chat model - extends ChatOpenAI with reasoning support.
 *
 * OpenRouter provides access to 300+ models through a unified OpenAI-compatible API.
 * This class adds automatic reasoning extraction for thinking models like DeepSeek R1,
 * Claude with extended thinking, OpenAI o-series, etc.
 *
 * @example
 * ```typescript
 * import { ChatOpenRouter } from "./chat-openrouter";
 *
 * // Basic usage - same as ChatOpenAI
 * const llm = new ChatOpenRouter({
 *   model: "openai/gpt-4o",
 * });
 *
 * // With reasoning model
 * const reasoningLlm = new ChatOpenRouter({
 *   model: "deepseek/deepseek-r1",
 *   reasoning: { effort: "high" },
 * });
 *
 * const response = await reasoningLlm.invoke("Which is larger: 9.11 or 9.9?");
 * console.log(response.content); // The answer
 * console.log(response.additional_kwargs.reasoning_content); // The thinking
 * ```
 */
export class ChatOpenRouter extends ChatOpenAICompletions<ChatOpenRouterCallOptions> {
  static lc_name() {
    return "ChatOpenRouter";
  }

  _llmType() {
    return "openrouter";
  }

  get lc_secrets(): { [key: string]: string } | undefined {
    return {
      apiKey: "OPENROUTER_API_KEY",
      openAIApiKey: "OPENROUTER_API_KEY",
    };
  }

  lc_serializable = true;

  // OpenRouter-specific fields
  reasoning?: OpenRouterReasoningConfig;
  provider?: OpenRouterProviderConfig;
  siteUrl?: string;
  siteName?: string;

  constructor(fields?: ChatOpenRouterInput) {
    const apiKey =
      fields?.apiKey ?? getEnvironmentVariable("OPENROUTER_API_KEY");

    if (!apiKey) {
      throw new Error(
        `OpenRouter API key not found. Set OPENROUTER_API_KEY environment variable or pass apiKey.`,
      );
    }

    // Build default headers for OpenRouter
    const defaultHeaders: Record<string, string> = {};
    if (fields?.siteUrl) {
      defaultHeaders["HTTP-Referer"] = fields.siteUrl;
    }
    if (fields?.siteName) {
      defaultHeaders["X-Title"] = fields.siteName;
    }

    super({
      ...fields,
      openAIApiKey: apiKey,
      configuration: {
        baseURL: "https://openrouter.ai/api/v1",
        defaultHeaders:
          Object.keys(defaultHeaders).length > 0 ? defaultHeaders : undefined,
      },
    });

    this.reasoning = fields?.reasoning;
    this.provider = fields?.provider;
    this.siteUrl = fields?.siteUrl;
    this.siteName = fields?.siteName;
  }

  /**
   * Override to inject reasoning and provider params into the request
   */
  override invocationParams(
    options?: this["ParsedCallOptions"],
  ): Omit<OpenAIClient.Chat.ChatCompletionCreateParams, "messages"> {
    const params = super.invocationParams(options);

    // Add reasoning config
    const reasoning = options?.reasoning ?? this.reasoning;
    if (reasoning) {
      (params as Record<string, unknown>).reasoning = reasoning;
    }

    // Add provider config
    const provider = options?.provider ?? this.provider;
    if (provider) {
      (params as Record<string, unknown>).provider = provider;
    }

    return params;
  }

  /**
   * Extract reasoning_content from streaming delta
   */
  protected override _convertCompletionsDeltaToBaseMessageChunk(
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    delta: Record<string, any>,
    rawResponse: OpenAIClient.ChatCompletionChunk,
    defaultRole?:
      | "function"
      | "user"
      | "system"
      | "developer"
      | "assistant"
      | "tool",
  ) {
    const messageChunk = super._convertCompletionsDeltaToBaseMessageChunk(
      delta,
      rawResponse,
      defaultRole,
    );

    // Extract reasoning_content (DeepSeek R1, Qwen style)
    if (delta.reasoning_content) {
      messageChunk.additional_kwargs.reasoning_content =
        delta.reasoning_content;
    }

    // Extract reasoning (legacy format)
    if (delta.reasoning) {
      messageChunk.additional_kwargs.reasoning_content =
        (messageChunk.additional_kwargs.reasoning_content ?? "") +
        delta.reasoning;
    }

    // Extract reasoning_details (Claude, OpenAI o-series style)
    if (delta.reasoning_details) {
      messageChunk.additional_kwargs.reasoning_details =
        delta.reasoning_details;

      // Also extract text for convenience
      let reasoningText = "";
      for (const detail of delta.reasoning_details) {
        if (detail.type === "reasoning.text" && detail.text) {
          reasoningText += detail.text;
        } else if (detail.type === "thinking" && detail.text) {
          reasoningText += detail.text;
        }
      }
      if (reasoningText) {
        messageChunk.additional_kwargs.reasoning_content =
          (messageChunk.additional_kwargs.reasoning_content ?? "") +
          reasoningText;
      }
    }

    return messageChunk;
  }

  /**
   * Extract reasoning_content from non-streaming response
   */
  protected override _convertCompletionsMessageToBaseMessage(
    message: OpenAIClient.ChatCompletionMessage,
    rawResponse: OpenAIClient.ChatCompletion,
  ) {
    const langChainMessage = super._convertCompletionsMessageToBaseMessage(
      message,
      rawResponse,
    );

    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    const msg = message as any;

    // Extract reasoning_content (DeepSeek R1, Qwen style)
    if (msg.reasoning_content) {
      langChainMessage.additional_kwargs.reasoning_content =
        msg.reasoning_content;
    }

    // Extract reasoning (legacy format)
    if (msg.reasoning) {
      langChainMessage.additional_kwargs.reasoning_content =
        (langChainMessage.additional_kwargs.reasoning_content ?? "") +
        msg.reasoning;
    }

    // Extract reasoning_details (Claude, OpenAI o-series style)
    if (msg.reasoning_details) {
      langChainMessage.additional_kwargs.reasoning_details =
        msg.reasoning_details;

      // Also extract text for convenience
      let reasoningText = "";
      for (const detail of msg.reasoning_details) {
        if (detail.type === "reasoning.text" && detail.text) {
          reasoningText += detail.text;
        } else if (detail.type === "reasoning.summary" && detail.summary) {
          reasoningText += `\n${detail.summary}`;
        } else if (detail.type === "thinking" && detail.text) {
          reasoningText += detail.text;
        }
      }
      if (reasoningText) {
        langChainMessage.additional_kwargs.reasoning_content =
          (langChainMessage.additional_kwargs.reasoning_content ?? "") +
          reasoningText;
      }
    }

    return langChainMessage;
  }
}

export default ChatOpenRouter;

Error Message and Stack Trace (if applicable)

No response

Description

I am trying to make own custom implementation of ChatOpenAI for openrouter since ChatDeepSeek and ChatOpenAI fail to extract the reasoning data properly.

I have made the ChatOpenRouter it does extract the reasoning data properly but, in the Frontend / place where i consume the message. I am trying to use the

{
    "lc": 1,
    "type": "constructor",
    "id": [
        "langchain_core",
        "messages",
        "AIMessage"
    ],
    "kwargs": {
        "content": "I am Gemini, a large language model, trained by Google. How can I help you today?",
        "additional_kwargs": {
            "reasoning_content": "**Define My Identity**\n\nI've clarified my core identity: I am Gemini, a creation of Google, specifically a large language model. My purpose is now well-defined: assisting users with tasks, answering their questions, and delivering information. This foundational understanding is now complete.\n\n\n**Define My Identity**\n\nI've clarified my core identity: I am Gemini, a creation of Google, specifically a large language model. My purpose is now well-defined: assisting users with tasks, answering their questions, and delivering information. This foundational understanding is now complete.\n\n\n**Establishing Helpful Persona**\n\nI'm now focusing on projecting my persona. I'm aiming for a helpful, professional tone while keeping it approachable and clear. I've drafted a few options, settling on a straightforward statement of who I am, coupled with a helpful opening. I'm prioritizing clarity.\n\n\n**Establishing Helpful Persona**\n\nI'm now focusing on projecting my persona. I'm aiming for a helpful, professional tone while keeping it approachable and clear. I've drafted a few options, settling on a straightforward statement of who I am, coupled with a helpful opening. I'm prioritizing clarity.\n\n\n",
            "reasoning_details": [
                {
                    "type": "reasoning.text",
                    "text": "**Define My Identity**\n\nI've clarified my core identity: I am Gemini, a creation of Google, specifically a large language model. My purpose is now well-defined: assisting users with tasks, answering their questions, and delivering information. This foundational understanding is now complete.\n\n\n**Establishing Helpful Persona**\n\nI'm now focusing on projecting my persona. I'm aiming for a helpful, professional tone while keeping it approachable and clear. I've drafted a few options, settling on a straightforward statement of who I am, coupled with a helpful opening. I'm prioritizing clarity.\n\n\n",
                    "format": "google-gemini-v1google-gemini-v1google-gemini-v1",
                    "index": 0,
                    "data": "Eq8HCqwHAXLI2nyVFk3BRAVz/oTEvlR8pz/j7gUvyAtIl7EfHuX9uXezaFfEMvu3k7vtquhsNcv25NRabSbSD4GKVPFf18E9LoHEFXE84keNijDMsTy9484iVJtqUnfyHcwL83FbMycgxP+Qt5gCZ28jZf2IbFPYboadoP9ZDOX73ULfRyWObLiDsBuc+nTKv3zpeb8TPQqZdhXzMszgkaA2UuQpjp72R3AUBO2ZSmXODpdM/qVdROhLwbq01nYpjJeQRBRG81/Z+Yx1j5xmyDl3IDS86OKxDgi+pnzUuSqnExTWkR3/vnRytEQ0seqLjlpdFoD3V0ctS/CU55JzyUTm4ItbpC+XNcMATggpG/4SuTmv0WAcNL5NdU/rlclcksq5ELDfSX51ope5F/PKYAIuzzy+facmfBcU6iDrhjl1T1lNYAXHS0frAvl5FpEWfrXi8jP/0XP1XBuv2ujhbs2zRR4j/yYLiCokWWt7OsFQusayYLXqlI5BdhVwqSFk0HyRQOEt6Cugb4jDfdhPzE+GElbXNZVen76meogVJO7MKJuhSlfiTv9BPbC+pHCXEndi6juuCRXyHJn1gOzEp1QHFIYWWJBXtCi1yITb7uLrdpJz0lMzPqlacSKreOoeOFZ6c1nNf5TmBzRddJTcFjdwYLziFOcqrqgl9uDUmgi+DPYEU3EyEmGsLU/hMLBfc7EgOQoHUmVKORJe4YezxazKmcRebmowxkbyGz9MRvlOZ+BobCZb67y1d7313zWmCCWePQG2jXgDzFCgCdaLY/l+/MtsYzymUY31T0l42yYUPcH5AQX98zWNThHFrh6njnCfWb1lpoJM1GearK4gqR5DoI70J8lRlgyYpu6xSxZM3/Wj+nHPeZEG/pzhPjWt6xjm99Qkxh8tRC2biEn6CFYW6mdlbGVDYPk3ZENLaaY7bGKhJtdnnTNof9MQPYopKPcjqdCT9xpvQX1ws9gUPJfQWVy8gYYhxwUkUyD2UGJ0zEs34GmUwcpcuRUanBdP/mf381OLx0ahZb7xFKR2Hnh6Smf2EHoiHAbuIAmxJdlPkv6qPVyaJiOQtVEoIf0vORP3RsmdNxx6RD5qnnBuUaKqFcOkffYdZhZwbCsqdvwcCOdLjJbX/7nVocV06P0dRygiRuCIG3oHgkA20DJvPJIJlwD54xLA27MabkOlvvDgmEnuNXHnaFYfGicD/yMnNHnsB8UCdwTWTLKsQdndXLb1995SLmcRwuOV1sn+N3s8Hg=="
                }
            ]
        },
        "response_metadata": {
            "model_provider": "openai",
            "usage": {
                "prompt_tokens": 138,
                "completion_tokens": 216,
                "total_tokens": 354,
                "cost": 0.000717,
                "is_byok": false,
                "prompt_tokens_details": {
                    "cached_tokens": 0,
                    "audio_tokens": 0,
                    "video_tokens": 0
                },
                "cost_details": {
                    "upstream_inference_cost": null,
                    "upstream_inference_prompt_cost": 0.000069,
                    "upstream_inference_completions_cost": 0.000648
                },
                "completion_tokens_details": {
                    "reasoning_tokens": 196,
                    "image_tokens": 0
                }
            }
        },
        "tool_call_chunks": [],
        "id": "gen-1767007881-PSN5ZqC1A7usisuWbOxu",
        "tool_calls": [],
        "invalid_tool_calls": [],
        "name": "chat_agent"
    }
}

This is the type of the data and when I do , message.contentBlocks I only see the {type:"text"}

System Info

Operating system: win32 x64
Package manager: pnpm
Package manager version: 10.17.0

zod -> 3.25.76
@langchain/anthropic -> 1.3.3
@langchain/core -> 1.1.8
langsmith -> 0.4.2
@langchain/classic -> 1.0.7
@langchain/openai -> 1.2.0
@langchain/textsplitters -> 1.0.1, 0.1.0
@langchain/community -> 1.1.1
@langchain/exa -> 1.0.1
@langchain/google-genai -> 2.1.3
@langchain/google-vertexai -> 2.1.3
@langchain/google-gauth -> 2.1.3
@langchain/google-common -> 2.1.3
@langchain/google-vertexai-web -> 2.1.3
@langchain/google-webauth -> 2.1.3
@langchain/groq -> 1.0.2
@langchain/langgraph -> 1.0.7
@langchain/langgraph-checkpoint -> 1.0.0
@langchain/langgraph-sdk -> 1.3.1
@langchain/langgraph-checkpoint-postgres -> 1.0.0
@langchain/ollama -> 1.1.0
@langchain/pinecone -> 1.0.1
@langchain/tavily -> 1.2.0
langchain -> 1.2.3

Originally created by @DevDeepakBhattarai on GitHub (Dec 29, 2025). ### Checked other resources - [x] I added a very descriptive title to this issue. - [x] I searched the LangGraph.js documentation with the integrated search. - [x] I used the GitHub search to find a similar question and didn't find it. - [x] I am sure that this is a bug in LangGraph.js rather than my code. - [x] The bug is not resolved by updating to the latest stable version of LangGraph (or the specific integration package). ### Example Code ```ts /** * ChatOpenRouter - Extends ChatOpenAI with OpenRouter + reasoning support * * @requires @langchain/openai * @requires @langchain/core */ import { getEnvironmentVariable } from "@langchain/core/utils/env"; import { ChatOpenAICallOptions, ChatOpenAICompletions, ChatOpenAIFields, OpenAIClient, } from "@langchain/openai"; // ============================================================================ // TYPES // ============================================================================ export interface OpenRouterReasoningConfig { effort?: "high" | "medium" | "low"; max_tokens?: number; exclude?: boolean; } export interface OpenRouterProviderConfig { order?: string[]; allow_fallbacks?: boolean; require_parameters?: boolean; only?: string[]; ignore?: string[]; data_collection?: "allow" | "deny"; sort?: "throughput"; quantizations?: string[]; } export interface ChatOpenRouterCallOptions extends ChatOpenAICallOptions { /** OpenRouter reasoning configuration */ reasoning?: OpenRouterReasoningConfig; /** OpenRouter provider routing */ provider?: OpenRouterProviderConfig; /** Extra headers for this request */ headers?: Record<string, string>; } export interface ChatOpenRouterInput extends Omit<ChatOpenAIFields, "openAIApiKey" | "configuration"> { /** * OpenRouter API key * @default process.env.OPENROUTER_API_KEY */ apiKey?: string; /** * Model to use (e.g., "openai/gpt-4o", "anthropic/claude-sonnet-4", "deepseek/deepseek-r1") */ model?: string; /** * Your site URL for OpenRouter rankings */ siteUrl?: string; /** * Your site/app name for OpenRouter rankings */ siteName?: string; /** * Default reasoning configuration */ reasoning?: OpenRouterReasoningConfig; /** * Default provider routing configuration */ provider?: OpenRouterProviderConfig; } // ============================================================================ // MAIN CLASS // ============================================================================ /** * OpenRouter chat model - extends ChatOpenAI with reasoning support. * * OpenRouter provides access to 300+ models through a unified OpenAI-compatible API. * This class adds automatic reasoning extraction for thinking models like DeepSeek R1, * Claude with extended thinking, OpenAI o-series, etc. * * @example * ```typescript * import { ChatOpenRouter } from "./chat-openrouter"; * * // Basic usage - same as ChatOpenAI * const llm = new ChatOpenRouter({ * model: "openai/gpt-4o", * }); * * // With reasoning model * const reasoningLlm = new ChatOpenRouter({ * model: "deepseek/deepseek-r1", * reasoning: { effort: "high" }, * }); * * const response = await reasoningLlm.invoke("Which is larger: 9.11 or 9.9?"); * console.log(response.content); // The answer * console.log(response.additional_kwargs.reasoning_content); // The thinking * ``` */ export class ChatOpenRouter extends ChatOpenAICompletions<ChatOpenRouterCallOptions> { static lc_name() { return "ChatOpenRouter"; } _llmType() { return "openrouter"; } get lc_secrets(): { [key: string]: string } | undefined { return { apiKey: "OPENROUTER_API_KEY", openAIApiKey: "OPENROUTER_API_KEY", }; } lc_serializable = true; // OpenRouter-specific fields reasoning?: OpenRouterReasoningConfig; provider?: OpenRouterProviderConfig; siteUrl?: string; siteName?: string; constructor(fields?: ChatOpenRouterInput) { const apiKey = fields?.apiKey ?? getEnvironmentVariable("OPENROUTER_API_KEY"); if (!apiKey) { throw new Error( `OpenRouter API key not found. Set OPENROUTER_API_KEY environment variable or pass apiKey.`, ); } // Build default headers for OpenRouter const defaultHeaders: Record<string, string> = {}; if (fields?.siteUrl) { defaultHeaders["HTTP-Referer"] = fields.siteUrl; } if (fields?.siteName) { defaultHeaders["X-Title"] = fields.siteName; } super({ ...fields, openAIApiKey: apiKey, configuration: { baseURL: "https://openrouter.ai/api/v1", defaultHeaders: Object.keys(defaultHeaders).length > 0 ? defaultHeaders : undefined, }, }); this.reasoning = fields?.reasoning; this.provider = fields?.provider; this.siteUrl = fields?.siteUrl; this.siteName = fields?.siteName; } /** * Override to inject reasoning and provider params into the request */ override invocationParams( options?: this["ParsedCallOptions"], ): Omit<OpenAIClient.Chat.ChatCompletionCreateParams, "messages"> { const params = super.invocationParams(options); // Add reasoning config const reasoning = options?.reasoning ?? this.reasoning; if (reasoning) { (params as Record<string, unknown>).reasoning = reasoning; } // Add provider config const provider = options?.provider ?? this.provider; if (provider) { (params as Record<string, unknown>).provider = provider; } return params; } /** * Extract reasoning_content from streaming delta */ protected override _convertCompletionsDeltaToBaseMessageChunk( // eslint-disable-next-line @typescript-eslint/no-explicit-any delta: Record<string, any>, rawResponse: OpenAIClient.ChatCompletionChunk, defaultRole?: | "function" | "user" | "system" | "developer" | "assistant" | "tool", ) { const messageChunk = super._convertCompletionsDeltaToBaseMessageChunk( delta, rawResponse, defaultRole, ); // Extract reasoning_content (DeepSeek R1, Qwen style) if (delta.reasoning_content) { messageChunk.additional_kwargs.reasoning_content = delta.reasoning_content; } // Extract reasoning (legacy format) if (delta.reasoning) { messageChunk.additional_kwargs.reasoning_content = (messageChunk.additional_kwargs.reasoning_content ?? "") + delta.reasoning; } // Extract reasoning_details (Claude, OpenAI o-series style) if (delta.reasoning_details) { messageChunk.additional_kwargs.reasoning_details = delta.reasoning_details; // Also extract text for convenience let reasoningText = ""; for (const detail of delta.reasoning_details) { if (detail.type === "reasoning.text" && detail.text) { reasoningText += detail.text; } else if (detail.type === "thinking" && detail.text) { reasoningText += detail.text; } } if (reasoningText) { messageChunk.additional_kwargs.reasoning_content = (messageChunk.additional_kwargs.reasoning_content ?? "") + reasoningText; } } return messageChunk; } /** * Extract reasoning_content from non-streaming response */ protected override _convertCompletionsMessageToBaseMessage( message: OpenAIClient.ChatCompletionMessage, rawResponse: OpenAIClient.ChatCompletion, ) { const langChainMessage = super._convertCompletionsMessageToBaseMessage( message, rawResponse, ); // eslint-disable-next-line @typescript-eslint/no-explicit-any const msg = message as any; // Extract reasoning_content (DeepSeek R1, Qwen style) if (msg.reasoning_content) { langChainMessage.additional_kwargs.reasoning_content = msg.reasoning_content; } // Extract reasoning (legacy format) if (msg.reasoning) { langChainMessage.additional_kwargs.reasoning_content = (langChainMessage.additional_kwargs.reasoning_content ?? "") + msg.reasoning; } // Extract reasoning_details (Claude, OpenAI o-series style) if (msg.reasoning_details) { langChainMessage.additional_kwargs.reasoning_details = msg.reasoning_details; // Also extract text for convenience let reasoningText = ""; for (const detail of msg.reasoning_details) { if (detail.type === "reasoning.text" && detail.text) { reasoningText += detail.text; } else if (detail.type === "reasoning.summary" && detail.summary) { reasoningText += `\n${detail.summary}`; } else if (detail.type === "thinking" && detail.text) { reasoningText += detail.text; } } if (reasoningText) { langChainMessage.additional_kwargs.reasoning_content = (langChainMessage.additional_kwargs.reasoning_content ?? "") + reasoningText; } } return langChainMessage; } } export default ChatOpenRouter; ``` ### Error Message and Stack Trace (if applicable) _No response_ ### Description I am trying to make own custom implementation of `ChatOpenAI` for openrouter since `ChatDeepSeek` and `ChatOpenAI` fail to extract the reasoning data properly. I have made the `ChatOpenRouter` it does extract the reasoning data properly but, in the Frontend / place where i consume the message. I am trying to use the ```json { "lc": 1, "type": "constructor", "id": [ "langchain_core", "messages", "AIMessage" ], "kwargs": { "content": "I am Gemini, a large language model, trained by Google. How can I help you today?", "additional_kwargs": { "reasoning_content": "**Define My Identity**\n\nI've clarified my core identity: I am Gemini, a creation of Google, specifically a large language model. My purpose is now well-defined: assisting users with tasks, answering their questions, and delivering information. This foundational understanding is now complete.\n\n\n**Define My Identity**\n\nI've clarified my core identity: I am Gemini, a creation of Google, specifically a large language model. My purpose is now well-defined: assisting users with tasks, answering their questions, and delivering information. This foundational understanding is now complete.\n\n\n**Establishing Helpful Persona**\n\nI'm now focusing on projecting my persona. I'm aiming for a helpful, professional tone while keeping it approachable and clear. I've drafted a few options, settling on a straightforward statement of who I am, coupled with a helpful opening. I'm prioritizing clarity.\n\n\n**Establishing Helpful Persona**\n\nI'm now focusing on projecting my persona. I'm aiming for a helpful, professional tone while keeping it approachable and clear. I've drafted a few options, settling on a straightforward statement of who I am, coupled with a helpful opening. I'm prioritizing clarity.\n\n\n", "reasoning_details": [ { "type": "reasoning.text", "text": "**Define My Identity**\n\nI've clarified my core identity: I am Gemini, a creation of Google, specifically a large language model. My purpose is now well-defined: assisting users with tasks, answering their questions, and delivering information. This foundational understanding is now complete.\n\n\n**Establishing Helpful Persona**\n\nI'm now focusing on projecting my persona. I'm aiming for a helpful, professional tone while keeping it approachable and clear. I've drafted a few options, settling on a straightforward statement of who I am, coupled with a helpful opening. I'm prioritizing clarity.\n\n\n", "format": "google-gemini-v1google-gemini-v1google-gemini-v1", "index": 0, "data": "Eq8HCqwHAXLI2nyVFk3BRAVz/oTEvlR8pz/j7gUvyAtIl7EfHuX9uXezaFfEMvu3k7vtquhsNcv25NRabSbSD4GKVPFf18E9LoHEFXE84keNijDMsTy9484iVJtqUnfyHcwL83FbMycgxP+Qt5gCZ28jZf2IbFPYboadoP9ZDOX73ULfRyWObLiDsBuc+nTKv3zpeb8TPQqZdhXzMszgkaA2UuQpjp72R3AUBO2ZSmXODpdM/qVdROhLwbq01nYpjJeQRBRG81/Z+Yx1j5xmyDl3IDS86OKxDgi+pnzUuSqnExTWkR3/vnRytEQ0seqLjlpdFoD3V0ctS/CU55JzyUTm4ItbpC+XNcMATggpG/4SuTmv0WAcNL5NdU/rlclcksq5ELDfSX51ope5F/PKYAIuzzy+facmfBcU6iDrhjl1T1lNYAXHS0frAvl5FpEWfrXi8jP/0XP1XBuv2ujhbs2zRR4j/yYLiCokWWt7OsFQusayYLXqlI5BdhVwqSFk0HyRQOEt6Cugb4jDfdhPzE+GElbXNZVen76meogVJO7MKJuhSlfiTv9BPbC+pHCXEndi6juuCRXyHJn1gOzEp1QHFIYWWJBXtCi1yITb7uLrdpJz0lMzPqlacSKreOoeOFZ6c1nNf5TmBzRddJTcFjdwYLziFOcqrqgl9uDUmgi+DPYEU3EyEmGsLU/hMLBfc7EgOQoHUmVKORJe4YezxazKmcRebmowxkbyGz9MRvlOZ+BobCZb67y1d7313zWmCCWePQG2jXgDzFCgCdaLY/l+/MtsYzymUY31T0l42yYUPcH5AQX98zWNThHFrh6njnCfWb1lpoJM1GearK4gqR5DoI70J8lRlgyYpu6xSxZM3/Wj+nHPeZEG/pzhPjWt6xjm99Qkxh8tRC2biEn6CFYW6mdlbGVDYPk3ZENLaaY7bGKhJtdnnTNof9MQPYopKPcjqdCT9xpvQX1ws9gUPJfQWVy8gYYhxwUkUyD2UGJ0zEs34GmUwcpcuRUanBdP/mf381OLx0ahZb7xFKR2Hnh6Smf2EHoiHAbuIAmxJdlPkv6qPVyaJiOQtVEoIf0vORP3RsmdNxx6RD5qnnBuUaKqFcOkffYdZhZwbCsqdvwcCOdLjJbX/7nVocV06P0dRygiRuCIG3oHgkA20DJvPJIJlwD54xLA27MabkOlvvDgmEnuNXHnaFYfGicD/yMnNHnsB8UCdwTWTLKsQdndXLb1995SLmcRwuOV1sn+N3s8Hg==" } ] }, "response_metadata": { "model_provider": "openai", "usage": { "prompt_tokens": 138, "completion_tokens": 216, "total_tokens": 354, "cost": 0.000717, "is_byok": false, "prompt_tokens_details": { "cached_tokens": 0, "audio_tokens": 0, "video_tokens": 0 }, "cost_details": { "upstream_inference_cost": null, "upstream_inference_prompt_cost": 0.000069, "upstream_inference_completions_cost": 0.000648 }, "completion_tokens_details": { "reasoning_tokens": 196, "image_tokens": 0 } } }, "tool_call_chunks": [], "id": "gen-1767007881-PSN5ZqC1A7usisuWbOxu", "tool_calls": [], "invalid_tool_calls": [], "name": "chat_agent" } } ``` This is the type of the data and when I do , `message.contentBlocks` I only see the `{type:"text"}` ### System Info Operating system: win32 x64 Package manager: pnpm Package manager version: 10.17.0 -------------------- zod -> 3.25.76 @langchain/anthropic -> 1.3.3 @langchain/core -> 1.1.8 langsmith -> 0.4.2 @langchain/classic -> 1.0.7 @langchain/openai -> 1.2.0 @langchain/textsplitters -> 1.0.1, 0.1.0 @langchain/community -> 1.1.1 @langchain/exa -> 1.0.1 @langchain/google-genai -> 2.1.3 @langchain/google-vertexai -> 2.1.3 @langchain/google-gauth -> 2.1.3 @langchain/google-common -> 2.1.3 @langchain/google-vertexai-web -> 2.1.3 @langchain/google-webauth -> 2.1.3 @langchain/groq -> 1.0.2 @langchain/langgraph -> 1.0.7 @langchain/langgraph-checkpoint -> 1.0.0 @langchain/langgraph-sdk -> 1.3.1 @langchain/langgraph-checkpoint-postgres -> 1.0.0 @langchain/ollama -> 1.1.0 @langchain/pinecone -> 1.0.1 @langchain/tavily -> 1.2.0 langchain -> 1.2.3
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: langchain-ai/langgraphjs#388