diff --git a/pkg/agent/core.go b/pkg/agent/core.go index 408b803..24bf290 100644 --- a/pkg/agent/core.go +++ b/pkg/agent/core.go @@ -47,18 +47,22 @@ type AgentEnv struct { func BuildAgentEnv(cfg *config.Config, d tools.Dispatcher, cwd string) AgentEnv { var messages []string - allToolInfos, listErr := d.ListTools() - if listErr != nil { - messages = append(messages, fmt.Sprintf("list tools: %v", listErr)) - } + var allToolInfos []tools.ToolInfo + var allTools []backend.Tool + serverOf := make(map[string]string) - serverOf := make(map[string]string, len(allToolInfos)) - for _, t := range allToolInfos { - serverOf[t.Name] = t.Server + if cfg == nil || cfg.ToolsEnabled() { + var listErr error + allToolInfos, listErr = d.ListTools() + if listErr != nil { + messages = append(messages, fmt.Sprintf("list tools: %v", listErr)) + } + for _, t := range allToolInfos { + serverOf[t.Name] = t.Server + } + allTools = toolInfosToBackend(allToolInfos) } - allTools := toolInfosToBackend(allToolInfos) - hooks := Hooks{} var preamble string var genParams backend.GenerationParams diff --git a/pkg/agent/core_test.go b/pkg/agent/core_test.go index ed1ccbf..beb7fd8 100644 --- a/pkg/agent/core_test.go +++ b/pkg/agent/core_test.go @@ -2335,6 +2335,19 @@ func TestBuildAgentEnv_ToolsPopulated(t *testing.T) { } } +func TestBuildAgentEnv_ToolsDisabled(t *testing.T) { + setupCfgDir(t) + d := &mockDispatcher{ + tools: []tools.ToolInfo{{Server: "s1", Name: "mytool", Description: "desc", InputSchema: json.RawMessage(`{}`)}}, + } + f := false + cfg := &config.Config{Tools: &f} + env := BuildAgentEnv(cfg, d, t.TempDir()) + if len(env.tools) != 0 { + t.Errorf("expected no tools when disabled; got %+v", env.tools) + } +} + func TestBuildAgentEnv_TrustedTools(t *testing.T) { setupCfgDir(t) setter := &mockTrustedSetter{} diff --git a/pkg/config/config.go b/pkg/config/config.go index c3bcc3f..608af02 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -61,6 +61,7 @@ func (p Prompt) MarshalJSON() ([]byte, error) { type Config struct { Hooks map[string]HookCmds `json:"hooks,omitempty"` Prompt Prompt `json:"prompt,omitempty"` + Tools *bool `json:"tools,omitempty"` TrustedTools []string `json:"trustedTools,omitempty"` MaxTokens int `json:"maxTokens,omitempty"` Temperature *float64 `json:"temperature,omitempty"` @@ -76,3 +77,9 @@ func Load(r io.Reader) (*Config, error) { } return &cfg, nil } + +// ToolsEnabled reports whether tool use is enabled. Defaults to true when +// the field is omitted from the config. +func (c *Config) ToolsEnabled() bool { + return c.Tools == nil || *c.Tools +} diff --git a/pkg/config/config_test.go b/pkg/config/config_test.go index 62f54f4..3a0b449 100644 --- a/pkg/config/config_test.go +++ b/pkg/config/config_test.go @@ -121,3 +121,21 @@ func TestLoadAllFields(t *testing.T) { t.Errorf("PresencePenalty = %v", cfg.PresencePenalty) } } + +func TestToolsEnabled(t *testing.T) { + // Omitted: defaults to true. + cfg, _ := Load(strings.NewReader(`{}`)) + if !cfg.ToolsEnabled() { + t.Error("expected ToolsEnabled()=true when omitted") + } + // Explicit false. + cfg, _ = Load(strings.NewReader(`{"tools": false}`)) + if cfg.ToolsEnabled() { + t.Error("expected ToolsEnabled()=false") + } + // Explicit true. + cfg, _ = Load(strings.NewReader(`{"tools": true}`)) + if !cfg.ToolsEnabled() { + t.Error("expected ToolsEnabled()=true") + } +} \ No newline at end of file