summaryrefslogtreecommitdiff
path: root/docs/phase-3.md
diff options
context:
space:
mode:
Diffstat (limited to 'docs/phase-3.md')
-rw-r--r--docs/phase-3.md42
1 files changed, 21 insertions, 21 deletions
diff --git a/docs/phase-3.md b/docs/phase-3.md
index 51e1341..1b9d83a 100644
--- a/docs/phase-3.md
+++ b/docs/phase-3.md
@@ -2,14 +2,14 @@
## Goal
-Introduce a Lua extension runtime and tool registration/execution, transforming `awl` from a chat client into an agent that can act on the world. The extension system is the primary mechanism for adding capability — tools are extensions, not built-ins.
+Introduce a Lua extension runtime and tool registration/execution, transforming `pantograph` from a chat client into an agent that can act on the world. The extension system is the primary mechanism for adding capability — tools are extensions, not built-ins.
## Deliverable
A working extension system where Lua scripts can register tools and handle tool-use requests. The agent loop detects ToolUse blocks in LLM responses, executes the corresponding tool handlers, and feeds ToolResult blocks back. At the end of this phase, you can:
- Write a Lua extension that registers a tool and handles invocations.
-- Place it in `~/.config/awl/extensions/` (or `.awl/extensions/`) and have `awl` discover and load it.
+- Place it in `~/.config/panto/extensions/` (or `.panto/extensions/`) and have `pantograph` discover and load it.
- Have a conversation where the LLM calls your tool and receives the result.
- See tool calls execute in parallel when the LLM returns multiple ToolUse blocks.
- See a meaningful error message when an extension crashes, instead of a process abort.
@@ -18,9 +18,9 @@ A working extension system where Lua scripts can register tools and handle tool-
| Capability | How to exercise it |
|---|---|
-| Write a tool extension | Create `~/.config/awl/extensions/mytool.lua` calling `awl.register_tool(...)` |
-| Discover extensions | Place `.lua` files or directories in extension directories; `awl` loads them on startup |
-| LLM calls a tool | Ask the LLM to use a registered tool; it emits a ToolUse block; awl executes the handler |
+| Write a tool extension | Create `~/.config/panto/extensions/mytool.lua` calling `panto.register_tool(...)` |
+| Discover extensions | Place `.lua` files or directories in extension directories; `pantograph` loads them on startup |
+| LLM calls a tool | Ask the LLM to use a registered tool; it emits a ToolUse block; pantograph executes the handler |
| Tool result fed back | The tool handler's return value becomes a ToolResult block sent back to the LLM |
| Parallel tool calls | LLM returns multiple ToolUse blocks; they execute concurrently |
| Extension crash handling | A crashing tool handler prints `the "mytool" extension crashed: <trace>` and aborts the turn |
@@ -29,7 +29,7 @@ A working extension system where Lua scripts can register tools and handle tool-
- Core tools as extensions (phase 5 — `std.read`, `std.write`, etc.)
- Conversation serialization / disk persistence (phase 4)
-- C ABI distribution of libawl for external consumers (future)
+- C ABI distribution of libpanto for external consumers (future)
- GitHub or luarocks extension loaders (future — local filesystem only in phase 3)
- Shared-object extensions (future)
- Extension sandboxing beyond `xpcall` crash protection (future)
@@ -41,10 +41,10 @@ A working extension system where Lua scripts can register tools and handle tool-
### Directory locations
-`awl` scans two directories in order:
+`pantograph` scans two directories in order:
-1. `.awl/extensions/` — project-local extensions (relative to current working directory)
-2. `~/.config/awl/extensions/` — user-level extensions
+1. `.panto/extensions/` — project-local extensions (relative to current working directory)
+2. `~/.config/panto/extensions/` — user-level extensions
### Naming and structure
@@ -58,25 +58,25 @@ Names can be hierarchical using dots as separators, mapping to directory nesting
- `utils/json.lua` → extension name is `utils.json`
- `coding/edit/init.lua` → extension name is `coding.edit`
-This convention mirrors Lua's `require("a.b.c")` path resolution. Extension sub-modules (e.g., `coding/edit/helpers.lua`) are the extension's internal business — awl only loads the top-level entry point (`init.lua` or the single file).
+This convention mirrors Lua's `require("a.b.c")` path resolution. Extension sub-modules (e.g., `coding/edit/helpers.lua`) are the extension's internal business — pantograph only loads the top-level entry point (`init.lua` or the single file).
### Loading behavior
- Scan both directories recursively.
- Construct extension names from relative paths using dot separators.
- Load each discovered entry point file into a fresh `lua_State`.
-- After loading, the extension's top-level code runs, which should call `awl.register_tool(...)` to register its tools.
+- After loading, the extension's top-level code runs, which should call `panto.register_tool(...)` to register its tools.
- Duplicate extension names: project-local takes precedence over user-level.
---
## Lua Bridge
-The Lua bridge is a Zig module (`lua_bridge.zig`) that registers awl functions into the Lua state and handles translation between Zig types and Lua types. It is compiled into the `awl` binary — it is not a separate library.
+The Lua bridge is a Zig module (`lua_bridge.zig`) that registers panto functions into the Lua state and handles translation between Zig types and Lua types. It is compiled into the `panto` binary — it is not a separate library.
### Functions exposed to Lua
-#### `awl.register_tool(name, schema, handler)`
+#### `panto.register_tool(name, schema, handler)`
Registers a tool with the agent.
@@ -87,7 +87,7 @@ Registers a tool with the agent.
Example:
```lua
-awl.register_tool("echo", {
+panto.register_tool("echo", {
type = "object",
properties = {
message = { type = "string", description = "The message to echo back" }
@@ -100,17 +100,17 @@ end)
### Input parsing at the bridge boundary
-Tool input arrives in libawl as raw JSON bytes (stored in the ToolUseBlock's TextualBlock). At the Lua bridge boundary, libawl parses these bytes into a Lua table using `std.json`, then passes the table to the handler. This is a convenience service for extension authors — internally, libawl still treats tool input as opaque bytes. The round-trip guarantee: the JSON bytes the provider sent are faithfully represented in the Lua table.
+Tool input arrives in libpanto as raw JSON bytes (stored in the ToolUseBlock's TextualBlock). At the Lua bridge boundary, libpanto parses these bytes into a Lua table using `std.json`, then passes the table to the handler. This is a convenience service for extension authors — internally, libpanto still treats tool input as opaque bytes. The round-trip guarantee: the JSON bytes the provider sent are faithfully represented in the Lua table.
### Output from handlers
-The handler returns a string. This string becomes the `content` of a ToolResult block. It is stored as raw bytes; libawl does not interpret or parse it.
+The handler returns a string. This string becomes the `content` of a ToolResult block. It is stored as raw bytes; libpanto does not interpret or parse it.
---
## Tool Registration (Internal)
-When `awl.register_tool()` is called from Lua, the bridge stores:
+When `panto.register_tool()` is called from Lua, the bridge stores:
```
RegisteredTool = struct {
@@ -185,7 +185,7 @@ end, input_table)
If the handler crashes:
- The error and stack trace are captured as a string.
-- awl prints: `the "<tool_name>" extension crashed: <trace>`
+- pantograph prints: `the "<tool_name>" extension crashed: <trace>`
- The current LLM turn is aborted — no ToolResult is generated for this tool call.
- Other concurrent tool calls in the same batch are not affected (they run in separate `lua_State` instances).
@@ -283,7 +283,7 @@ src/extension_loader.zig // Directory scanning, extension discovery and loading
### External dependency
-Lua interpreter linked into the `awl` binary. Zig's build system can fetch and compile Lua from source (Lua is a small C codebase, ~30KLOC). No system dependency required.
+Lua interpreter linked into the `panto` binary. Zig's build system can fetch and compile Lua from source (Lua is a small C codebase, ~30KLOC). No system dependency required.
---
@@ -302,7 +302,7 @@ Lua interpreter linked into the `awl` binary. Zig's build system can fetch and c
### Integration test (manual)
- Write a simple `echo.lua` extension, place it in extension directory
-- Start `awl`, ask the LLM to use the echo tool
+- Start `panto`, ask the LLM to use the echo tool
- Verify the tool is called, result is fed back, LLM continues
- Write a `crash.lua` extension that throws an error
- Verify the crash is caught and printed with context, turn aborts gracefully
@@ -315,4 +315,4 @@ Lua interpreter linked into the `awl` binary. Zig's build system can fetch and c
1. **Lua version**: Lua 5.4 is current. Luau (Roblox's fork) has performance improvements but diverges. Stick with standard Lua 5.4 for compatibility with luarocks and existing ecosystem?
2. **Handler timeout**: Should tool handlers have a timeout? A hung tool call blocks the agent loop. Could add a configurable timeout with abort.
3. **Streaming tool results**: Some tools (e.g., `bash` running a long command) produce output incrementally. Phase 3 handlers return a single string. Streaming results would require a different handler interface — possibly a callback the handler calls to emit partial output. Defer to a later phase?
-4. **Tool description field**: The `awl.register_tool()` call in phase 3 includes a schema but no explicit description string. Provider APIs require a description. Options: add a `description` parameter, or extract it from the schema. Probably simplest to add it as a parameter.
+4. **Tool description field**: The `panto.register_tool()` call in phase 3 includes a schema but no explicit description string. Provider APIs require a description. Options: add a `description` parameter, or extract it from the schema. Probably simplest to add it as a parameter.