421ab5c773
Cuando command_prefix es "" en el config, el parser trata el primer token del mensaje como nombre de comando sin requerir el prefijo !. Si el token empieza con !, se le quita igualmente para retrocompatibilidad. Cambios: - pkg/message/parse.go: modo sin prefijo en Parse() (puro, sin side effects) - agents/robot.go: mensaje "comando desconocido" y !help adaptados al prefijo - agents/handler.go: mensaje "comando desconocido" adaptado al prefijo - internal/config/schema.go: documentar command_prefix: "" en FiltersCfg - agents/_template_robot/config.yaml: ejemplo comentado de command_prefix: "" El comportamiento con command_prefix: "!" no cambia (retrocompatible).
73 lines
2.2 KiB
Go
73 lines
2.2 KiB
Go
// Package message provides pure parsing and formatting for Matrix messages.
|
|
package message
|
|
|
|
import (
|
|
"strings"
|
|
|
|
"github.com/enmanuel/agents/pkg/decision"
|
|
)
|
|
|
|
// ParseOptions configures how messages are parsed.
|
|
type ParseOptions struct {
|
|
CommandPrefix string // e.g. "!"
|
|
BotUserID string // for mention detection, e.g. "@bot:server"
|
|
MentionedUserIDs []string // pre-extracted from m.mentions event field (modern Matrix spec)
|
|
}
|
|
|
|
// Parse converts a raw Matrix message body into a structured MessageContext. Pure.
|
|
func Parse(body, senderID, roomID string, powerLevel int, isDM bool, opts ParseOptions) decision.MessageContext {
|
|
ctx := decision.MessageContext{
|
|
SenderID: senderID,
|
|
RoomID: roomID,
|
|
Content: body,
|
|
PowerLevel: powerLevel,
|
|
IsDirectMsg: isDM,
|
|
}
|
|
|
|
// Detect mention: check m.mentions list first (modern Matrix spec).
|
|
if opts.BotUserID != "" {
|
|
for _, uid := range opts.MentionedUserIDs {
|
|
if uid == opts.BotUserID {
|
|
ctx.IsMention = true
|
|
break
|
|
}
|
|
}
|
|
// Fallback: check if full user ID appears in the plain text body.
|
|
if !ctx.IsMention && strings.Contains(body, opts.BotUserID) {
|
|
ctx.IsMention = true
|
|
}
|
|
}
|
|
|
|
// Parse command.
|
|
// When CommandPrefix is non-empty (e.g. "!"), only messages starting with that
|
|
// prefix are treated as commands.
|
|
// When CommandPrefix is empty, every message is a potential command: the first
|
|
// token is the command name. If it starts with "!", the "!" is stripped for
|
|
// backward compatibility (so both "help" and "!help" work the same).
|
|
switch {
|
|
case opts.CommandPrefix != "":
|
|
// Standard mode: require prefix
|
|
if strings.HasPrefix(body, opts.CommandPrefix) {
|
|
parts := strings.Fields(strings.TrimPrefix(body, opts.CommandPrefix))
|
|
if len(parts) > 0 {
|
|
ctx.Command = strings.ToLower(parts[0])
|
|
ctx.Args = parts[1:]
|
|
}
|
|
}
|
|
case opts.CommandPrefix == "":
|
|
// No-prefix mode: treat first token as command
|
|
parts := strings.Fields(body)
|
|
if len(parts) > 0 {
|
|
cmd := parts[0]
|
|
// Strip leading "!" for backward compatibility
|
|
cmd = strings.TrimPrefix(cmd, "!")
|
|
if cmd != "" {
|
|
ctx.Command = strings.ToLower(cmd)
|
|
ctx.Args = parts[1:]
|
|
}
|
|
}
|
|
}
|
|
|
|
return ctx
|
|
}
|