libs/core/langchain_core/messages/block_translators/bedrock.py PYTHON 109 lines View on github.com → Search inside
1"""Derivations of standard content blocks from Bedrock content."""23from langchain_core.messages import AIMessage, AIMessageChunk4from langchain_core.messages import content as types5from langchain_core.messages.block_translators.anthropic import (6    _convert_to_v1_from_anthropic,7)8910def _convert_to_v1_from_bedrock(message: AIMessage) -> list[types.ContentBlock]:11    """Convert bedrock message content to v1 format."""12    out = _convert_to_v1_from_anthropic(message)1314    content_tool_call_ids = {15        block.get("id")16        for block in out17        if isinstance(block, dict) and block.get("type") == "tool_call"18    }19    for tool_call in message.tool_calls:20        if (id_ := tool_call.get("id")) and id_ not in content_tool_call_ids:21            tool_call_block: types.ToolCall = {22                "type": "tool_call",23                "id": id_,24                "name": tool_call["name"],25                "args": tool_call["args"],26            }27            if "index" in tool_call:28                tool_call_block["index"] = tool_call["index"]  # type: ignore[typeddict-item]29            if "extras" in tool_call:30                tool_call_block["extras"] = tool_call["extras"]  # type: ignore[typeddict-item]31            out.append(tool_call_block)32    return out333435def _convert_to_v1_from_bedrock_chunk(36    message: AIMessageChunk,37) -> list[types.ContentBlock]:38    """Convert bedrock message chunk content to v1 format."""39    if (40        message.content == ""41        and not message.additional_kwargs42        and not message.tool_calls43    ):44        # Bedrock outputs multiple chunks containing response metadata45        return []4647    out = _convert_to_v1_from_anthropic(message)4849    if (50        message.tool_call_chunks51        and not message.content52        and message.chunk_position != "last"  # keep tool_calls if aggregated53    ):54        for tool_call_chunk in message.tool_call_chunks:55            tc: types.ToolCallChunk = {56                "type": "tool_call_chunk",57                "id": tool_call_chunk.get("id"),58                "name": tool_call_chunk.get("name"),59                "args": tool_call_chunk.get("args"),60            }61            if (idx := tool_call_chunk.get("index")) is not None:62                tc["index"] = idx63            out.append(tc)64    return out656667def translate_content(message: AIMessage) -> list[types.ContentBlock]:68    """Derive standard content blocks from a message with Bedrock content.6970    Args:71        message: The message to translate.7273    Returns:74        The derived content blocks.75    """76    if "claude" not in message.response_metadata.get("model_name", "").lower():77        raise NotImplementedError  # fall back to best-effort parsing78    return _convert_to_v1_from_bedrock(message)798081def translate_content_chunk(message: AIMessageChunk) -> list[types.ContentBlock]:82    """Derive standard content blocks from a message chunk with Bedrock content.8384    Args:85        message: The message chunk to translate.8687    Returns:88        The derived content blocks.89    """90    # TODO: add model_name to all Bedrock chunks and update core merging logic91    # to not append during aggregation. Then raise NotImplementedError here if92    # not an Anthropic model to fall back to best-effort parsing.93    return _convert_to_v1_from_bedrock_chunk(message)949596def _register_bedrock_translator() -> None:97    """Register the bedrock translator with the central registry.9899    Run automatically when the module is imported.100    """101    from langchain_core.messages.block_translators import (  # noqa: PLC0415102        register_translator,103    )104105    register_translator("bedrock", translate_content, translate_content_chunk)106107108_register_bedrock_translator()

Code quality findings 1

Overuse may indicate design issues; consider polymorphism
isinstance-overuse
if isinstance(block, dict) and block.get("type") == "tool_call"

Get this view in your editor

Same data, no extra tab — call code_get_file + code_get_findings over MCP from Claude/Cursor/Copilot.