Skip to main content

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.

Function tools

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.

AgentTool - sub-agents as tools

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.

AgentTool callbacks

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)

Transfer tool - explicit agent handoff

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.

Exit loop tool

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.

Filesystem tools

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)
ToolDescription
lsList files and directories
read_fileRead file contents (returns base64 for images)
write_fileWrite content to a file, creating parents as needed
edit_fileReplace the first occurrence of old with new
mkdirCreate a directory and parents
globFind files matching a glob pattern (e.g. **/*.py)
grepSearch file contents for a text pattern
In Composer YAML, use the filesystem builtin:
tools:
  fs:
    builtin: filesystem

Shell tools

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)
)
ToolDescription
shell_execRun a command and return stdout + stderr
shell_exec_backgroundStart a command in the background, return PID
Configuration via environment variables:
VariableDefaultDescription
AGENT_WORKSPACE/tmp/agent-workspaceWorking directory
AGENT_SHELL_TIMEOUT30Max seconds per command
AGENT_SHELL_MAX_OUTPUT102400Output truncation limit (bytes)
In Composer YAML, use the shell builtin:
tools:
  sh:
    builtin: shell