mirror of
https://github.com/hwchase17/langchain.git
synced 2025-05-05 23:28:47 +00:00
community[minor]: Add Riza Python/JS code execution tool (#23995)
- **Description:** Add Riza Python/JS code execution tool - **Issue:** N/A - **Dependencies:** an optional dependency on the `rizaio` pypi package - **Twitter handle:** [@rizaio](https://x.com/rizaio) [Riza](https://riza.io) is a safe code execution environment for agent-generated Python and JavaScript that's easy to integrate into langchain apps. This PR adds two new tool classes to the community package.
This commit is contained in:
parent
3691701d58
commit
f9d64d22e5
docs/docs/integrations/tools
libs/community/langchain_community/tools/riza
183
docs/docs/integrations/tools/riza.ipynb
Normal file
183
docs/docs/integrations/tools/riza.ipynb
Normal file
@ -0,0 +1,183 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "7d143c73",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# Riza Code Interpreter\n",
|
||||
"\n",
|
||||
"> The Riza Code Interpreter is a WASM-based isolated environment for running Python or JavaScript generated by AI agents.\n",
|
||||
"\n",
|
||||
"In this notebook we'll create an example of an agent that uses Python to solve a problem that an LLM can't solve on its own:\n",
|
||||
"counting the number of 'r's in the word \"strawberry.\"\n",
|
||||
"\n",
|
||||
"Before you get started grab an API key from the [Riza dashboard](https://dashboard.riza.io). For more guides and a full API reference\n",
|
||||
"head over to the [Riza Code Interpreter API documentation](https://docs.riza.io)."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "894aa87a",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Make sure you have the necessary dependencies installed."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "8265cf7f",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"%pip install --upgrade --quiet langchain-community rizaio"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "e085eb51",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Set up your API keys as an environment variable."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "45ba8936",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"%env ANTHROPIC_API_KEY=<your_anthropic_api_key_here>\n",
|
||||
"%env RIZA_API_KEY=<your_riza_api_key_here>"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 13,
|
||||
"id": "efe26fd9-6e33-4f5f-b49b-ea74fa6c4915",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from langchain_community.tools.riza.command import ExecPython"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 14,
|
||||
"id": "cd5b952e",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from langchain.agents import AgentExecutor, create_tool_calling_agent\n",
|
||||
"from langchain_anthropic import ChatAnthropic\n",
|
||||
"from langchain_core.prompts import ChatPromptTemplate"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "7bd0b610",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Initialize the `ExecPython` tool."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 15,
|
||||
"id": "32f1543f",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"tools = [ExecPython()]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "24f952d5",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Initialize an agent using Anthropic's Claude Haiku model."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 16,
|
||||
"id": "71831ea8",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"llm = ChatAnthropic(model=\"claude-3-haiku-20240307\", temperature=0)\n",
|
||||
"\n",
|
||||
"prompt_template = ChatPromptTemplate.from_messages(\n",
|
||||
" [\n",
|
||||
" (\n",
|
||||
" \"system\",\n",
|
||||
" \"You are a helpful assistant. Make sure to use a tool if you need to solve a problem.\",\n",
|
||||
" ),\n",
|
||||
" (\"human\", \"{input}\"),\n",
|
||||
" (\"placeholder\", \"{agent_scratchpad}\"),\n",
|
||||
" ]\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"agent = create_tool_calling_agent(llm, tools, prompt_template)\n",
|
||||
"agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 34,
|
||||
"id": "36b24036",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"\n",
|
||||
"\n",
|
||||
"\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n",
|
||||
"\u001b[32;1m\u001b[1;3m\n",
|
||||
"Invoking: `riza_exec_python` with `{'code': 'word = \"strawberry\"\\nprint(word.count(\"r\"))'}`\n",
|
||||
"responded: [{'id': 'toolu_01JwPLAAqqCNCjVuEnK8Fgut', 'input': {}, 'name': 'riza_exec_python', 'type': 'tool_use', 'index': 0, 'partial_json': '{\"code\": \"word = \\\\\"strawberry\\\\\"\\\\nprint(word.count(\\\\\"r\\\\\"))\"}'}]\n",
|
||||
"\n",
|
||||
"\u001b[0m\u001b[36;1m\u001b[1;3m3\n",
|
||||
"\u001b[0m\u001b[32;1m\u001b[1;3m[{'text': '\\n\\nThe word \"strawberry\" contains 3 \"r\" characters.', 'type': 'text', 'index': 0}]\u001b[0m\n",
|
||||
"\n",
|
||||
"\u001b[1m> Finished chain.\u001b[0m\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"The word \"strawberry\" contains 3 \"r\" characters.\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# Ask a tough question\n",
|
||||
"result = agent_executor.invoke({\"input\": \"how many rs are in strawberry?\"})\n",
|
||||
"print(result[\"output\"][0][\"text\"])"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3 (ipykernel)",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.12.3"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
}
|
95
libs/community/langchain_community/tools/riza/command.py
Normal file
95
libs/community/langchain_community/tools/riza/command.py
Normal file
@ -0,0 +1,95 @@
|
||||
"""
|
||||
Tool implementations for the Riza (https://riza.io) code interpreter API.
|
||||
|
||||
Documentation: https://docs.riza.io
|
||||
API keys: https://dashboard.riza.io
|
||||
"""
|
||||
|
||||
from typing import Any, Optional, Type
|
||||
|
||||
from langchain_core.callbacks import (
|
||||
CallbackManagerForToolRun,
|
||||
)
|
||||
from langchain_core.pydantic_v1 import BaseModel, Field
|
||||
from langchain_core.tools import BaseTool, ToolException
|
||||
|
||||
|
||||
class ExecPythonInput(BaseModel):
|
||||
code: str = Field(description="the Python code to execute")
|
||||
|
||||
|
||||
class ExecPython(BaseTool):
|
||||
"""A tool implementation to execute Python via Riza's Code Interpreter API."""
|
||||
|
||||
name: str = "riza_exec_python"
|
||||
description: str = """Execute Python code to solve problems.
|
||||
|
||||
The Python runtime does not have filesystem access. You can use the httpx
|
||||
or requests library to make HTTP requests. Always print output to stdout."""
|
||||
args_schema: Type[BaseModel] = ExecPythonInput
|
||||
handle_tool_error: bool = True
|
||||
|
||||
client: Any = None
|
||||
|
||||
def __init__(self, **kwargs: Any) -> None:
|
||||
try:
|
||||
from rizaio import Riza
|
||||
except ImportError as e:
|
||||
raise ImportError(
|
||||
"Couldn't import the `rizaio` package. "
|
||||
"Try running `pip install rizaio`."
|
||||
) from e
|
||||
super().__init__(**kwargs)
|
||||
self.client = Riza()
|
||||
|
||||
def _run(
|
||||
self, code: str, run_manager: Optional[CallbackManagerForToolRun] = None
|
||||
) -> str:
|
||||
output = self.client.command.exec(language="PYTHON", code=code)
|
||||
if output.exit_code > 0:
|
||||
raise ToolException(
|
||||
f"Riza code execution returned a non-zero exit code. "
|
||||
f"The output captured from stderr was:\n{output.stderr}"
|
||||
)
|
||||
return output.stdout
|
||||
|
||||
|
||||
class ExecJavaScriptInput(BaseModel):
|
||||
code: str = Field(description="the JavaScript code to execute")
|
||||
|
||||
|
||||
class ExecJavaScript(BaseTool):
|
||||
"""A tool implementation to execute JavaScript via Riza's Code Interpreter API."""
|
||||
|
||||
name: str = "riza_exec_javascript"
|
||||
description: str = """Execute JavaScript code to solve problems.
|
||||
|
||||
The JavaScript runtime does not have filesystem access, but can use fetch
|
||||
to make HTTP requests and does include the global JSON object. Always print
|
||||
output to stdout."""
|
||||
args_schema: Type[BaseModel] = ExecJavaScriptInput
|
||||
handle_tool_error: bool = True
|
||||
|
||||
client: Any = None
|
||||
|
||||
def __init__(self, **kwargs: Any) -> None:
|
||||
try:
|
||||
from rizaio import Riza
|
||||
except ImportError as e:
|
||||
raise ImportError(
|
||||
"Couldn't import the `rizaio` package. "
|
||||
"Try running `pip install rizaio`."
|
||||
) from e
|
||||
super().__init__(**kwargs)
|
||||
self.client = Riza()
|
||||
|
||||
def _run(
|
||||
self, code: str, run_manager: Optional[CallbackManagerForToolRun] = None
|
||||
) -> str:
|
||||
output = self.client.command.exec(language="JAVASCRIPT", code=code)
|
||||
if output.exit_code > 0:
|
||||
raise ToolException(
|
||||
f"Riza code execution returned a non-zero exit code. "
|
||||
f"The output captured from stderr was:\n{output.stderr}"
|
||||
)
|
||||
return output.stdout
|
Loading…
Reference in New Issue
Block a user