Skip to content

fix(models): preserve string content in anthropic tool results#5373

Open
lawrence3699 wants to merge 2 commits intogoogle:mainfrom
lawrence3699:fix/anthropic-string-content
Open

fix(models): preserve string content in anthropic tool results#5373
lawrence3699 wants to merge 2 commits intogoogle:mainfrom
lawrence3699:fix/anthropic-string-content

Conversation

@lawrence3699
Copy link
Copy Markdown

Please ensure you have read the contribution guide before creating a pull request.

Link to Issue or Description of Change

1. Link to an existing issue (if applicable):

Problem:
part_to_message_block() currently assumes every function_response.response["content"] value is a list-like content payload. LoadSkillResourceTool returns a plain string in content, so Claude tool results get flattened character-by-character with newlines inserted.

On current main, this deterministic repro returns the wrong content:

from google.adk.models.anthropic_llm import part_to_message_block
from google.genai import types

part = types.Part.from_function_response(
    name="load_skill_resource",
    response={
        "skill_name": "my-skill",
        "file_path": "references/doc.md",
        "content": "Hello",
    },
)
print(repr(part_to_message_block(part)["content"]))
# 'H\\ne\\nl\\nl\\no'

Solution:
Keep the existing list handling for Anthropic content blocks, but branch on the runtime type of response["content"]:

  • list: preserve the current block flattening behavior
  • dict: JSON-serialize it
  • scalar/string (including ""): pass it through as a scalar string

That preserves LoadSkillResourceTool string payloads without changing the existing content list contract.

Testing Plan

Unit Tests:

  • I have added or updated unit tests for my change.
  • All unit tests pass locally.

Passed pytest results:

  • pytest tests/unittests/models/test_anthropic_llm.py -q
    • 43 passed, 1 warning in 1.38s
  • pytest tests/unittests/tools/test_skill_toolset.py -k 'load_resource_run_async' -q
    • 10 passed, 71 deselected, 2 warnings in 1.27s

Manual End-to-End (E2E) Tests:

Minimal local repro after the patch:

from google.adk.models.anthropic_llm import part_to_message_block
from google.genai import types

for value in ["Hello", ""]:
    part = types.Part.from_function_response(
        name="load_skill_resource",
        response={
            "skill_name": "my-skill",
            "file_path": "references/doc.md",
            "content": value,
        },
    )
    print(repr(value), '=>', repr(part_to_message_block(part)["content"]))

Console output:

'Hello' => 'Hello'
'' => ''

Checklist

  • I have read the CONTRIBUTING.md document.
  • I have performed a self-review of my own code.
  • I have commented my code, particularly in hard-to-understand areas.
  • I have added tests that prove my fix is effective or that my feature works.
  • New and existing unit tests pass locally with my changes.
  • I have manually tested my changes end-to-end.
  • Any dependent changes have been merged and published in downstream modules.

Additional context

I also checked upstream overlap before opening this PR:

  • #5364 already has open PR #5366, so I did not touch that nearby schema bug.
  • I found no open PR for #5358 or another in-flight part_to_message_block() string-content fix.

@google-cla
Copy link
Copy Markdown

google-cla bot commented Apr 17, 2026

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

@adk-bot adk-bot added the models [Component] Issues related to model support label Apr 17, 2026
@adk-bot
Copy link
Copy Markdown
Collaborator

adk-bot commented Apr 17, 2026

Response from ADK Triaging Agent

Hello @lawrence3699, thank you for your contribution!

It looks like the Contributor License Agreement (CLA) has not been signed. Please sign the CLA to proceed with the review process. You can find more information in the "cla/google" check at the bottom of the pull request.

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

models [Component] Issues related to model support

Projects

None yet

Development

Successfully merging this pull request may close these issues.

AnthropicLlm.part_to_message_block() iterates "content" string char-by-character when LoadSkillResourceTool is used with Claude

2 participants