Skip to content

fix(langgraph): restore currency agent sample (Gemini model, LangChain 1.x, Frankfurter API) - #723

Open
naveenkarmegam wants to merge 3 commits into
a2aproject:mainfrom
naveenkarmegam:fix/langgraph-currency-agent
Open

naveenkarmegam wants to merge 3 commits into
a2aproject:mainfrom
naveenkarmegam:fix/langgraph-currency-agent

Conversation

@naveenkarmegam

Copy link
Copy Markdown

Description

The LangGraph currency agent sample (samples/python/agents/langgraph) currently fails on every request with a JSON-RPC -32603 Internal error. This PR fixes the three underlying causes described in #722. There is one commit per cause, plus a small test-client fix.

Changes

  1. fix(langgraph): use frankfurter.dev v1 endpoint
    api.frankfurter.app now returns 301 to api.frankfurter.dev/v1. httpx doesn't follow redirects by default, so the tool always returned API request failed. This commit updates the tool URL and the README docs link.

  2. fix(langgraph): upgrade to LangChain/LangGraph 1.x and gemini-3.8-flash

    • gemini-2.0-flash has been retired and returns 404 NOT_FOUND. Switched to gemini-3.8-flash.
    • Current Gemini models need thought signatures on function calls, which langchain-google-genai 2.x doesn't send (400 Function call is missing a thought_signature). Bumped langchain-google-genai>=3.0.0, langgraph>=1.0.0 and langchain-openai>=1.0.0, added langchain>=1.0.0, and regenerated uv.lock.
    • On LangGraph 1.x, create_react_agent(..., response_format=...) makes an extra model call that ends on a model turn, and Gemini rejects it (400 Requests ending with a model turn are not supported). Replaced it with langchain.agents.create_agent + ToolStrategy(ResponseFormat), which returns the structured response through a tool call.
    • Registered ResponseFormat with the checkpointer's JsonPlusSerializer. Without this, LangGraph 1.x warns that restoring it between turns "will be blocked in a future version", which would break multi-turn conversations.

    The model change and the dependency upgrade are in one commit because neither works without the other.

  3. fix(langgraph): raise test client HTTP timeout
    A full request (model → tool → structured response) can take more than httpx's default 5 s, so test_client.py failed with A2AClientTimeoutError even though the server succeeded. Raised the timeout to 60 s.

Testing

Ran uv run app and app/test_client.py locally (Windows 11, Python 3.12, a2a-sdk 0.3.0):

  • Single-turn message/send: "how much is 10 USD in INR?" → completed with the converted amount
  • Multi-turn: "exchange rate for 1 USD?" → input-required → "CAD" → completed
  • Streaming message/stream: submitted → working updates → artifact → completed
  • No warnings or errors in the server log
  • model_source=openai path still builds the agent with langchain-openai 1.x
  • ruff check / ruff format: no new findings in changed lines (the file's pre-existing findings are unchanged)

Out of scope

About 22 other Python samples still reference gemini-2.0-flash and/or api.frankfurter.app and are likely affected too. I've kept this PR to the LangGraph sample and can follow up separately.

Fixes #722 🦕

api.frankfurter.app now responds with a 301 redirect to
api.frankfurter.dev/v1. httpx does not follow redirects by default, so
raise_for_status() failed and get_exchange_rate always returned an
"API request failed" error. Point the tool and the README docs link at
the new location.
gemini-2.0-flash has been retired and the Gemini API now returns
404 NOT_FOUND for it. Current Gemini models require thought signatures
on function calls, which langchain-google-genai 2.x does not send
("Function call is missing a thought_signature"), so move to
langchain-google-genai 3.x and the LangChain/LangGraph 1.x stack it
requires.

On LangGraph 1.x, create_react_agent's response_format makes an extra
model call that ends with a model turn, which Gemini rejects ("Requests
ending with a model turn are not supported"). Switch to
langchain.agents.create_agent with ToolStrategy(ResponseFormat) so the
structured response is returned as a tool call instead.

Also register ResponseFormat with the checkpoint serializer so restoring
it between turns does not trigger LangGraph's "unregistered type"
deserialization warning.
httpx defaults to a 5 second timeout, and a full request against the
agent (model call, tool call, structured response) can take longer,
which made test_client.py fail with A2AClientTimeoutError.

This branch has not been deployed

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: LangGraph currency agent sample fails with "Internal error" (retired Gemini model, outdated deps, Frankfurter API redirect)

1 participant