Skip to main content

Overview

The BashExecutorProxy intercepts curl commands and routes API calls to isolated environments. Code runs in a subprocess.

Basic Usage

from agent_diff import BashExecutorProxy

# Create executor for an environment
executor = BashExecutorProxy(
    environment_id="env-123",
    base_url="http://localhost:8000"
)

# Execute shell command
result = executor.execute("""
curl -X POST https://slack.com/api/chat.postMessage \
  -H "Content-Type: application/json" \
  -d '{"channel": "C01GENERAL99", "text": "Hello from bash!"}'
""")

print(result["stdout"])

Creating Framework Tools

Python - OpenAI Agents

from agent_diff import BashExecutorProxy, create_openai_tool
from agents import Agent

executor = BashExecutorProxy(env.environmentId, client.base_url)
tool = create_openai_tool(executor)

agent = Agent(
    name="CLI Agent",
    tools=[tool],
    instructions="Use execute_bash with curl to interact with Slack API..."
)

TypeScript - Vercel AI

import { BashExecutorProxy, createVercelAITool } from 'agent-diff';

const executor = new BashExecutorProxy(env.environmentId, client.getBaseUrl());
const tool = await createVercelAITool(executor);

URL Transformation

The bash executor transforms curl URLs:
# Original command (what agent writes):
curl https://slack.com/api/conversations.list

# Transformed (what actually runs):
curl http://localhost:8000/api/env/{id}/services/slack/conversations.list

Execution Result

result = executor.execute(command)

# Result structure:
{
    "status": "success" | "error",
    "stdout": "...",     # Command output
    "stderr": "...",     # Error output
    "exit_code": 0       # Process exit code
}

Example: Slack API Calls

# List channels
curl https://slack.com/api/conversations.list

# Post message
curl -X POST https://slack.com/api/chat.postMessage \
  -H "Content-Type: application/json" \
  -d '{
    "channel": "C01GENERAL99",
    "text": "Hello!"
  }'

# Add reaction
curl -X POST https://slack.com/api/reactions.add \
  -H "Content-Type: application/json" \
  -d '{
    "channel": "C01GENERAL99",
    "timestamp": "1234567890.123456",
    "name": "thumbsup"
  }'

Example: Linear GraphQL

curl -X POST https://api.linear.app/graphql \
  -H "Content-Type: application/json" \
  -d '{
    "query": "mutation { issueCreate(input: { title: \"Fix bug\", teamId: \"team-123\" }) { success } }"
  }'

Supported Commands

The bash executor primarily intercepts:
  • curl: All HTTP methods, headers, data
  • Other commands run normally (piping, jq, etc.)

Complex Scripts

You can write multi-line scripts:
# Get channels, then post to the first one
CHANNELS=$(curl -s https://slack.com/api/conversations.list)
FIRST_CHANNEL=$(echo $CHANNELS | jq -r '.channels[0].id')

curl -X POST https://slack.com/api/chat.postMessage \
  -H "Content-Type: application/json" \
  -d "{\"channel\": \"$FIRST_CHANNEL\", \"text\": \"Hello!\"}"

Configuration Options

executor = BashExecutorProxy(
    environment_id="env-123",
    base_url="http://localhost:8000",
    api_key="ad_live_sk_..."
)

When to Use Bash Executor

Use CaseRecommended
Simple API calls✓ Bash
Complex logic/loopsPython/TS
JSON manipulationPython/TS
Quick curl tests✓ Bash
Multi-step workflowsPython/TS

Next Steps