Files
Agent-Native/runtime/tools/alias.go
weichenandCursor dfd0d23bf3 Add pi tool aliases, context files, and project trust
Why: Headless runs need the pi tool names, walked context files, prompt includes, and a trust gate before project settings are loaded.
Evidence: go test -count=1 ./runtime/tools/ ./runtime/resources/ ./runtime/skills/
Impact: Existing tool names stay registered. Aliases are added only when the underlying tool exists.
Refs: feature/pi-headless N4
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-01 10:12:26 +00:00

84 lines
2.0 KiB
Go

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
}