arcade-mcp/examples/langchain/langgraph_with_tool_exec.py
Sam Partee 2eb46a3a98
Client Fixes and LangGraph Examples (#50)
This PR includes several improvements to the Arcade client and adds
LangGraph examples:

1. Enhanced error handling in the Arcade client:
   - Improved HTTP error handling in `BaseArcadeClient`
- Simplified request methods in `SyncArcadeClient` and
`AsyncArcadeClient`

2. Updated `ToolResource` class:
   - Changed base path from `/v1/tool` to `/v1/tools`
   - Added `tool_version` parameter to `authorize` method

3. Improved Toolkit discovery:
- Updated `find_all_arcade_toolkits` to search only in the current
Python interpreter's site-packages

5. Added LangGraph examples:
   - New `langgraph_auth.py` example demonstrating Gmail authentication
- New `langgraph_with_tool_exec.py` example showing tool execution
within a LangGraph

6. Minor updates:
   - Changed default `BASE_URL` to `https://api.arcade.com/`
   - Updated import error message for eval dependencies

---------

Co-authored-by: Nate Barbettini <nate@arcade-ai.com>
2024-09-24 10:13:45 -07:00

63 lines
1.6 KiB
Python

import json
import os
from typing import Any, TypedDict
from langgraph.checkpoint.memory import MemorySaver
from langgraph.errors import NodeInterrupt
from langgraph.graph import END, START, StateGraph
from arcade.client import Arcade
client = Arcade(api_key=os.environ["ARCADE_API_KEY"])
class State(TypedDict):
emails: Any
def step_1(state: State, config) -> State:
user_id = config["configurable"]["user_id"]
challenge = client.tools.authorize(
tool_name="ListEmails",
user_id=user_id,
)
if challenge.status != "completed":
raise NodeInterrupt(f"Please visit this URL to authorize: {challenge.auth_url}")
result = client.tools.run(
tool_name="ListEmails",
user_id=user_id,
tool_version="default",
inputs=json.dumps({"n_emails": 5}),
)
return {"emails": result}
builder = StateGraph(State)
builder.add_node("step_1", step_1)
builder.add_edge(START, "step_1")
builder.add_edge("step_1", END)
# Set up memory
memory = MemorySaver()
# Compile the graph with memory
graph = builder.compile(checkpointer=memory)
config = {"configurable": {"thread_id": "2", "user_id": "sam@arcade-ai.com"}}
result = graph.invoke({"emails": None}, config=config)
state = graph.get_state({"configurable": {"thread_id": "2"}})
print("interrupted state\n----------")
print(state)
print("----------")
input()
result = graph.invoke({"emails": None}, config=config)
state = graph.get_state({"configurable": {"thread_id": "2"}})
print("final state\n----------")
print(state)
print("----------")
print("final result\n----------")
print(result)
print("----------")