Repository navigation
Conversation
LangGraphAgent passed the last message's `content` straight to `Part.from_text`. LangChain message content can be a list of content blocks, for example a reasoning block and a text block. `Part.from_text` then fails pydantic validation and the agent raises instead of answering. When the content is a list, use the message's `.text` property, which keeps only the text. String content is passed through unchanged, so installs still on langchain-core 0.3, where `.text` is a method, keep working.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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):
2. Or, if no issue exists, describe the change:
Problem:
LangGraphAgent._run_async_impltakesfinal_state['messages'][-1].contentand passes it straight totypes.Part.from_text(text=...). In LangChain,BaseMessage.contentisstr | list[str | dict]. Chat models return the list form in common setups: Gemini 3 models throughChatGoogleGenerativeAI(langchain-google-genai 4.x returns text blocks for them; langchain-ai/langchain-google#1460 shows the streamed form), Vertex with a thinking budget (langchain-ai/langchain-google#1621), and any model set tooutput_version="v1". ThenPart.from_textfails validation and the agent raises on every turn instead of answering:Repro (a real compiled graph through
InMemoryRunner; the node returns what such a model returns):On main it raises the
ValidationErrorabove.Solution:
When the content is a list, use the message's
.textproperty. It keeps plain strings andtype == "text"blocks and joins them into astr. String content is passed through as before, so graphs that work today are unchanged..textis a property on every langchain-core 1.x, which ADK'slanggraph>=1.0.10floor requires. On langchain-core 0.3, which installs from when ADK required langgraph 0.x can still have,.textis a method; string content never reaches it there, so those installs keep working.Non-text blocks (reasoning, images) are left out of the reply. Mapping reasoning blocks to ADK thought parts would be a separate change.
With this change the repro prints:
Testing Plan
Unit Tests:
New test
test_langgraph_agent_reads_text_from_content_blocksintests/unittests/agents/test_langgraph_agent.py, next totest_langgraph_agent_runs_real_compiled_state_graph. It runs a real compiledStateGraph(MessagesState)whose node returns a reasoning block and a text block.Without the source change it fails with the
ValidationErrorabove (1 failed, 10 passed). With it:The whole
tests/unittests/agentsfolder: 975 passed, 1 xfailed (974 passed on main). I also ran the file on langgraph 0.4.8 with langchain-core 0.3.79: the 10 existing tests pass with the change, as on main; the new list test fails there on both, since 0.3 has no.textproperty. pyink and isort leave both files unchanged.Manual End-to-End (E2E) Tests:
The repro above stands in for a manual run: a real compiled LangGraph graph through
InMemoryRunner, with the node returning the block content a Gemini 3 oroutput_version="v1"model gives, in place of a live model call. Versions: langgraph 1.2.20, langchain-core 1.7.6.Checklist
Additional context
A list with no text blocks gives an empty text part instead of a crash.