LangGraph implementation of CodeAct agent that generates and executes code instead of tool calling.
Project description
langgraph-codeact
This library implements the CodeAct architecture in LangGraph. This is the architecture is used by Manus.im. It implements an alternative to JSON function-calling, which enables solving more complex tasks in less steps. This is achieved by making use of the full power of a Turing complete programming language (such as Python used here) to combine and transform the outputs of multiple tools.
Features
- Message history is saved between turns, to support follow-up questions
- Python variables are saved between turns, which enables more advanced follow-up questions
- Use .invoke() to get just the final result, or .stream() to get token-by-token output, see example below
- You can use any custom tools you wrote, any LangChain tools, or any MCP tools
- You can use this with any model supported by LangChain (but we've only tested with Claude 3.7 so far)
- You can bring your own code sandbox, with a simple functional API
- The system message is customizable
Installation
pip install langgraph-codeact
To run the example install also
pip install langchain langchain-anthropic
Example
A full version of this in one file can be found here
1. Define your tools
You can use any tools you want, including custom tools, LangChain tools, or MCP tools. In this example, we define a few simple math functions.
import math
from langchain_core.tools import tool
def add(a: float, b: float) -> float:
"""Add two numbers together."""
return a + b
def multiply(a: float, b: float) -> float:
"""Multiply two numbers together."""
return a * b
def divide(a: float, b: float) -> float:
"""Divide two numbers."""
return a / b
def subtract(a: float, b: float) -> float:
"""Subtract two numbers."""
return a - b
def sin(a: float) -> float:
"""Take the sine of a number."""
return math.sin(a)
def cos(a: float) -> float:
"""Take the cosine of a number."""
return math.cos(a)
def radians(a: float) -> float:
"""Convert degrees to radians."""
return math.radians(a)
def exponentiation(a: float, b: float) -> float:
"""Raise one number to the power of another."""
return a**b
def sqrt(a: float) -> float:
"""Take the square root of a number."""
return math.sqrt(a)
def ceil(a: float) -> float:
"""Round a number up to the nearest integer."""
return math.ceil(a)
tools = [
add,
multiply,
divide,
subtract,
sin,
cos,
radians,
exponentiation,
sqrt,
ceil,
]
2. Bring-your-own code sandbox
You can use any code sandbox you want, pass it in as a function which accepts two arguments
- the string of code to run
- the dictionary of locals to run it in (includes the tools, and any variables you set in the previous turns)
[!Warning] Use a sandboxed environment in production! The
evalfunction below is just for demonstration purposes, not safe!
import builtins
import contextlib
import io
from typing import Any
def eval(code: str, _locals: dict[str, Any]) -> tuple[str, dict[str, Any]]:
# Store original keys before execution
original_keys = set(_locals.keys())
try:
with contextlib.redirect_stdout(io.StringIO()) as f:
exec(code, builtins.__dict__, _locals)
result = f.getvalue()
if not result:
result = "<code ran, no output printed to stdout>"
except Exception as e:
result = f"Error during execution: {repr(e)}"
# Determine new variables created during execution
new_keys = set(_locals.keys()) - original_keys
new_vars = {key: _locals[key] for key in new_keys}
return result, new_vars
3. Create the CodeAct graph
You can also customize the prompt, through the prompt= argument.
from langchain.chat_models import init_chat_model
from langgraph_codeact import create_codeact
from langgraph.checkpoint.memory import MemorySaver
model = init_chat_model("claude-3-7-sonnet-latest", model_provider="anthropic")
code_act = create_codeact(model, tools, eval)
agent = code_act.compile(checkpointer=MemorySaver())
4. Run it!
You can use the .invoke() method to get the final result, or the .stream() method to get token-by-token output.
messages = [{
"role": "user",
"content": "A batter hits a baseball at 45.847 m/s at an angle of 23.474° above the horizontal. The outfielder, who starts facing the batter, picks up the baseball as it lands, then throws it back towards the batter at 24.12 m/s at an angle of 39.12 degrees. How far is the baseball from where the batter originally hit it? Assume zero air resistance."
}]
for typ, chunk in agent.stream(
{"messages": messages},
stream_mode=["values", "messages"],
config={"configurable": {"thread_id": 1}},
):
if typ == "messages":
print(chunk[0].content, end="")
elif typ == "values":
print("\n\n---answer---\n\n", chunk)
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file langgraph_codeact-0.1.3.tar.gz.
File metadata
- Download URL: langgraph_codeact-0.1.3.tar.gz
- Upload date:
- Size: 7.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
39f22b7c1a3b4fc61c29e66a9914313cd938a89b2fc2340b5b9c0e965bdcda4d
|
|
| MD5 |
b26d68cde5143d2027c3ea0aa5460dd5
|
|
| BLAKE2b-256 |
e59ddfc90b15b4e82e4e0bea4a29df97b897d62f0ee60d473d58962c23dfc094
|
File details
Details for the file langgraph_codeact-0.1.3-py3-none-any.whl.
File metadata
- Download URL: langgraph_codeact-0.1.3-py3-none-any.whl
- Upload date:
- Size: 7.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0677d65ca9ffa8347aa3df85205d9eafa9c898e2220ebe36eedf178c2f614862
|
|
| MD5 |
a37b181a6f214d748972a1bd8e1b1eff
|
|
| BLAKE2b-256 |
d9c758b198305a7762d3daad34261cfd5548712eb2dc1dfefa24e1a5272449cc
|