Add tool requires approval
This commit is contained in:
@@ -238,6 +238,9 @@ type ToolConfig struct {
|
||||
Parameters map[string]any `yaml:"parameters"`
|
||||
// Timeout limits execution time (e.g., "30s", "5m"). Zero means no limit.
|
||||
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 {
|
||||
|
||||
@@ -386,6 +386,50 @@ tools:
|
||||
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")
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
|
||||
+11
-7
@@ -52,6 +52,9 @@ type Tool struct {
|
||||
// used to validate a tool call before its arguments are rendered. See
|
||||
// config.ToolConfig.Parameters.
|
||||
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 time.Duration
|
||||
}
|
||||
@@ -72,13 +75,14 @@ func NewTool(cfg config.ToolConfig) (*Tool, error) {
|
||||
}
|
||||
|
||||
return &Tool{
|
||||
Name: cfg.Name,
|
||||
Description: cfg.Description,
|
||||
Command: cfg.Command,
|
||||
Arguments: cfg.Arguments,
|
||||
Parameters: cfg.Parameters,
|
||||
tmpl: templates,
|
||||
timeout: cfg.Timeout,
|
||||
Name: cfg.Name,
|
||||
Description: cfg.Description,
|
||||
Command: cfg.Command,
|
||||
Arguments: cfg.Arguments,
|
||||
Parameters: cfg.Parameters,
|
||||
RequiresApproval: cfg.RequiresApproval,
|
||||
tmpl: templates,
|
||||
timeout: cfg.Timeout,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -112,10 +112,11 @@ func TestTool_ParseArguments_ExecutionError(t *testing.T) {
|
||||
|
||||
func TestNewTool(t *testing.T) {
|
||||
tool, err := NewTool(config.ToolConfig{
|
||||
Name: "test",
|
||||
Description: "desc",
|
||||
Command: "ls",
|
||||
Timeout: 10 * time.Second,
|
||||
Name: "test",
|
||||
Description: "desc",
|
||||
Command: "ls",
|
||||
Timeout: 10 * time.Second,
|
||||
RequiresApproval: true,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("NewTool() error = %v", err)
|
||||
@@ -123,6 +124,9 @@ func TestNewTool(t *testing.T) {
|
||||
if 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 {
|
||||
t.Errorf("timeout = %v, want 10s", tool.timeout)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user