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>
63 lines
1.6 KiB
Python
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("----------")
|