diff --git a/README.md b/README.md index 021e379..2fad30d 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ pkg/backend/ — Backend interface + implementations (Ollama, OpenAI, An pkg/config/ — Config struct and loader pkg/mcp/ — MCP client pkg/tools/ — Server and Dispatcher interfaces; tool definitions -pkg/tools/execute/ — execute.Server: execute_code, execute_tool, execute_pipe +pkg/tools/execute/ — execute.Server: execute_code, execute_pipe ``` ## Install @@ -72,11 +72,9 @@ Controls landrun sandboxing for `execute_code`. Created automatically with defau ## Tools -Three built-in tools via `execute.Server`: +Two built-in tools via `execute.Server`: -**`execute_code`** — run one or more code snippets in a sandbox. Accepts a `steps` array; multiple steps run concurrently and results are returned in submission order. Each step is either inline `code` (with optional `language`) or a named `tool` script. Supported languages: bash (default), python3, perl, lua, awk, sed, jq, ed, expect, bc. Accepts `timeout` (per-step, default 30s) and `sandbox` (default: `default`). - -**`execute_tool`** — run a named script from `OLLIE_TOOLS_PATH`. Language detected from shebang. Accepts `tool`, `args`, `timeout`, `sandbox`. +**`execute_code`** — run one or more steps in a sandbox. Accepts a `steps` array; multiple steps run concurrently and results are returned in submission order. Each step is either inline `{code, language}` or a named `{tool, args}` script (language detected from shebang). Supported inline languages: bash (default), python3, perl, lua, awk, sed, jq, ed, expect, bc. Accepts `timeout` (per-step, default 30s) and `sandbox` (default: `default`). **`execute_pipe`** — run a sequential pipeline, chaining each stage's stdout to the next stage's stdin. Each stage is `{code}`, `{tool, args}`, or `{parallel: [...]}` for concurrent fan-out within a stage. Accepts `timeout` (per-stage) and `sandbox`. diff --git a/pkg/tools/execute/code.go b/pkg/tools/execute/code.go index f032c70..ddd57a4 100644 --- a/pkg/tools/execute/code.go +++ b/pkg/tools/execute/code.go @@ -106,8 +106,6 @@ func (e *Server) Dispatch(ctx context.Context, name string, args json.RawMessage switch name { case "execute_code": return dispatchExecuteCode(ctx, e, args) - case "execute_tool": - return dispatchExecuteTool(ctx, e, args) case "execute_pipe": return dispatchExecutePipe(ctx, e, args) default: diff --git a/pkg/tools/execute/pipe.go b/pkg/tools/execute/pipe.go index 25ad772..77d725f 100644 --- a/pkg/tools/execute/pipe.go +++ b/pkg/tools/execute/pipe.go @@ -1,7 +1,7 @@ package execute -// execute_pipe constructs a pipeline of execute_code and execute_tool calls -// to enable the composition of tools and arbitrary code. +// execute_pipe constructs a sequential pipeline of code and tool steps, +// enabling composition of named scripts and arbitrary inline code. import ( "context" diff --git a/pkg/tools/execute/server.go b/pkg/tools/execute/server.go index b83b971..835442e 100644 --- a/pkg/tools/execute/server.go +++ b/pkg/tools/execute/server.go @@ -94,34 +94,6 @@ Examples: } }`), }, - { - Name: "execute_tool", - Description: `Run a named tool script from the tools directory. - -Usage: -- Scripts located in: ollie/t (default: $HOME/mnt/ollie/t) -- Supported languages: bash, python3, perl, awk, sed, ed, jq, expect, bc, lua (detected from shebang) -- Use for named scripts, not inline shell commands -- Default timeout: 30 seconds - -Tool Discovery: -- List tools: execute_code with 'ls ollie/t' -- Check script permissions before execution - -Examples: -- Run bash tool: tool='script.sh', args=['arg1', 'arg2'] -- Run python tool: tool='process.py', args=['--input', 'data.txt']`, - InputSchema: json.RawMessage(`{ - "type": "object", - "required": ["tool"], - "properties": { - "tool": {"type": "string", "description": "Name of the tool script in the tools directory."}, - "args": {"type": "array", "items": {"type": "string"}, "description": "Arguments for the tool script."}, - "timeout": {"type": "integer", "description": "Timeout in seconds (default: 30)."}, - "sandbox": {"type": "string", "description": "Sandbox name (default: default)."} - } - }`), - }, { Name: "execute_pipe", Description: `Run a sequential pipeline, chaining each stage's stdout to the next stage's stdin. diff --git a/pkg/tools/execute/tool.go b/pkg/tools/execute/tool.go index a8ff590..55ac02d 100644 --- a/pkg/tools/execute/tool.go +++ b/pkg/tools/execute/tool.go @@ -1,12 +1,6 @@ package execute -// execute_tool is a specific case of execute_code, such that the name of the -// script passed to `tool` is loaded into memory from `$OLLIE_9MOUNT/t/` and -// run with Execute(...). - import ( - "context" - "encoding/json" "fmt" "os" "path/filepath" @@ -171,44 +165,3 @@ func ReadTool(name string) (string, error) { return string(data), nil } -func dispatchExecuteTool(ctx context.Context, e *Server, args json.RawMessage) (string, error) { - var a struct { - Tool string `json:"tool"` - Args []string `json:"args"` - Timeout int `json:"timeout"` - Sandbox string `json:"sandbox"` - } - if err := json.Unmarshal(args, &a); err != nil { - return "", fmt.Errorf("execute_tool: bad args: %w", err) - } - if a.Tool == "" { - return "", fmt.Errorf("execute_tool: 'tool' is required") - } - if !e.allowed("execute_tool", fmt.Sprintf("execute_tool: %s %s", a.Tool, strings.Join(a.Args, " "))) { - return "", fmt.Errorf("execute_tool: denied by user") - } - toolCode, err := ReadTool(a.Tool) - if err != nil { - return "", err - } - language := detectLanguage(toolCode) - code := toolCode - if len(a.Args) > 0 { - code = injectArgs(language, a.Tool, a.Args, toolCode) - // injectArgs for file-based languages produces a bash command snippet; - // run it as bash rather than trying to pass it as a raw program argument. - switch language { - case "awk", "sed", "jq", "ed", "expect", "bc": - language = "bash" - } - } - timeout := a.Timeout - if timeout <= 0 { - timeout = 30 - } - sandbox := a.Sandbox - if sandbox == "" { - sandbox = "default" - } - return e.Execute(ctx, code, language, timeout, sandbox, true) -}