-
Notifications
You must be signed in to change notification settings - Fork 757
feat: Add LangGraph Restaurant Finder sample agent #508
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
feat: Add LangGraph Restaurant Finder sample agent #508
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code Review
This pull request introduces a new sample agent for a restaurant finder using LangGraph. The implementation is comprehensive, covering the agent logic, server setup, and UI examples. My review focuses on improving code quality, fixing a critical issue with a hardcoded URL that would affect functionality, and ensuring the sample is easy for developers to use. I've provided suggestions for refactoring to handle state correctly, cleaning up unused code and developer comments, and aligning the project's configuration with its documentation.
| # Create a simple mock context that mimics what the tool expects | ||
| # In a real app we might want to pass the real context if we had one | ||
| # For now, we hardcode localhost or inject from somewhere if needed, | ||
| # but the tool just uses it for replacing URL in data. | ||
| # We can try to get base_url from environment or defaults. | ||
| base_url = "http://localhost:10002" | ||
| # Ideally should come from config, but inside a tool we don't have easy access to state unless we bind it. | ||
| # We can rely on default logic inside tool or pass valid one. | ||
|
|
||
| ctx = MockToolContext(base_url) | ||
| return get_restaurants(cuisine=cuisine or "", location=location or "", tool_context=ctx, count=count) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The base_url is hardcoded within the search_restaurants tool. This will cause incorrect image URLs to be generated if the server is run on a different host or port. The base_url is available in the AgentState, but the tool, being globally defined, cannot access it.
To fix this, you should refactor the graph and tool creation to be stateful, for instance, by moving them inside the RestaurantAgent class. This would allow the tool to be created with access to the base_url from the class instance.
| from a2a.types import AgentCapabilities, AgentCard, AgentSkill | ||
| from a2ui.a2ui_extension import get_a2ui_agent_extension | ||
| from agent_executor import RestaurantAgentExecutor | ||
| from agent import RestaurantAgent # To get SUPPORTED_CONTENT_TYPES ideally, but we can hardcode for now or add it to class |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The import RestaurantAgent is not used in this file and should be removed. The associated comment appears to be a developer note that is no longer relevant.
Additionally, there are other developer comments that should be cleaned up to improve code clarity:
- Lines 66-68: Comment about hardcoding
SUPPORTED_CONTENT_TYPES. - Lines 103-105: Comment about the
imagesdirectory.
| import json | ||
| import logging | ||
| import os | ||
| from typing import Annotated, Any, Dict, List, TypedDict | ||
|
|
||
| import jsonschema | ||
| from langchain_core.messages import BaseMessage, HumanMessage, AIMessage, ToolMessage | ||
| from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder | ||
| from langchain_core.tools import tool | ||
| from langchain_google_genai import ChatGoogleGenerativeAI | ||
| from langchain_core.runnables import RunnableConfig | ||
| from langgraph.graph import END, StateGraph, START | ||
| from langgraph.graph.message import add_messages | ||
| from langgraph.prebuilt import ToolNode |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This file contains several unused imports that should be removed for code clarity: os, Any, Dict, ToolMessage, ChatPromptTemplate, MessagesPlaceholder, and RunnableConfig. Additionally, MemorySaver is imported on line 192 but is also unused.
| import json | |
| import logging | |
| import os | |
| from typing import Annotated, Any, Dict, List, TypedDict | |
| import jsonschema | |
| from langchain_core.messages import BaseMessage, HumanMessage, AIMessage, ToolMessage | |
| from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder | |
| from langchain_core.tools import tool | |
| from langchain_google_genai import ChatGoogleGenerativeAI | |
| from langchain_core.runnables import RunnableConfig | |
| from langgraph.graph import END, StateGraph, START | |
| from langgraph.graph.message import add_messages | |
| from langgraph.prebuilt import ToolNode | |
| import json | |
| import logging | |
| from typing import Annotated, List, TypedDict | |
| import jsonschema | |
| from langchain_core.messages import BaseMessage, HumanMessage, AIMessage | |
| from langchain_core.tools import tool | |
| from langchain_google_genai import ChatGoogleGenerativeAI | |
| from langgraph.graph import END, StateGraph, START | |
| from langgraph.graph.message import add_messages | |
| from langgraph.prebuilt import ToolNode |
| return {"error_message": "Empty JSON part."} | ||
|
|
||
| # Attempt to repair common JSON errors (like unquoted keys) | ||
| import re |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| version = "0.1.0" | ||
| description = "Sample LangGraph-based Restaurant finder agent that uses a2ui UI." | ||
| readme = "README.md" | ||
| requires-python = ">=3.13" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The requires-python is set to >=3.13, but the README.md for this sample specifies Python 3.9 or higher. These should be consistent to avoid confusion for users trying to run the sample. Given that Python 3.13 is a very recent release, you might want to verify if the code can run on an earlier, more common version (like 3.9+) and update this requirement accordingly for broader compatibility.
| logger = logging.getLogger(__name__) | ||
|
|
||
|
|
||
| def get_restaurants(cuisine: str, location: str, tool_context: ToolContext, count: int = 5) -> str: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The get_restaurants function's tool_context: ToolContext parameter introduces an unnecessary dependency on the ADK (google.adk.tools.tool_context). This requires creating a MockToolContext in agent.py just to pass the base_url.
To simplify and make the code more self-contained within the LangGraph context, consider passing base_url directly as a string argument. This would also require updating the implementation to use the base_url string directly instead of tool_context.state.get("base_url").
| def get_restaurants(cuisine: str, location: str, tool_context: ToolContext, count: int = 5) -> str: | |
| def get_restaurants(cuisine: str, location: str, base_url: str, count: int = 5) -> str: |
Description
This PR adds a new sample agent (
samples/agent/langgraph/restaurant_finder) implemented using LangGraph.This sample demonstrates how to build A2UI-compliant applications using the LangGraph framework, replicating the functionality of the existing ADK restaurant finder. It provides a reference architecture for handling the A2UI protocol (UI generation, event handling, and data updates) within a LangGraph state machine.
Key improvements included in this implementation:
book_restaurantandsubmit_bookingevents.Pre-launch Checklist
README.mdfor the sample).If you need help, consider asking for advice on the discussion board.