execute: remove execute_tool; use execute_code {tool} steps instead
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
a5fd0a8156
commit
ab96de2771
|
|
@ -30,7 +30,7 @@ pkg/backend/ — Backend interface + implementations (Ollama, OpenAI, An
|
||||||
pkg/config/ — Config struct and loader
|
pkg/config/ — Config struct and loader
|
||||||
pkg/mcp/ — MCP client
|
pkg/mcp/ — MCP client
|
||||||
pkg/tools/ — Server and Dispatcher interfaces; tool definitions
|
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
|
## Install
|
||||||
|
|
@ -72,11 +72,9 @@ Controls landrun sandboxing for `execute_code`. Created automatically with defau
|
||||||
|
|
||||||
## Tools
|
## 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_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_tool`** — run a named script from `OLLIE_TOOLS_PATH`. Language detected from shebang. Accepts `tool`, `args`, `timeout`, `sandbox`.
|
|
||||||
|
|
||||||
**`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`.
|
**`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`.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -106,8 +106,6 @@ func (e *Server) Dispatch(ctx context.Context, name string, args json.RawMessage
|
||||||
switch name {
|
switch name {
|
||||||
case "execute_code":
|
case "execute_code":
|
||||||
return dispatchExecuteCode(ctx, e, args)
|
return dispatchExecuteCode(ctx, e, args)
|
||||||
case "execute_tool":
|
|
||||||
return dispatchExecuteTool(ctx, e, args)
|
|
||||||
case "execute_pipe":
|
case "execute_pipe":
|
||||||
return dispatchExecutePipe(ctx, e, args)
|
return dispatchExecutePipe(ctx, e, args)
|
||||||
default:
|
default:
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
package execute
|
package execute
|
||||||
|
|
||||||
// execute_pipe constructs a pipeline of execute_code and execute_tool calls
|
// execute_pipe constructs a sequential pipeline of code and tool steps,
|
||||||
// to enable the composition of tools and arbitrary code.
|
// enabling composition of named scripts and arbitrary inline code.
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
|
||||||
|
|
@ -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",
|
Name: "execute_pipe",
|
||||||
Description: `Run a sequential pipeline, chaining each stage's stdout to the next stage's stdin.
|
Description: `Run a sequential pipeline, chaining each stage's stdout to the next stage's stdin.
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,6 @@
|
||||||
package execute
|
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 (
|
import (
|
||||||
"context"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
@ -171,44 +165,3 @@ func ReadTool(name string) (string, error) {
|
||||||
return string(data), nil
|
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)
|
|
||||||
}
|
|
||||||
|
|
|
||||||
Reference in New Issue