Documentation Index
Fetch the complete documentation index at: https://docs.orxhestra.com/llms.txt
Use this file to discover all available pages before exploring further.
Wrap any async function as a LangChain BaseTool:
from orxhestra import function_tool
async def search_web(query: str) -> str:
"""Search the web and return results."""
...
tool = function_tool(search_web)
# or: function_tool(search_web, name="web_search", description="...")
Or use LangChain’s @tool decorator directly - both work with LlmAgent.
Wrap a BaseAgent so it can be called as a tool by a parent agent:
from orxhestra import LlmAgent
from orxhestra.tools.agent_tool import AgentTool
research_agent = LlmAgent(name="ResearchAgent", model=model, tools=[search_tool])
parent = LlmAgent(
name="Coordinator",
model=model,
tools=[AgentTool(research_agent)],
instructions="Delegate research to ResearchAgent.",
)
The tool derives a child context with branch isolation and a clean session automatically. Sub-agent events stream through the parent in real-time via ctx.event_callback - each event carries a branch field (e.g. "ResearchAgent") for attribution.
Hook into the child agent’s event stream with before_agent_callback (intercept each event, optionally short-circuit) and after_agent_callback (run after completion):
def check_event(event, child_ctx):
if child_ctx.state.get("needs_approval"):
return "Paused: awaiting approval." # short-circuits, returns this as tool result
return None # continue
tool = AgentTool(research_agent, before_agent_callback=check_event)
Any custom tool can push events the same way:
if ctx.event_callback is not None:
ctx.event_callback(my_event)
from orxhestra import make_transfer_tool
transfer = make_transfer_tool([billing_agent, support_agent, tech_agent])
# The LLM can call "transfer_to_agent" with the target agent name.
# EventActions.transfer_to_agent is set; the parent routes accordingly.
Signal a LoopAgent to stop iterating:
from orxhestra import exit_loop_tool
loop_agent = LoopAgent(
name="RefineLoop",
agents=[refine_agent],
# refine_agent has exit_loop_tool in its tools list
)
CallContext
Inside a tool’s _arun(), use CallContext to read/write agent state:
from orxhestra.tools import CallContext
class MyStatefulTool(BaseTool):
_ctx: CallContext | None = None
def inject_context(self, ctx: InvocationContext) -> None:
self._ctx = CallContext(ctx)
async def _arun(self, query: str) -> str:
self._ctx.state["last_query"] = query
return "done"
LlmAgent automatically calls inject_context() on any tool that exposes it before each tool execution.
Sandboxed file operations restricted to a configurable workspace directory. All paths are validated to prevent escaping the workspace.
from orxhestra.tools import make_filesystem_tools
tools = make_filesystem_tools(workspace="/tmp/my-workspace")
# or use $AGENT_WORKSPACE env var / default /tmp/agent-workspace
agent = LlmAgent(name="coder", model=model, tools=tools)
| Tool | Description |
|---|
ls | List files and directories |
read_file | Read file contents (returns base64 for images) |
write_file | Write content to a file, creating parents as needed |
edit_file | Replace the first occurrence of old with new |
mkdir | Create a directory and parents |
glob | Find files matching a glob pattern (e.g. **/*.py) |
grep | Search file contents for a text pattern |
In Composer YAML, use the filesystem builtin:
tools:
fs:
builtin: filesystem
Sandboxed shell execution with timeout, output truncation, and command filtering.
from orxhestra.tools import make_shell_tools
tools = make_shell_tools(
workspace="/tmp/my-workspace",
timeout=30, # max seconds per command
max_output_bytes=102400, # truncate beyond 100KB
allowed_commands=["python", "npm"], # whitelist (optional)
denied_commands=["rm", "shutdown"], # blocklist (optional)
env={"NODE_ENV": "test"}, # extra env vars (optional)
)
| Tool | Description |
|---|
shell_exec | Run a command and return stdout + stderr |
shell_exec_background | Start a command in the background, return PID |
Configuration via environment variables:
| Variable | Default | Description |
|---|
AGENT_WORKSPACE | /tmp/agent-workspace | Working directory |
AGENT_SHELL_TIMEOUT | 30 | Max seconds per command |
AGENT_SHELL_MAX_OUTPUT | 102400 | Output truncation limit (bytes) |
In Composer YAML, use the shell builtin:
tools:
sh:
builtin: shell