Remove Go language support from execute_code (go run lacks stdin)

Keep code extensible for future language support.
This commit is contained in:
Levi Neely 2026-03-06 14:15:51 +01:00
parent b3bb801b23
commit fc6cca01a8
3 changed files with 22 additions and 55 deletions

View File

@ -258,43 +258,11 @@ func executeCode(code, language string, timeout int, sandboxName string, trusted
cmd = exec.CommandContext(ctx, landrunPath, args...)
cmd.Dir = workDir
case "go":
args := []string{}
addPaths := func(flag string, paths []string) {
for _, p := range paths {
expanded := sandbox.ExpandPath(p, workDir)
if expanded == "" || strings.Contains(expanded, "{") {
continue
}
if _, err := os.Stat(expanded); err == nil {
args = append(args, flag, expanded)
}
}
}
addPaths("--ro", cfg.Filesystem.RO)
addPaths("--rox", cfg.Filesystem.ROX)
addPaths("--rw", cfg.Filesystem.RW)
addPaths("--rwx", cfg.Filesystem.RWX)
if cfg.Network.Unrestricted {
args = append(args, "--unrestricted-network")
}
for _, env := range cfg.Env {
if os.Getenv(env) != "" || env == "HOME" || env == "USER" || env == "PATH" {
args = append(args, "--env", env)
}
}
args = append(args, "--", "go", "run", "-")
cmd = exec.CommandContext(ctx, landrunPath, args...)
cmd.Dir = workDir
cmd.Stdin = strings.NewReader(code)
// Add new language cases here:
// case "python":
// args = append(args, "--", "python3", "-c", code)
default:
return "", fmt.Errorf("unsupported language: %s (supported: bash, go)", language)
return "", fmt.Errorf("unsupported language: %s (supported: bash)", language)
}
// Limit output size (10MB)

View File

@ -133,7 +133,7 @@ func main() {
"tool": {Type: "string", Description: "Tool name from agent/tools/ (e.g. 'list_sessions.sh')"},
"args": {Type: "array", Description: "Arguments to pass to tool", Items: &Items{Type: "string"}},
"code": {Type: "string", Description: "Inline code to execute (if tool not specified)"},
"language": {Type: "string", Description: "Programming language (auto-detected from tool extension)", Enum: []string{"bash", "go"}},
"language": {Type: "string", Description: "Programming language", Enum: []string{"bash"}},
"timeout": {Type: "integer", Description: "Timeout in seconds (default: 30)"},
"sandbox": {Type: "string", Description: "Sandbox config name (default: default)"},
},
@ -183,17 +183,8 @@ func handleToolCall(req MCPRequest) {
return
}
code = toolCode
// Auto-detect language from extension
if language == "" {
switch {
case strings.HasSuffix(tool, ".go"):
language = "go"
default:
language = "bash"
}
}
// For bash with args, wrap script to receive positional params
if language == "bash" && len(toolArgs) > 0 {
if len(toolArgs) > 0 {
// Escape args for bash array
var escaped []string
for _, arg := range toolArgs {

View File

@ -94,8 +94,11 @@ func parseFrontMatter(path string) (*ToolMeta, error) {
scanner := bufio.NewScanner(f)
for scanner.Scan() {
line := scanner.Text()
// Handle both shell (#) and Go (//) comments
if comment, ok := strings.CutPrefix(line, "#"); ok {
line = strings.TrimSpace(comment)
} else if comment, ok := strings.CutPrefix(line, "//"); ok {
line = strings.TrimSpace(comment)
} else {
break
}
@ -114,7 +117,7 @@ func parseFrontMatter(path string) (*ToolMeta, error) {
return meta, nil
}
// listAllTools scans all tools directories and returns metadata for all .sh files
// listAllTools scans all tools directories and returns metadata for all tool files
func (t *ToolsFS) listAllTools() ([]*ToolMeta, error) {
seen := make(map[string]bool)
var tools []*ToolMeta
@ -126,17 +129,22 @@ func (t *ToolsFS) listAllTools() ([]*ToolMeta, error) {
}
for _, entry := range entries {
if entry.IsDir() || !strings.HasSuffix(entry.Name(), ".sh") {
name := entry.Name()
if entry.IsDir() {
continue
}
if seen[entry.Name()] {
// Include .sh and .go files
if !strings.HasSuffix(name, ".sh") && !strings.HasSuffix(name, ".go") {
continue
}
meta, err := parseFrontMatter(filepath.Join(dir, entry.Name()))
if seen[name] {
continue
}
meta, err := parseFrontMatter(filepath.Join(dir, name))
if err != nil {
continue
}
seen[entry.Name()] = true
seen[name] = true
tools = append(tools, meta)
}
}
@ -170,15 +178,15 @@ func (t *ToolsFS) List(path string) ([]plan9.Dir, error) {
func (t *ToolsFS) Read(path string) ([]byte, error) {
parts := strings.Split(strings.TrimPrefix(path, "/"), "/")
// /tools/<tool.sh> - read tool script
// /tools/<tool> - read tool script
if len(parts) != 2 || parts[0] != "tools" {
return nil, fmt.Errorf("not found")
}
filename := parts[1]
if !strings.HasSuffix(filename, ".sh") {
return nil, fmt.Errorf("not a shell script")
if !strings.HasSuffix(filename, ".sh") && !strings.HasSuffix(filename, ".go") {
return nil, fmt.Errorf("not a tool file")
}
// Prevent path traversal