|
| 1 | +--- |
| 2 | +description: 'Implement the CodeAct pattern with Hyperlight sandbox. Collapse multi-step tool chains into a single sandboxed Python execution that calls host tools via call_tool(). Tool names match Copilot CLI built-ins (view, create, edit, glob, grep, bash, sql, web_fetch, github_api) so the agent uses familiar names inside the sandbox. Use when a task requires chaining 3+ tool calls (data lookups, code search, computation, file manipulation, API calls). Trigger phrases: "codeact", "hyperlight sandbox", "chain tools together", "sandbox execution", "collapse tool calls", "run in sandbox".' |
| 3 | +name: hyperlight-codeact |
| 4 | +--- |
| 5 | +# Hyperlight CodeAct |
| 6 | + |
| 7 | +Collapse multi-step tool chains into a single sandboxed Python execution. |
| 8 | +Instead of N individual tool calls (model -> tool -> model -> tool ...), write |
| 9 | +one Python program that chains `call_tool()` for each step inside an isolated |
| 10 | +Hyperlight micro-VM. |
| 11 | + |
| 12 | +Tool names inside the sandbox **match Copilot CLI built-in tools**: |
| 13 | + |
| 14 | +| Copilot CLI tool | Sandbox `call_tool()` | What it does | |
| 15 | +|----------------------|-----------------------|----------------------------| |
| 16 | +| `view` | `view` | Read files / list dirs | |
| 17 | +| `create` | `create` | Create new files | |
| 18 | +| `edit` | `edit` | Surgical string replace | |
| 19 | +| `glob` | `glob` | Find files by pattern | |
| 20 | +| `grep` / `rg` | `grep` | Search file contents | |
| 21 | +| `bash` | `bash` | Run shell commands | |
| 22 | +| `sql` | `sql` | SQLite queries | |
| 23 | +| `web_fetch` | `web_fetch` | Fetch URLs | |
| 24 | +| `github-mcp-server-*`| `github_api` | GitHub REST API via `gh` | |
| 25 | + |
| 26 | +## Trust model |
| 27 | + |
| 28 | +The sandbox isolates model-generated **glue code** (the Python program), not |
| 29 | +the tool implementations. Tools run on the **host** with full process access. |
| 30 | +Sandboxed code can only reach the outside world through `call_tool()` bridges. |
| 31 | + |
| 32 | +**Sandboxed:** The Python program. Cannot touch host FS, network, or processes. |
| 33 | +**Host-side:** Tool callbacks. They have whatever access the process has. |
| 34 | +**Implication:** Only register tools appropriate for the trust level. Use |
| 35 | +`--workspace` to restrict file tools to a directory tree. |
| 36 | + |
| 37 | +## When to use CodeAct vs direct tool calls |
| 38 | + |
| 39 | +**Reach for CodeAct when:** |
| 40 | +- Chaining 3+ tool calls (search -> read -> transform -> write). |
| 41 | +- Intermediate results need computation (filtering, aggregation, formatting). |
| 42 | +- Reducing latency and token usage matters. |
| 43 | + |
| 44 | +**Stay with direct tool calls when:** |
| 45 | +- Only 1-2 tool calls needed. |
| 46 | +- Each call needs individual approval. |
| 47 | +- Tool outputs are large and need streaming. |
| 48 | + |
| 49 | +## Quick start |
| 50 | + |
| 51 | +```bash |
| 52 | +# 1. Discover tools (matches Copilot CLI tool names) |
| 53 | +python3 scripts/codeact.py --discover |
| 54 | + |
| 55 | +# 2. Run code with auto-discovered tools |
| 56 | +python3 scripts/codeact.py --auto --workspace . --code ' |
| 57 | +content = call_tool("view", path="README.md") |
| 58 | +print(f"README has {len(content.splitlines())} lines") |
| 59 | +' |
| 60 | +``` |
| 61 | + |
| 62 | +## Workflow |
| 63 | + |
| 64 | +### Step 1 -- Discover tools |
| 65 | + |
| 66 | +```bash |
| 67 | +python3 scripts/codeact.py --discover # JSON manifest |
| 68 | +python3 scripts/codeact.py --instructions # LLM-ready reference |
| 69 | +python3 scripts/codeact.py --discover --output tools.json # save manifest |
| 70 | +``` |
| 71 | + |
| 72 | +### Step 2 -- Write sandboxed code |
| 73 | + |
| 74 | +Use `call_tool(name, **kwargs)` -- built-in global, no import needed. |
| 75 | +**All arguments must be keyword arguments.** |
| 76 | + |
| 77 | +```python |
| 78 | +# Same names as Copilot CLI tools |
| 79 | +content = call_tool('view', path='src/main.py') |
| 80 | +files = call_tool('glob', pattern='**/*.py') |
| 81 | +hits = call_tool('grep', pattern='TODO', paths='src') |
| 82 | +result = call_tool('bash', command='git log --oneline -5') |
| 83 | +call_tool('edit', path='config.json', old_str='"debug": false', new_str='"debug": true') |
| 84 | +rows = call_tool('sql', query='SELECT * FROM users', db_path='app.db') |
| 85 | +data = call_tool('github_api', endpoint='/repos/owner/repo/issues') |
| 86 | +``` |
| 87 | + |
| 88 | +Chain by sequencing or nesting: |
| 89 | + |
| 90 | +```python |
| 91 | +# Sequential: find files, read them, analyze |
| 92 | +for f in call_tool('glob', pattern='**/*.py', paths='src'): |
| 93 | + content = call_tool('view', path=f) |
| 94 | + if 'TODO' in content: |
| 95 | + print(f"{f}: {content.count('TODO')} TODOs") |
| 96 | + |
| 97 | +# Nested: read a file found by glob |
| 98 | +content = call_tool('view', path=call_tool('glob', pattern='config.json')[0]) |
| 99 | +``` |
| 100 | + |
| 101 | +### Step 3 -- Execute |
| 102 | + |
| 103 | +```bash |
| 104 | +# Auto-discover + workspace scoping (recommended) |
| 105 | +python3 scripts/codeact.py --auto --workspace . --code '...' |
| 106 | + |
| 107 | +# With saved manifest |
| 108 | +python3 scripts/codeact.py --manifest tools.json --code-file script.py |
| 109 | + |
| 110 | +# Via stdin |
| 111 | +echo '{"tools": [...], "code": "..."}' | python3 scripts/codeact.py --stdin |
| 112 | +``` |
| 113 | + |
| 114 | +Output is always JSON: `{"stdout": "...", "stderr": "...", "exit_code": 0, "success": true}` |
| 115 | + |
| 116 | +## Available scripts |
| 117 | + |
| 118 | +### `scripts/codeact.py` |
| 119 | +Main executor. Key flags: |
| 120 | +- `--discover` / `--instructions` -- tool discovery |
| 121 | +- `--auto` -- auto-discover tools before running |
| 122 | +- `--workspace <dir>` -- restrict file tools to a directory tree |
| 123 | +- `--allowed-domains` -- allow sandbox-native HTTP |
| 124 | +- `--manifest <file>` -- load tools from JSON |
| 125 | + |
| 126 | +## References |
| 127 | + |
| 128 | +- **Tool patterns and chaining examples**: See [references/tool-patterns.md](references/tool-patterns.md) |
| 129 | + |
| 130 | +## Prerequisites |
| 131 | + |
| 132 | +- Python 3.10+ |
| 133 | +- `hyperlight-sandbox[wasm,python_guest]` or build via `just python-build` |
0 commit comments