libs/core/langchain_core/messages/content.py PYTHON 1,489 lines View on github.com → Search inside
1"""Standard, multimodal content blocks for Large Language Model I/O.23This module provides standardized data structures for representing inputs to and outputs4from LLMs. The core abstraction is the **Content Block**, a `TypedDict`.56**Rationale**78Different LLM providers use distinct and incompatible API schemas. This module provides9a unified, provider-agnostic format to facilitate these interactions. A message to or10from a model is simply a list of content blocks, allowing for the natural interleaving11of text, images, and other content in a single ordered sequence.1213An adapter for a specific provider is responsible for translating this standard list of14blocks into the format required by its API.1516**Extensibility**1718Data **not yet mapped** to a standard block may be represented using the19`NonStandardContentBlock`, which allows for provider-specific data to be included20without losing the benefits of type checking and validation.2122Furthermore, provider-specific fields **within** a standard block are fully supported23by default in the `extras` field of each block. This allows for additional metadata24to be included without breaking the standard structure. For example, Google's thought25signature:2627```python28AIMessage(29    content=[30        {31            "type": "text",32            "text": "J'adore la programmation.",33            "extras": {"signature": "EpoWCpc..."},  # Thought signature34        }35    ], ...36)37```383940!!! note4142    Following widespread adoption of [PEP 728](https://peps.python.org/pep-0728/), we43    intend to add `extra_items=Any` as a param to Content Blocks. This will signify to44    type checkers that additional provider-specific fields are allowed outside of the45    `extras` field, and that will become the new standard approach to adding46    provider-specific metadata.4748    ??? note4950        **Example with PEP 728 provider-specific fields:**5152        ```python53        # Content block definition54        # NOTE: `extra_items=Any`55        class TextContentBlock(TypedDict, extra_items=Any):56            type: Literal["text"]57            id: NotRequired[str]58            text: str59            annotations: NotRequired[list[Annotation]]60            index: NotRequired[int]61        ```6263        ```python64        from langchain_core.messages.content import TextContentBlock6566        # Create a text content block with provider-specific fields67        my_block: TextContentBlock = {68            # Add required fields69            "type": "text",70            "text": "Hello, world!",71            # Additional fields not specified in the TypedDict72            # These are valid with PEP 728 and are typed as Any73            "openai_metadata": {"model": "gpt-4", "temperature": 0.7},74            "anthropic_usage": {"input_tokens": 10, "output_tokens": 20},75            "custom_field": "any value",76        }7778        # Mutating an existing block to add provider-specific fields79        openai_data = my_block["openai_metadata"]  # Type: Any80        ```8182**Example Usage**8384```python85# Direct construction86from langchain_core.messages.content import TextContentBlock, ImageContentBlock8788multimodal_message: AIMessage(89    content_blocks=[90        TextContentBlock(type="text", text="What is shown in this image?"),91        ImageContentBlock(92            type="image",93            url="https://www.langchain.com/images/brand/langchain_logo_text_w_white.png",94            mime_type="image/png",95        ),96    ]97)9899# Using factories100from langchain_core.messages.content import create_text_block, create_image_block101102multimodal_message: AIMessage(103    content=[104        create_text_block("What is shown in this image?"),105        create_image_block(106            url="https://www.langchain.com/images/brand/langchain_logo_text_w_white.png",107            mime_type="image/png",108        ),109    ]110)111```112113Factory functions offer benefits such as:114115- Automatic ID generation (when not provided)116- No need to manually specify the `type` field117"""118119from typing import Any, Literal, get_args, get_type_hints120121from typing_extensions import NotRequired, TypedDict122123from langchain_core.utils.utils import ensure_id124125126class Citation(TypedDict):127    """Annotation for citing data from a document.128129    !!! note130131        `start`/`end` indices refer to the **response text**,132        not the source text. This means that the indices are relative to the model's133        response, not the original document (as specified in the `url`).134135    !!! note "Factory function"136137        `create_citation` may also be used as a factory to create a `Citation`.138        Benefits include:139140        * Automatic ID generation (when not provided)141        * Required arguments strictly validated at creation time142    """143144    type: Literal["citation"]145    """Type of the content block. Used for discrimination."""146147    id: NotRequired[str]148    """Unique identifier for this content block.149150    Either:151152    - Generated by the provider153    - Generated by LangChain upon creation (`UUID4` prefixed with `'lc_'`))154    """155156    url: NotRequired[str]157    """URL of the document source."""158159    title: NotRequired[str]160    """Source document title.161162    For example, the page title for a web page or the title of a paper.163    """164165    start_index: NotRequired[int]166    """Start index of the **response text** (`TextContentBlock.text`)."""167168    end_index: NotRequired[int]169    """End index of the **response text** (`TextContentBlock.text`)"""170171    cited_text: NotRequired[str]172    """Excerpt of source text being cited."""173174    # NOTE: not including spans for the raw document text (such as `text_start_index`175    # and `text_end_index`) as this is not currently supported by any provider. The176    # thinking is that the `cited_text` should be sufficient for most use cases, and it177    # is difficult to reliably extract spans from the raw document text across file178    # formats or encoding schemes.179180    extras: NotRequired[dict[str, Any]]181    """Provider-specific metadata."""182183184class NonStandardAnnotation(TypedDict):185    """Provider-specific annotation format."""186187    type: Literal["non_standard_annotation"]188    """Type of the content block. Used for discrimination."""189190    id: NotRequired[str]191    """Unique identifier for this content block.192193    Either:194195    - Generated by the provider196    - Generated by LangChain upon creation (`UUID4` prefixed with `'lc_'`))197    """198199    value: dict[str, Any]200    """Provider-specific annotation data."""201202203Annotation = Citation | NonStandardAnnotation204"""A union of all defined `Annotation` types."""205206207class TextContentBlock(TypedDict):208    """Text output from a LLM.209210    This typically represents the main text content of a message, such as the response211    from a language model or the text of a user message.212213    !!! note "Factory function"214215        `create_text_block` may also be used as a factory to create a216        `TextContentBlock`. Benefits include:217218        * Automatic ID generation (when not provided)219        * Required arguments strictly validated at creation time220    """221222    type: Literal["text"]223    """Type of the content block. Used for discrimination."""224225    id: NotRequired[str]226    """Unique identifier for this content block.227228    Either:229230    - Generated by the provider231    - Generated by LangChain upon creation (`UUID4` prefixed with `'lc_'`))232    """233234    text: str235    """Block text."""236237    annotations: NotRequired[list[Annotation]]238    """`Citation`s and other annotations."""239240    index: NotRequired[int | str]241    """Index of block in aggregate response. Used during streaming."""242243    extras: NotRequired[dict[str, Any]]244    """Provider-specific metadata."""245246247class ToolCall(TypedDict):248    """Represents an AI's request to call a tool.249250    Example:251        ```python252        {"name": "foo", "args": {"a": 1}, "id": "123"}253        ```254255        This represents a request to call the tool named "foo" with arguments {"a": 1}256        and an identifier of "123".257258    !!! note "Factory function"259260        `create_tool_call` may also be used as a factory to create a261        `ToolCall`. Benefits include:262263        * Automatic ID generation (when not provided)264        * Required arguments strictly validated at creation time265    """266267    type: Literal["tool_call"]268    """Used for discrimination."""269270    id: str | None271    """An identifier associated with the tool call.272273    An identifier is needed to associate a tool call request with a tool274    call result in events when multiple concurrent tool calls are made.275    """276    # TODO: Consider making this NotRequired[str] in the future.277278    name: str279    """The name of the tool to be called."""280281    args: dict[str, Any]282    """The arguments to the tool call."""283284    index: NotRequired[int | str]285    """Index of block in aggregate response. Used during streaming."""286287    extras: NotRequired[dict[str, Any]]288    """Provider-specific metadata."""289290291class ToolCallChunk(TypedDict):292    """A chunk of a tool call (yielded when streaming).293294    When merging `ToolCallChunks` (e.g., via `AIMessageChunk.__add__`),295    all string attributes are concatenated. Chunks are only merged if their296    values of `index` are equal and not `None`.297298    Example:299    ```python300    left_chunks = [ToolCallChunk(name="foo", args='{"a":', index=0)]301    right_chunks = [ToolCallChunk(name=None, args="1}", index=0)]302303    (304        AIMessageChunk(content="", tool_call_chunks=left_chunks)305        + AIMessageChunk(content="", tool_call_chunks=right_chunks)306    ).tool_call_chunks == [ToolCallChunk(name="foo", args='{"a":1}', index=0)]307    ```308    """309310    # TODO: Consider making fields NotRequired[str] in the future.311312    type: Literal["tool_call_chunk"]313    """Used for serialization."""314315    id: str | None316    """An identifier associated with the tool call.317318    An identifier is needed to associate a tool call request with a tool319    call result in events when multiple concurrent tool calls are made.320    """321    # TODO: Consider making this NotRequired[str] in the future.322323    name: str | None324    """The name of the tool to be called."""325326    args: str | None327    """The arguments to the tool call."""328329    index: NotRequired[int | str]330    """The index of the tool call in a sequence."""331332    extras: NotRequired[dict[str, Any]]333    """Provider-specific metadata."""334335336class InvalidToolCall(TypedDict):337    """Allowance for errors made by LLM.338339    Here we add an `error` key to surface errors made during generation340    (e.g., invalid JSON arguments.)341    """342343    # TODO: Consider making fields NotRequired[str] in the future.344345    type: Literal["invalid_tool_call"]346    """Used for discrimination."""347348    id: str | None349    """An identifier associated with the tool call.350351    An identifier is needed to associate a tool call request with a tool352    call result in events when multiple concurrent tool calls are made.353    """354    # TODO: Consider making this NotRequired[str] in the future.355356    name: str | None357    """The name of the tool to be called."""358359    args: str | None360    """The arguments to the tool call."""361362    error: str | None363    """An error message associated with the tool call."""364365    index: NotRequired[int | str]366    """Index of block in aggregate response. Used during streaming."""367368    extras: NotRequired[dict[str, Any]]369    """Provider-specific metadata."""370371372class ServerToolCall(TypedDict):373    """Tool call that is executed server-side.374375    For example: code execution, web search, etc.376    """377378    type: Literal["server_tool_call"]379    """Used for discrimination."""380381    id: str382    """An identifier associated with the tool call."""383384    name: str385    """The name of the tool to be called."""386387    args: dict[str, Any]388    """The arguments to the tool call."""389390    index: NotRequired[int | str]391    """Index of block in aggregate response. Used during streaming."""392393    extras: NotRequired[dict[str, Any]]394    """Provider-specific metadata."""395396397class ServerToolCallChunk(TypedDict):398    """A chunk of a server-side tool call (yielded when streaming)."""399400    type: Literal["server_tool_call_chunk"]401    """Used for discrimination."""402403    name: NotRequired[str]404    """The name of the tool to be called."""405406    args: NotRequired[str]407    """JSON substring of the arguments to the tool call."""408409    id: NotRequired[str]410    """Unique identifier for this server tool call chunk.411412    Either:413414    - Generated by the provider415    - Generated by LangChain upon creation (`UUID4` prefixed with `'lc_'`))416    """417418    index: NotRequired[int | str]419    """Index of block in aggregate response. Used during streaming."""420421    extras: NotRequired[dict[str, Any]]422    """Provider-specific metadata."""423424425class ServerToolResult(TypedDict):426    """Result of a server-side tool call."""427428    type: Literal["server_tool_result"]429    """Used for discrimination."""430431    id: NotRequired[str]432    """Unique identifier for this server tool result.433434    Either:435436    - Generated by the provider437    - Generated by LangChain upon creation (`UUID4` prefixed with `'lc_'`))438    """439440    tool_call_id: str441    """ID of the corresponding server tool call."""442443    status: Literal["success", "error"]444    """Execution status of the server-side tool."""445446    output: NotRequired[Any]447    """Output of the executed tool."""448449    index: NotRequired[int | str]450    """Index of block in aggregate response. Used during streaming."""451452    extras: NotRequired[dict[str, Any]]453    """Provider-specific metadata."""454455456class ReasoningContentBlock(TypedDict):457    """Reasoning output from a LLM.458459    !!! note "Factory function"460461        `create_reasoning_block` may also be used as a factory to create a462        `ReasoningContentBlock`. Benefits include:463464        * Automatic ID generation (when not provided)465        * Required arguments strictly validated at creation time466    """467468    type: Literal["reasoning"]469    """Type of the content block. Used for discrimination."""470471    id: NotRequired[str]472    """Unique identifier for this content block.473474    Either:475476    - Generated by the provider477    - Generated by LangChain upon creation (`UUID4` prefixed with `'lc_'`))478    """479480    reasoning: NotRequired[str]481    """Reasoning text.482483    Either the thought summary or the raw reasoning text itself.484485    Often parsed from `<think>` tags in the model's response.486    """487488    index: NotRequired[int | str]489    """Index of block in aggregate response. Used during streaming."""490491    extras: NotRequired[dict[str, Any]]492    """Provider-specific metadata."""493494495# Note: `title` and `context` are fields that could be used to provide additional496# information about the file, such as a description or summary of its content.497# E.g. with Claude, you can provide a context for a file which is passed to the model.498class ImageContentBlock(TypedDict):499    """Image data.500501    !!! note "Factory function"502503        `create_image_block` may also be used as a factory to create an504        `ImageContentBlock`. Benefits include:505506        * Automatic ID generation (when not provided)507        * Required arguments strictly validated at creation time508    """509510    type: Literal["image"]511    """Type of the content block. Used for discrimination."""512513    id: NotRequired[str]514    """Unique identifier for this content block.515516    Either:517518    - Generated by the provider519    - Generated by LangChain upon creation (`UUID4` prefixed with `'lc_'`))520    """521522    file_id: NotRequired[str]523    """Reference to the image in an external file storage system.524525    For example, OpenAI or Anthropic's Files API.526    """527528    mime_type: NotRequired[str]529    """MIME type of the image.530531    Required for base64 data.532533    [Examples from IANA](https://www.iana.org/assignments/media-types/media-types.xhtml#image)534    """535536    index: NotRequired[int | str]537    """Index of block in aggregate response. Used during streaming."""538539    url: NotRequired[str]540    """URL of the image."""541542    base64: NotRequired[str]543    """Data as a base64 string."""544545    extras: NotRequired[dict[str, Any]]546    """Provider-specific metadata. This shouldn't be used for the image data itself."""547548549class VideoContentBlock(TypedDict):550    """Video data.551552    !!! note "Factory function"553554        `create_video_block` may also be used as a factory to create a555        `VideoContentBlock`. Benefits include:556557        * Automatic ID generation (when not provided)558        * Required arguments strictly validated at creation time559    """560561    type: Literal["video"]562    """Type of the content block. Used for discrimination."""563564    id: NotRequired[str]565    """Unique identifier for this content block.566567    Either:568569    - Generated by the provider570    - Generated by LangChain upon creation (`UUID4` prefixed with `'lc_'`))571    """572573    file_id: NotRequired[str]574    """Reference to the video in an external file storage system.575576    For example, OpenAI or Anthropic's Files API.577    """578579    mime_type: NotRequired[str]580    """MIME type of the video.581582    Required for base64 data.583584    [Examples from IANA](https://www.iana.org/assignments/media-types/media-types.xhtml#video)585    """586587    index: NotRequired[int | str]588    """Index of block in aggregate response. Used during streaming."""589590    url: NotRequired[str]591    """URL of the video."""592593    base64: NotRequired[str]594    """Data as a base64 string."""595596    extras: NotRequired[dict[str, Any]]597    """Provider-specific metadata. This shouldn't be used for the video data itself."""598599600class AudioContentBlock(TypedDict):601    """Audio data.602603    !!! note "Factory function"604605        `create_audio_block` may also be used as a factory to create an606        `AudioContentBlock`. Benefits include:607608        * Automatic ID generation (when not provided)609        * Required arguments strictly validated at creation time610    """611612    type: Literal["audio"]613    """Type of the content block. Used for discrimination."""614615    id: NotRequired[str]616    """Unique identifier for this content block.617618    Either:619620    - Generated by the provider621    - Generated by LangChain upon creation (`UUID4` prefixed with `'lc_'`))622    """623624    file_id: NotRequired[str]625    """Reference to the audio file in an external file storage system.626627    For example, OpenAI or Anthropic's Files API.628    """629630    mime_type: NotRequired[str]631    """MIME type of the audio.632633    Required for base64 data.634635    [Examples from IANA](https://www.iana.org/assignments/media-types/media-types.xhtml#audio)636    """637638    index: NotRequired[int | str]639    """Index of block in aggregate response. Used during streaming."""640641    url: NotRequired[str]642    """URL of the audio."""643644    base64: NotRequired[str]645    """Data as a base64 string."""646647    extras: NotRequired[dict[str, Any]]648    """Provider-specific metadata. This shouldn't be used for the audio data itself."""649650651class PlainTextContentBlock(TypedDict):652    """Plaintext data (e.g., from a `.txt` or `.md` document).653654    !!! note655656        A `PlainTextContentBlock` existed in `langchain-core<1.0.0`. Although the657        name has carried over, the structure has changed significantly. The only shared658        keys between the old and new versions are `type` and `text`, though the659        `type` value has changed from `'text'` to `'text-plain'`.660661    !!! note662663        Title and context are optional fields that may be passed to the model. See664        Anthropic [example](https://platform.claude.com/docs/en/build-with-claude/citations#citable-vs-non-citable-content).665666    !!! note "Factory function"667668        `create_plaintext_block` may also be used as a factory to create a669        `PlainTextContentBlock`. Benefits include:670671        * Automatic ID generation (when not provided)672        * Required arguments strictly validated at creation time673    """674675    type: Literal["text-plain"]676    """Type of the content block. Used for discrimination."""677678    id: NotRequired[str]679    """Unique identifier for this content block.680681    Either:682683    - Generated by the provider684    - Generated by LangChain upon creation (`UUID4` prefixed with `'lc_'`))685    """686687    file_id: NotRequired[str]688    """Reference to the plaintext file in an external file storage system.689690    For example, OpenAI or Anthropic's Files API.691    """692693    mime_type: Literal["text/plain"]694    """MIME type of the file.695696    Required for base64 data.697    """698699    index: NotRequired[int | str]700    """Index of block in aggregate response. Used during streaming."""701702    url: NotRequired[str]703    """URL of the plaintext."""704705    base64: NotRequired[str]706    """Data as a base64 string."""707708    text: NotRequired[str]709    """Plaintext content. This is optional if the data is provided as base64."""710711    title: NotRequired[str]712    """Title of the text data, e.g., the title of a document."""713714    context: NotRequired[str]715    """Context for the text, e.g., a description or summary of the text's content."""716717    extras: NotRequired[dict[str, Any]]718    """Provider-specific metadata. This shouldn't be used for the data itself."""719720721class FileContentBlock(TypedDict):722    """File data that doesn't fit into other multimodal block types.723724    This block is intended for files that are not images, audio, or plaintext. For725    example, it can be used for PDFs, Word documents, etc.726727    If the file is an image, audio, or plaintext, you should use the corresponding728    content block type (e.g., `ImageContentBlock`, `AudioContentBlock`,729    `PlainTextContentBlock`).730731    !!! note "Factory function"732733        `create_file_block` may also be used as a factory to create a734        `FileContentBlock`. Benefits include:735736        * Automatic ID generation (when not provided)737        * Required arguments strictly validated at creation time738    """739740    type: Literal["file"]741    """Type of the content block. Used for discrimination."""742743    id: NotRequired[str]744    """Unique identifier for this content block.745746    Used for tracking and referencing specific blocks (e.g., during streaming).747748    Not to be confused with `file_id`, which references an external file in a749    storage system.750751    Either:752753    - Generated by the provider754    - Generated by LangChain upon creation (`UUID4` prefixed with `'lc_'`))755    """756757    file_id: NotRequired[str]758    """Reference to the file in an external file storage system.759760    For example, a file ID from OpenAI's Files API or another cloud storage provider.761    This is distinct from `id`, which identifies the content block itself.762    """763764    mime_type: NotRequired[str]765    """MIME type of the file.766767    Required for base64 data.768769    [Examples from IANA](https://www.iana.org/assignments/media-types/media-types.xhtml)770    """771772    index: NotRequired[int | str]773    """Index of block in aggregate response. Used during streaming."""774775    url: NotRequired[str]776    """URL of the file."""777778    base64: NotRequired[str]779    """Data as a base64 string."""780781    extras: NotRequired[dict[str, Any]]782    """Provider-specific metadata. This shouldn't be used for the file data itself."""783784785# Future modalities to consider:786# - 3D models787# - Tabular data788789790class NonStandardContentBlock(TypedDict):791    """Provider-specific content data.792793    This block contains data for which there is not yet a standard type.794795    The purpose of this block should be to simply hold a provider-specific payload.796    If a provider's non-standard output includes reasoning and tool calls, it should be797    the adapter's job to parse that payload and emit the corresponding standard798    `ReasoningContentBlock` and `ToolCalls`.799800    Has no `extras` field, as provider-specific data should be included in the801    `value` field.802803    !!! note "Factory function"804805        `create_non_standard_block` may also be used as a factory to create a806        `NonStandardContentBlock`. Benefits include:807808        * Automatic ID generation (when not provided)809        * Required arguments strictly validated at creation time810    """811812    type: Literal["non_standard"]813    """Type of the content block. Used for discrimination."""814815    id: NotRequired[str]816    """Unique identifier for this content block.817818    Either:819820    - Generated by the provider821    - Generated by LangChain upon creation (`UUID4` prefixed with `'lc_'`))822    """823824    value: dict[str, Any]825    """Provider-specific content data."""826827    index: NotRequired[int | str]828    """Index of block in aggregate response. Used during streaming."""829830831# --- Aliases ---832DataContentBlock = (833    ImageContentBlock834    | VideoContentBlock835    | AudioContentBlock836    | PlainTextContentBlock837    | FileContentBlock838)839"""A union of all defined multimodal data `ContentBlock` types."""840841ToolContentBlock = (842    ToolCall | ToolCallChunk | ServerToolCall | ServerToolCallChunk | ServerToolResult843)844845ContentBlock = (846    TextContentBlock847    | InvalidToolCall848    | ReasoningContentBlock849    | NonStandardContentBlock850    | DataContentBlock851    | ToolContentBlock852)853"""A union of all defined `ContentBlock` types and aliases."""854855856KNOWN_BLOCK_TYPES = {857    # Text output858    "text",859    "reasoning",860    # Tools861    "tool_call",862    "invalid_tool_call",863    "tool_call_chunk",864    # Multimodal data865    "image",866    "audio",867    "file",868    "text-plain",869    "video",870    # Server-side tool calls871    "server_tool_call",872    "server_tool_call_chunk",873    "server_tool_result",874    # Catch-all875    "non_standard",876    # citation and non_standard_annotation intentionally omitted877}878"""These are block types known to `langchain-core >= 1.0.0`.879880If a block has a type not in this set, it is considered to be provider-specific.881"""882883884def _get_data_content_block_types() -> tuple[str, ...]:885    """Get type literals from DataContentBlock union members dynamically.886887    Example: ("image", "video", "audio", "text-plain", "file")888889    Note that old style multimodal blocks type literals with new style blocks.890    Specifically, "image", "audio", and "file".891892    See the docstring of `_normalize_messages` in `language_models._utils` for details.893    """894    data_block_types = []895896    for block_type in get_args(DataContentBlock):897        hints = get_type_hints(block_type)898        if "type" in hints:899            type_annotation = hints["type"]900            if hasattr(type_annotation, "__args__"):901                # This is a Literal type, get the literal value902                literal_value = type_annotation.__args__[0]903                data_block_types.append(literal_value)904905    return tuple(data_block_types)906907908def is_data_content_block(block: dict) -> bool:909    """Check if the provided content block is a data content block.910911    Returns True for both v0 (old-style) and v1 (new-style) multimodal data blocks.912913    Args:914        block: The content block to check.915916    Returns:917        `True` if the content block is a data content block, `False` otherwise.918    """919    if block.get("type") not in _get_data_content_block_types():920        return False921922    if any(key in block for key in ("url", "base64", "file_id", "text")):923        # Type is valid and at least one data field is present924        # (Accepts old-style image and audio URLContentBlock)925926        # 'text' is checked to support v0 PlainTextContentBlock types927        # We must guard against new style TextContentBlock which also has 'text' `type`928        # by ensuring the presence of `source_type`929        if block["type"] == "text" and "source_type" not in block:  # noqa: SIM103  # This is more readable930            return False931932        return True933934    if "source_type" in block:935        # Old-style content blocks had possible types of 'image', 'audio', and 'file'936        # which is not captured in the prior check937        source_type = block["source_type"]938        if (source_type == "url" and "url" in block) or (939            source_type == "base64" and "data" in block940        ):941            return True942        if (source_type == "id" and "id" in block) or (943            source_type == "text" and "url" in block944        ):945            return True946947    return False948949950def create_text_block(951    text: str,952    *,953    id: str | None = None,954    annotations: list[Annotation] | None = None,955    index: int | str | None = None,956    **kwargs: Any,957) -> TextContentBlock:958    """Create a `TextContentBlock`.959960    Args:961        text: The text content of the block.962        id: Content block identifier.963964            Generated automatically if not provided.965        annotations: `Citation`s and other annotations for the text.966        index: Index of block in aggregate response.967968            Used during streaming.969970    Returns:971        A properly formatted `TextContentBlock`.972973    !!! note974975        The `id` is generated automatically if not provided, using a UUID4 format976        prefixed with `'lc_'` to indicate it is a LangChain-generated ID.977    """978    block = TextContentBlock(979        type="text",980        text=text,981        id=ensure_id(id),982    )983    if annotations is not None:984        block["annotations"] = annotations985    if index is not None:986        block["index"] = index987988    extras = {k: v for k, v in kwargs.items() if v is not None}989    if extras:990        block["extras"] = extras991992    return block993994995def create_image_block(996    *,997    url: str | None = None,998    base64: str | None = None,999    file_id: str | None = None,1000    mime_type: str | None = None,1001    id: str | None = None,1002    index: int | str | None = None,1003    **kwargs: Any,1004) -> ImageContentBlock:1005    """Create an `ImageContentBlock`.10061007    Args:1008        url: URL of the image.1009        base64: Base64-encoded image data.1010        file_id: ID of the image file from a file storage system.1011        mime_type: MIME type of the image.10121013            Required for base64 data.1014        id: Content block identifier.10151016            Generated automatically if not provided.1017        index: Index of block in aggregate response.10181019            Used during streaming.10201021    Returns:1022        A properly formatted `ImageContentBlock`.10231024    Raises:1025        ValueError: If no image source is provided or if `base64` is used without1026            `mime_type`.10271028    !!! note10291030        The `id` is generated automatically if not provided, using a UUID4 format1031        prefixed with `'lc_'` to indicate it is a LangChain-generated ID.1032    """1033    if not any([url, base64, file_id]):1034        msg = "Must provide one of: url, base64, or file_id"1035        raise ValueError(msg)10361037    block = ImageContentBlock(type="image", id=ensure_id(id))10381039    if url is not None:1040        block["url"] = url1041    if base64 is not None:1042        block["base64"] = base641043    if file_id is not None:1044        block["file_id"] = file_id1045    if mime_type is not None:1046        block["mime_type"] = mime_type1047    if index is not None:1048        block["index"] = index10491050    extras = {k: v for k, v in kwargs.items() if v is not None}1051    if extras:1052        block["extras"] = extras10531054    return block105510561057def create_video_block(1058    *,1059    url: str | None = None,1060    base64: str | None = None,1061    file_id: str | None = None,1062    mime_type: str | None = None,1063    id: str | None = None,1064    index: int | str | None = None,1065    **kwargs: Any,1066) -> VideoContentBlock:1067    """Create a `VideoContentBlock`.10681069    Args:1070        url: URL of the video.1071        base64: Base64-encoded video data.1072        file_id: ID of the video file from a file storage system.1073        mime_type: MIME type of the video.10741075            Required for base64 data.1076        id: Content block identifier.10771078            Generated automatically if not provided.1079        index: Index of block in aggregate response.10801081            Used during streaming.10821083    Returns:1084        A properly formatted `VideoContentBlock`.10851086    Raises:1087        ValueError: If no video source is provided or if `base64` is used without1088            `mime_type`.10891090    !!! note10911092        The `id` is generated automatically if not provided, using a UUID4 format1093        prefixed with `'lc_'` to indicate it is a LangChain-generated ID.1094    """1095    if not any([url, base64, file_id]):1096        msg = "Must provide one of: url, base64, or file_id"1097        raise ValueError(msg)10981099    if base64 and not mime_type:1100        msg = "mime_type is required when using base64 data"1101        raise ValueError(msg)11021103    block = VideoContentBlock(type="video", id=ensure_id(id))11041105    if url is not None:1106        block["url"] = url1107    if base64 is not None:1108        block["base64"] = base641109    if file_id is not None:1110        block["file_id"] = file_id1111    if mime_type is not None:1112        block["mime_type"] = mime_type1113    if index is not None:1114        block["index"] = index11151116    extras = {k: v for k, v in kwargs.items() if v is not None}1117    if extras:1118        block["extras"] = extras11191120    return block112111221123def create_audio_block(1124    *,1125    url: str | None = None,1126    base64: str | None = None,1127    file_id: str | None = None,1128    mime_type: str | None = None,1129    id: str | None = None,1130    index: int | str | None = None,1131    **kwargs: Any,1132) -> AudioContentBlock:1133    """Create an `AudioContentBlock`.11341135    Args:1136        url: URL of the audio.1137        base64: Base64-encoded audio data.1138        file_id: ID of the audio file from a file storage system.1139        mime_type: MIME type of the audio.11401141            Required for base64 data.1142        id: Content block identifier.11431144            Generated automatically if not provided.1145        index: Index of block in aggregate response.11461147            Used during streaming.11481149    Returns:1150        A properly formatted `AudioContentBlock`.11511152    Raises:1153        ValueError: If no audio source is provided or if `base64` is used without1154            `mime_type`.11551156    !!! note11571158        The `id` is generated automatically if not provided, using a UUID4 format1159        prefixed with `'lc_'` to indicate it is a LangChain-generated ID.1160    """1161    if not any([url, base64, file_id]):1162        msg = "Must provide one of: url, base64, or file_id"1163        raise ValueError(msg)11641165    if base64 and not mime_type:1166        msg = "mime_type is required when using base64 data"1167        raise ValueError(msg)11681169    block = AudioContentBlock(type="audio", id=ensure_id(id))11701171    if url is not None:1172        block["url"] = url1173    if base64 is not None:1174        block["base64"] = base641175    if file_id is not None:1176        block["file_id"] = file_id1177    if mime_type is not None:1178        block["mime_type"] = mime_type1179    if index is not None:1180        block["index"] = index11811182    extras = {k: v for k, v in kwargs.items() if v is not None}1183    if extras:1184        block["extras"] = extras11851186    return block118711881189def create_file_block(1190    *,1191    url: str | None = None,1192    base64: str | None = None,1193    file_id: str | None = None,1194    mime_type: str | None = None,1195    id: str | None = None,1196    index: int | str | None = None,1197    **kwargs: Any,1198) -> FileContentBlock:1199    """Create a `FileContentBlock`.12001201    Args:1202        url: URL of the file.1203        base64: Base64-encoded file data.1204        file_id: ID of the file from a file storage system.1205        mime_type: MIME type of the file.12061207            Required for base64 data.1208        id: Content block identifier.12091210            Generated automatically if not provided.1211        index: Index of block in aggregate response.12121213            Used during streaming.12141215    Returns:1216        A properly formatted `FileContentBlock`.12171218    Raises:1219        ValueError: If no file source is provided or if `base64` is used without1220            `mime_type`.12211222    !!! note12231224        The `id` is generated automatically if not provided, using a UUID4 format1225        prefixed with `'lc_'` to indicate it is a LangChain-generated ID.1226    """1227    if not any([url, base64, file_id]):1228        msg = "Must provide one of: url, base64, or file_id"1229        raise ValueError(msg)12301231    if base64 and not mime_type:1232        msg = "mime_type is required when using base64 data"1233        raise ValueError(msg)12341235    block = FileContentBlock(type="file", id=ensure_id(id))12361237    if url is not None:1238        block["url"] = url1239    if base64 is not None:1240        block["base64"] = base641241    if file_id is not None:1242        block["file_id"] = file_id1243    if mime_type is not None:1244        block["mime_type"] = mime_type1245    if index is not None:1246        block["index"] = index12471248    extras = {k: v for k, v in kwargs.items() if v is not None}1249    if extras:1250        block["extras"] = extras12511252    return block125312541255def create_plaintext_block(1256    text: str | None = None,1257    url: str | None = None,1258    base64: str | None = None,1259    file_id: str | None = None,1260    title: str | None = None,1261    context: str | None = None,1262    id: str | None = None,1263    index: int | str | None = None,1264    **kwargs: Any,1265) -> PlainTextContentBlock:1266    """Create a `PlainTextContentBlock`.12671268    Args:1269        text: The plaintext content.1270        url: URL of the plaintext file.1271        base64: Base64-encoded plaintext data.1272        file_id: ID of the plaintext file from a file storage system.1273        title: Title of the text data.1274        context: Context or description of the text content.1275        id: Content block identifier.12761277            Generated automatically if not provided.1278        index: Index of block in aggregate response.12791280            Used during streaming.12811282    Returns:1283        A properly formatted `PlainTextContentBlock`.12841285    !!! note12861287        The `id` is generated automatically if not provided, using a UUID4 format1288        prefixed with `'lc_'` to indicate it is a LangChain-generated ID.1289    """1290    block = PlainTextContentBlock(1291        type="text-plain",1292        mime_type="text/plain",1293        id=ensure_id(id),1294    )12951296    if text is not None:1297        block["text"] = text1298    if url is not None:1299        block["url"] = url1300    if base64 is not None:1301        block["base64"] = base641302    if file_id is not None:1303        block["file_id"] = file_id1304    if title is not None:1305        block["title"] = title1306    if context is not None:1307        block["context"] = context1308    if index is not None:1309        block["index"] = index13101311    extras = {k: v for k, v in kwargs.items() if v is not None}1312    if extras:1313        block["extras"] = extras13141315    return block131613171318def create_tool_call(1319    name: str,1320    args: dict[str, Any],1321    *,1322    id: str | None = None,1323    index: int | str | None = None,1324    **kwargs: Any,1325) -> ToolCall:1326    """Create a `ToolCall`.13271328    Args:1329        name: The name of the tool to be called.1330        args: The arguments to the tool call.1331        id: An identifier for the tool call.13321333            Generated automatically if not provided.1334        index: Index of block in aggregate response.13351336            Used during streaming.13371338    Returns:1339        A properly formatted `ToolCall`.13401341    !!! note13421343        The `id` is generated automatically if not provided, using a UUID4 format1344        prefixed with `'lc_'` to indicate it is a LangChain-generated ID.1345    """1346    block = ToolCall(1347        type="tool_call",1348        name=name,1349        args=args,1350        id=ensure_id(id),1351    )13521353    if index is not None:1354        block["index"] = index13551356    extras = {k: v for k, v in kwargs.items() if v is not None}1357    if extras:1358        block["extras"] = extras13591360    return block136113621363def create_reasoning_block(1364    reasoning: str | None = None,1365    id: str | None = None,1366    index: int | str | None = None,1367    **kwargs: Any,1368) -> ReasoningContentBlock:1369    """Create a `ReasoningContentBlock`.13701371    Args:1372        reasoning: The reasoning text or thought summary.1373        id: Content block identifier.13741375            Generated automatically if not provided.1376        index: Index of block in aggregate response.13771378            Used during streaming.13791380    Returns:1381        A properly formatted `ReasoningContentBlock`.13821383    !!! note13841385        The `id` is generated automatically if not provided, using a UUID4 format1386        prefixed with `'lc_'` to indicate it is a LangChain-generated ID.1387    """1388    block = ReasoningContentBlock(1389        type="reasoning",1390        reasoning=reasoning or "",1391        id=ensure_id(id),1392    )13931394    if index is not None:1395        block["index"] = index13961397    extras = {k: v for k, v in kwargs.items() if v is not None}1398    if extras:1399        block["extras"] = extras14001401    return block140214031404def create_citation(1405    *,1406    url: str | None = None,1407    title: str | None = None,1408    start_index: int | None = None,1409    end_index: int | None = None,1410    cited_text: str | None = None,1411    id: str | None = None,1412    **kwargs: Any,1413) -> Citation:1414    """Create a `Citation`.14151416    Args:1417        url: URL of the document source.1418        title: Source document title.1419        start_index: Start index in the response text where citation applies.1420        end_index: End index in the response text where citation applies.1421        cited_text: Excerpt of source text being cited.1422        id: Content block identifier.14231424            Generated automatically if not provided.14251426    Returns:1427        A properly formatted `Citation`.14281429    !!! note14301431        The `id` is generated automatically if not provided, using a UUID4 format1432        prefixed with `'lc_'` to indicate it is a LangChain-generated ID.1433    """1434    block = Citation(type="citation", id=ensure_id(id))14351436    if url is not None:1437        block["url"] = url1438    if title is not None:1439        block["title"] = title1440    if start_index is not None:1441        block["start_index"] = start_index1442    if end_index is not None:1443        block["end_index"] = end_index1444    if cited_text is not None:1445        block["cited_text"] = cited_text14461447    extras = {k: v for k, v in kwargs.items() if v is not None}1448    if extras:1449        block["extras"] = extras14501451    return block145214531454def create_non_standard_block(1455    value: dict[str, Any],1456    *,1457    id: str | None = None,1458    index: int | str | None = None,1459) -> NonStandardContentBlock:1460    """Create a `NonStandardContentBlock`.14611462    Args:1463        value: Provider-specific content data.1464        id: Content block identifier.14651466            Generated automatically if not provided.1467        index: Index of block in aggregate response.14681469            Used during streaming.14701471    Returns:1472        A properly formatted `NonStandardContentBlock`.14731474    !!! note14751476        The `id` is generated automatically if not provided, using a UUID4 format1477        prefixed with `'lc_'` to indicate it is a LangChain-generated ID.1478    """1479    block = NonStandardContentBlock(1480        type="non_standard",1481        value=value,1482        id=ensure_id(id),1483    )14841485    if index is not None:1486        block["index"] = index14871488    return block

Code quality findings 10

Ensure functions have docstrings for documentation
missing-docstring
def create_text_block(
Ensure functions have docstrings for documentation
missing-docstring
def create_image_block(
Ensure functions have docstrings for documentation
missing-docstring
def create_video_block(
Ensure functions have docstrings for documentation
missing-docstring
def create_audio_block(
Ensure functions have docstrings for documentation
missing-docstring
def create_file_block(
Ensure functions have docstrings for documentation
missing-docstring
def create_plaintext_block(
Ensure functions have docstrings for documentation
missing-docstring
def create_tool_call(
Ensure functions have docstrings for documentation
missing-docstring
def create_reasoning_block(
Ensure functions have docstrings for documentation
missing-docstring
def create_citation(
Ensure functions have docstrings for documentation
missing-docstring
def create_non_standard_block(

Get this view in your editor

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