diff --git a/README.md b/README.md index de6bc37f..e57c8565 100644 --- a/README.md +++ b/README.md @@ -196,7 +196,7 @@ To create a new toolkit, you can use the `arcade new` command. This will create The template is meant to be customized so feel free to change anything about the structure, package management, linting, etc. -4. **Show the tools in the template Toolkit:** +3. **Show the tools in the template Toolkit:** ```bash # show the tools in Mytoolkit @@ -359,47 +359,72 @@ Here's an example of how to use the Tools API with LangChain/Langgraph: ```python import os -from langchain_arcade import ArcadeToolManager + +from langchain_arcade import ToolManager from langchain_openai import ChatOpenAI +from langgraph.checkpoint.memory import MemorySaver from langgraph.prebuilt import create_react_agent -arcade_api_key = os.environ["ARCADE_API_KEY"] -openai_api_key = os.environ["OPENAI_API_KEY"] +# 1) Set API keys (place your real keys in env variables or directly below) +arcade_api_key = os.environ.get("ARCADE_API_KEY", "YOUR_ARCADE_API_KEY") +openai_api_key = os.environ.get("OPENAI_API_KEY", "YOUR_OPENAI_API_KEY") -manager = ArcadeToolManager(api_key=arcade_api_key) -tools = manager.get_tools(tools=["Mytoolkit.SayHello"]) +# 2) Create an ToolManager and fetch/add tools/toolkits +manager = ToolManager(api_key=arcade_api_key) -model = ChatOpenAI( - model="gpt-4o", - api_key=openai_api_key, -) +# Tool names follow the format "ToolkitName.ToolName" +tools = manager.init_tools(tools=["Web.ScrapeUrl"]) +print(manager.tools) -bound_model = model.bind_tools(tools) -graph = create_react_agent(model=bound_model, tools=tools) +# Get all tools from a toolkit +tools = manager.init_tools(toolkits=["github"]) +print(manager.tools) -config = { - "configurable": { - "thread_id": "1", - "user_id": "user@unique_id.com", - } -} -user_input = { - "messages": [ - { - "role": "system", - "content": "You are a helpful assistant", - }, - { - "role": "user", - "content": "Say hello to Sam", - }, - ] -} +# add a tool +manager.add_tool("Search.SearchGoogle") +print(manager.tools) +# add a toolkit +manager.add_toolkit("Search") +print(manager.tools) + +# 3) Get StructuredTool objects for langchain +lc_tools = manager.to_langchain() + +# 4) Create a ChatOpenAI model and bind the Arcade tools. +model = ChatOpenAI(model="gpt-4o", api_key=openai_api_key) +bound_model = model.bind_tools(lc_tools) + +# 5) Use MemorySaver for checkpointing. +memory = MemorySaver() + +# 6) Create a ReAct-style agent from the prebuilt function. +graph = create_react_agent(model=bound_model, tools=lc_tools, checkpointer=memory) + +# 7) Provide basic config and a user query. +# Note: user_id is required for the tool to be authorized +config = {"configurable": {"thread_id": "1", "user_id": "user@example.com"}} +user_input = {"messages": [("user", "star the arcadeai/arcade-ai repo on github")]} + +# 8) Stream the agent's output. If the tool is unauthorized, it may trigger interrupts for chunk in graph.stream(user_input, config, stream_mode="values"): chunk["messages"][-1].pretty_print() + +# if we were interrupted, we can check for interrupts in state +current_state = graph.get_state(config) +if current_state.tasks: + for task in current_state.tasks: + if hasattr(task, "interrupts"): + for interrupt in task.interrupts: + print(interrupt.value) ``` +The last message may result in an authorization prompt. + +If so, the user will need to authorize the tool by visiting the url in the response. Once authorized, running the +same script will return the completed action since the tool will be authorized for that +user. + ### Arcade Auth API The Auth API provides the lowest-level integration with Arcade, for when you only need Arcade's authentication capabilities. This API is ideal for: diff --git a/examples/langchain/langgraph_arcade_minimal.py b/examples/langchain/langgraph_arcade_minimal.py index c69a064e..f294ffbb 100644 --- a/examples/langchain/langgraph_arcade_minimal.py +++ b/examples/langchain/langgraph_arcade_minimal.py @@ -17,7 +17,7 @@ tools = manager.init_tools(tools=["Web.ScrapeUrl"]) print(manager.tools) # Get all tools from a toolkit -tools = manager.init_tools(toolkits=["Google"]) +tools = manager.init_tools(toolkits=["github"]) print(manager.tools) # add a tool @@ -43,11 +43,11 @@ graph = create_react_agent(model=bound_model, tools=lc_tools, checkpointer=memor # 6) Provide basic config and a user query. # Note: user_id is required for the tool to be authorized -config = {"configurable": {"thread_id": "1", "user_id": "userrerr@example.coom"}} -user_input = {"messages": [("user", "List any new and important emails in my inbox.")]} +config = {"configurable": {"thread_id": "1", "user_id": "user@example.com"}} +user_input = {"messages": [("user", "star the arcadeai/arcade-ai repo on github")]} # 7) Stream the agent's output. If the tool is unauthorized, it may trigger interrupts -for chunk in graph.stream(user_input, config, stream_mode="values", debug=True): +for chunk in graph.stream(user_input, config, stream_mode="values"): chunk["messages"][-1].pretty_print() # if we were interrupted, we can check for interrupts in state