package tools import ( "context" "encoding/json" ) // aliasTool exposes an existing tool under a pi-style name. type aliasTool struct { name string inner Tool } func (a aliasTool) Name() string { return a.name } func (a aliasTool) Description() string { return a.inner.Description() } func (a aliasTool) Parameters() json.RawMessage { return a.inner.Parameters() } func (a aliasTool) Execute(ctx context.Context, args json.RawMessage) (Result, error) { return a.inner.Execute(ctx, args) } // piAliases maps the headless pi tool name onto the name already registered. var piAliases = map[string]string{ "read": "read_file", "write": "write_file", "edit": "edit_file", "bash": "run_command", "grep": "grep", "find": "glob", "ls": "list_dir", } // RegisterPiAliases adds pi tool names beside the existing ones. // A name is skipped when the underlying tool is not registered. func (r *Registry) RegisterPiAliases() { for alias, inner := range piAliases { if alias == inner || r.Has(alias) || !r.Has(inner) { continue } r.Register(aliasTool{name: alias, inner: r.tools[inner]}) } } // FilterOptions selects which tools stay visible. type FilterOptions struct { Tools []string Exclude []string NoBuiltin bool } // Filter applies an allow list, then exclusions. NoBuiltin drops the // workspace tool names and their pi aliases. func (r *Registry) Filter(opts FilterOptions) error { if len(opts.Tools) > 0 { if err := r.Restrict(opts.Tools); err != nil { return err } } drop := map[string]bool{} for _, name := range opts.Exclude { drop[name] = true } if opts.NoBuiltin { for _, name := range []string{"read_file", "write_file", "edit_file", "multi_edit", "list_dir", "grep", "glob", "run_command", "run_python"} { drop[name] = true } for alias := range piAliases { drop[alias] = true } } if len(drop) == 0 { return nil } var order []string for _, name := range r.order { if drop[name] { delete(r.tools, name) continue } order = append(order, name) } r.order = order return nil }