Add tool requires approval

This commit is contained in:
dwrz
2026-10-06 12:08:12 +00:00
parent bbfac06732
commit 83ff81dd2c
4 changed files with 66 additions and 11 deletions
+3
View File
@@ -238,6 +238,9 @@ type ToolConfig struct {
Parameters map[string]any `yaml:"parameters"` Parameters map[string]any `yaml:"parameters"`
// Timeout limits execution time (e.g., "30s", "5m"). Zero means no limit. // Timeout limits execution time (e.g., "30s", "5m"). Zero means no limit.
Timeout time.Duration `yaml:"timeout"` Timeout time.Duration `yaml:"timeout"`
// RequiresApproval specifies whether a tool must be approved by a user
// to execute.
RequiresApproval bool `yaml:"require_approval,omitempty"`
} }
func (cfg ToolConfig) Validate() error { func (cfg ToolConfig) Validate() error {
+44
View File
@@ -386,6 +386,50 @@ tools:
cfg.Tools[0].Name, "echo", cfg.Tools[0].Name, "echo",
) )
} }
if cfg.Tools[0].RequiresApproval {
t.Error("Tools[0].RequiresApproval = true, want false")
}
},
},
{
name: "tool with require_approval",
config: `
database:
path: "/tmp/odidere-test.db"
default_model:
provider: testprovider
model: test-model
providers:
- name: testprovider
url: http://localhost:8080
stt:
url: http://localhost:8178
tts:
url: http://localhost:8880
voice: af_heart
tools:
- name: echo
description: echoes input
command: echo
arguments:
- "{{.message}}"
require_approval: true
`,
check: func(t *testing.T, cfg *Config) {
if len(cfg.Tools) != 1 {
t.Errorf(
"len(Tools) = %d, want 1",
len(cfg.Tools),
)
}
if !cfg.Tools[0].RequiresApproval {
t.Error("Tools[0].RequiresApproval = false, want true")
}
}, },
}, },
{ {
+4
View File
@@ -52,6 +52,9 @@ type Tool struct {
// used to validate a tool call before its arguments are rendered. See // used to validate a tool call before its arguments are rendered. See
// config.ToolConfig.Parameters. // config.ToolConfig.Parameters.
Parameters map[string]any Parameters map[string]any
// RequiresApproval reports whether calls to this tool must be approved
// by a user before the subprocess launches.
RequiresApproval bool
// timeout is the parsed execution duration limit. // timeout is the parsed execution duration limit.
timeout time.Duration timeout time.Duration
} }
@@ -77,6 +80,7 @@ func NewTool(cfg config.ToolConfig) (*Tool, error) {
Command: cfg.Command, Command: cfg.Command,
Arguments: cfg.Arguments, Arguments: cfg.Arguments,
Parameters: cfg.Parameters, Parameters: cfg.Parameters,
RequiresApproval: cfg.RequiresApproval,
tmpl: templates, tmpl: templates,
timeout: cfg.Timeout, timeout: cfg.Timeout,
}, nil }, nil
+4
View File
@@ -116,6 +116,7 @@ func TestNewTool(t *testing.T) {
Description: "desc", Description: "desc",
Command: "ls", Command: "ls",
Timeout: 10 * time.Second, Timeout: 10 * time.Second,
RequiresApproval: true,
}) })
if err != nil { if err != nil {
t.Fatalf("NewTool() error = %v", err) t.Fatalf("NewTool() error = %v", err)
@@ -123,6 +124,9 @@ func TestNewTool(t *testing.T) {
if tool.Name != "test" { if tool.Name != "test" {
t.Errorf("Name = %q, want %q", tool.Name, "test") t.Errorf("Name = %q, want %q", tool.Name, "test")
} }
if !tool.RequiresApproval {
t.Error("RequiresApproval = false, want true")
}
if tool.timeout != 10*time.Second { if tool.timeout != 10*time.Second {
t.Errorf("timeout = %v, want 10s", tool.timeout) t.Errorf("timeout = %v, want 10s", tool.timeout)
} }