feat: sistema RegisterCommand para comandos por agente
Añade RegisterCommand(spec, handler) al Agent para que cada agente pueda registrar comandos propios (!xxx) sin modificar built-ins ni usar reglas. Cambios principales: - agents/runtime.go: nuevo método RegisterCommand + campo customSpecs - agents/commands.go: !help muestra comandos del agente en sección separada, extrae writeSpec helper, elimina customCommandRules (ya no se usan reglas para comandos) - handleEvent simplificado: los comandos se resuelven por lookup directo (built-in + registered), nunca pasan por reglas ni LLM Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
+22
-22
@@ -22,7 +22,7 @@ func (a *Agent) registerBuiltinCommands() {
|
||||
a.commands["version"] = a.cmdVersion
|
||||
}
|
||||
|
||||
// cmdHelp lists all available commands (built-in + custom rules with MatchCommand).
|
||||
// cmdHelp lists all available commands (built-in + agent-specific).
|
||||
func (a *Agent) cmdHelp(_ context.Context, _ decision.MessageContext) string {
|
||||
var b strings.Builder
|
||||
b.WriteString("Comandos disponibles:\n\n")
|
||||
@@ -32,25 +32,36 @@ func (a *Agent) cmdHelp(_ context.Context, _ decision.MessageContext) string {
|
||||
if spec.Hidden {
|
||||
continue
|
||||
}
|
||||
aliases := ""
|
||||
if len(spec.Aliases) > 0 {
|
||||
aliases = " (" + strings.Join(prefixAll(spec.Aliases, "!"), ", ") + ")"
|
||||
}
|
||||
fmt.Fprintf(&b, " %s%s — %s\n", spec.Usage, aliases, spec.Description)
|
||||
writeSpec(&b, spec)
|
||||
}
|
||||
|
||||
// Custom commands from agent rules (rules named with MatchCommand pattern)
|
||||
customRules := a.customCommandRules()
|
||||
if len(customRules) > 0 {
|
||||
// Agent-specific commands (registered via RegisterCommand)
|
||||
if len(a.customSpecs) > 0 {
|
||||
b.WriteString("\nComandos del agente:\n")
|
||||
for _, name := range customRules {
|
||||
fmt.Fprintf(&b, " !%s\n", name)
|
||||
for _, spec := range a.customSpecs {
|
||||
if spec.Hidden {
|
||||
continue
|
||||
}
|
||||
writeSpec(&b, spec)
|
||||
}
|
||||
}
|
||||
|
||||
return b.String()
|
||||
}
|
||||
|
||||
// writeSpec formats a single command spec for the help output.
|
||||
func writeSpec(b *strings.Builder, spec command.Spec) {
|
||||
aliases := ""
|
||||
if len(spec.Aliases) > 0 {
|
||||
aliases = " (" + strings.Join(prefixAll(spec.Aliases, "!"), ", ") + ")"
|
||||
}
|
||||
usage := spec.Usage
|
||||
if usage == "" {
|
||||
usage = "!" + spec.Name
|
||||
}
|
||||
fmt.Fprintf(b, " %s%s — %s\n", usage, aliases, spec.Description)
|
||||
}
|
||||
|
||||
// cmdTools lists all tools registered in the agent's tool registry.
|
||||
func (a *Agent) cmdTools(_ context.Context, _ decision.MessageContext) string {
|
||||
names := a.toolReg.Names()
|
||||
@@ -159,17 +170,6 @@ func (a *Agent) cmdVersion(_ context.Context, _ decision.MessageContext) string
|
||||
return fmt.Sprintf("%s %s", a.cfg.Agent.Name, v)
|
||||
}
|
||||
|
||||
// customCommandRules extracts rule names that look like command handlers.
|
||||
func (a *Agent) customCommandRules() []string {
|
||||
var names []string
|
||||
for _, r := range a.rules {
|
||||
if r.Name != "" {
|
||||
names = append(names, r.Name)
|
||||
}
|
||||
}
|
||||
return names
|
||||
}
|
||||
|
||||
// prefixAll adds a prefix to each string in a slice.
|
||||
func prefixAll(ss []string, prefix string) []string {
|
||||
out := make([]string, len(ss))
|
||||
|
||||
Reference in New Issue
Block a user