From 44592065d8d2cb8bb79a4aee0155f66e595b81d2 Mon Sep 17 00:00:00 2001 From: Levi Neely Date: Thu, 6 Aug 2026 11:17:10 +0200 Subject: [PATCH] fix: respect agent-provided timeout and sandbox params in callPromotedTool callPromotedTool was hardcoding timeout=30 and sandbox="default" for all promoted tool executions, ignoring the timeout and sandbox parameters provided by the agent in tool call args. Extract these from the JSON args map (same pattern as elevated) and pass them through to the execution functions. --- toolsrv/server.go | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/toolsrv/server.go b/toolsrv/server.go index f3b355b..a68b89a 100644 --- a/toolsrv/server.go +++ b/toolsrv/server.go @@ -216,8 +216,10 @@ func (e *Server) callPromotedTool(ctx context.Context, tool string, args json.Ra return nil, err } - // Extract elevated flag (dispatch-level concern, not passed to tool). + // Extract dispatch-level flags (not passed to tool script). elevated := false + timeout := 30 + sandboxName := "default" var argMap map[string]interface{} if err := json.Unmarshal(args, &argMap); err == nil { if e, ok := argMap["elevated"]; ok { @@ -227,10 +229,27 @@ func (e *Server) callPromotedTool(ctx context.Context, tool string, args json.Ra case string: elevated = v == "true" || v == "1" } - // Remove elevated from the args passed to the tool. delete(argMap, "elevated") - args, _ = json.Marshal(argMap) } + if t, ok := argMap["timeout"]; ok { + switch v := t.(type) { + case float64: + timeout = int(v) + case string: + var n int + if _, err := fmt.Sscanf(v, "%d", &n); err == nil { + timeout = n + } + } + delete(argMap, "timeout") + } + if s, ok := argMap["sandbox"]; ok { + if v, ok := s.(string); ok && v != "" { + sandboxName = v + } + delete(argMap, "sandbox") + } + args, _ = json.Marshal(argMap) } // Check if tool requires sudo (from .meta). @@ -253,16 +272,16 @@ func (e *Server) callPromotedTool(ctx context.Context, tool string, args json.Ra workDir := e.cwd e.wdMu.RUnlock() sudoCode := fmt.Sprintf("cat <<'OLLIE_EOF' | %s\n%s\nOLLIE_EOF", code, stdinData) - result, err = e.executeElevatedSudo(ctx, sudoCode, workDir, 30) + result, err = e.executeElevatedSudo(ctx, sudoCode, workDir, timeout) } else if elevated { e.wdMu.RLock() workDir := e.cwd e.wdMu.RUnlock() // Broker protocol has no stdin support; pipe JSON via heredoc. elevatedCode := fmt.Sprintf("cat <<'OLLIE_EOF' | %s\n%s\nOLLIE_EOF", code, stdinData) - result, err = e.executeElevated(ctx, elevatedCode, workDir, 30) + result, err = e.executeElevated(ctx, elevatedCode, workDir, timeout) } else { - result, err = e.executeWithStdin(ctx, code, "bash", 30, "default", false, stdinData) + result, err = e.executeWithStdin(ctx, code, "bash", timeout, sandboxName, false, stdinData) } if err != nil { return json.Marshal(map[string]interface{}{