feat: import agents_and_robots platform as unibots (Matrix-out, unibus transport)
Reemplaza el scaffold del echobot por la plataforma completa de bots traida desde ~/DataProyects/Github/agents_and_robots tras la operacion Matrix-out: los bots ya no hablan por Matrix sino por el bus unibus (modelo todo-rooms + E2E via shell/transportunibus sobre github.com/enmanuel/unibus/pkg/client). - go.mod: replace de unibus -> ../unibus y de fn-registry -> ../../../.. (paths relativos reajustados a la nueva ubicacion dentro de fn_registry). - app.md: bump a 0.2.0, descripcion + arquitectura + comandos + gotchas reales. - modulo Go conservado como github.com/enmanuel/agents (sin reescribir imports). agents_and_robots queda archivado como museo de la era Matrix.
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
package decision
|
||||
|
||||
import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Rule maps a condition to a set of actions.
|
||||
type Rule struct {
|
||||
Name string
|
||||
Match MatchFunc
|
||||
Actions []Action
|
||||
}
|
||||
|
||||
// MatchFunc is a pure predicate over a MessageContext.
|
||||
type MatchFunc func(ctx MessageContext) bool
|
||||
|
||||
// Evaluate runs all rules against the context and returns the matching actions. Pure.
|
||||
func Evaluate(ctx MessageContext, rules []Rule) []Action {
|
||||
var actions []Action
|
||||
for _, rule := range rules {
|
||||
if rule.Match(ctx) {
|
||||
actions = append(actions, rule.Actions...)
|
||||
}
|
||||
}
|
||||
return actions
|
||||
}
|
||||
|
||||
// MatchCommand returns a MatchFunc that matches when the command equals cmd.
|
||||
func MatchCommand(cmd string) MatchFunc {
|
||||
return func(ctx MessageContext) bool {
|
||||
return strings.EqualFold(ctx.Command, cmd)
|
||||
}
|
||||
}
|
||||
|
||||
// MatchPrefix returns a MatchFunc that matches when content starts with prefix.
|
||||
func MatchPrefix(prefix string) MatchFunc {
|
||||
return func(ctx MessageContext) bool {
|
||||
return strings.HasPrefix(ctx.Content, prefix)
|
||||
}
|
||||
}
|
||||
|
||||
// MatchAny returns a MatchFunc that matches any message.
|
||||
func MatchAny() MatchFunc {
|
||||
return func(_ MessageContext) bool { return true }
|
||||
}
|
||||
|
||||
// MatchMinPowerLevel returns a MatchFunc that requires a minimum Matrix power level.
|
||||
func MatchMinPowerLevel(level int) MatchFunc {
|
||||
return func(ctx MessageContext) bool {
|
||||
return ctx.PowerLevel >= level
|
||||
}
|
||||
}
|
||||
|
||||
// And composes multiple MatchFuncs with logical AND.
|
||||
func And(fns ...MatchFunc) MatchFunc {
|
||||
return func(ctx MessageContext) bool {
|
||||
for _, fn := range fns {
|
||||
if !fn(ctx) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
// Or composes multiple MatchFuncs with logical OR.
|
||||
func Or(fns ...MatchFunc) MatchFunc {
|
||||
return func(ctx MessageContext) bool {
|
||||
for _, fn := range fns {
|
||||
if fn(ctx) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
// Package decision implements the pure decision engine.
|
||||
// Input: MessageContext. Output: []Action. Zero side effects.
|
||||
package decision
|
||||
|
||||
import "github.com/enmanuel/agents/pkg/tools"
|
||||
|
||||
// MessageContext holds all the information about an incoming message.
|
||||
type MessageContext struct {
|
||||
SenderID string
|
||||
SenderName string
|
||||
RoomID string
|
||||
EventID string // Matrix event ID of the incoming message
|
||||
Content string
|
||||
Command string // parsed command name, e.g. "deploy"
|
||||
Args []string // parsed arguments
|
||||
PowerLevel int
|
||||
IsDirectMsg bool
|
||||
IsMention bool
|
||||
ThreadID string
|
||||
}
|
||||
|
||||
// ActionKind is the type of action to perform.
|
||||
type ActionKind string
|
||||
|
||||
const (
|
||||
ActionKindReply ActionKind = "reply"
|
||||
ActionKindSSH ActionKind = "ssh"
|
||||
ActionKindHTTP ActionKind = "http"
|
||||
ActionKindScript ActionKind = "script"
|
||||
ActionKindFileOps ActionKind = "file_ops"
|
||||
ActionKindMCP ActionKind = "mcp"
|
||||
ActionKindLLM ActionKind = "llm"
|
||||
ActionKindDelegate ActionKind = "delegate"
|
||||
)
|
||||
|
||||
// Action is a pure description of what the shell should do.
|
||||
// It is a tagged union — only the field matching Kind is set.
|
||||
type Action struct {
|
||||
Kind ActionKind
|
||||
Reply *ReplyAction
|
||||
SSH *tools.SSHCommandSpec
|
||||
HTTP *tools.HTTPCallSpec
|
||||
Script *tools.ScriptSpec
|
||||
FileOps *tools.FileOpsSpec
|
||||
MCP *tools.MCPCallSpec
|
||||
LLM *LLMAction
|
||||
Delegate *DelegateAction
|
||||
}
|
||||
|
||||
type ReplyAction struct {
|
||||
Content string
|
||||
ThreadID string // empty = new thread
|
||||
InReplyTo string // Matrix event ID to reply to (m.in_reply_to)
|
||||
Reaction string // optional Matrix reaction
|
||||
}
|
||||
|
||||
type LLMAction struct {
|
||||
ContextKey string // key to look up conversation history
|
||||
ExtraTools []string // additional tool names to make available
|
||||
}
|
||||
|
||||
type DelegateAction struct {
|
||||
TargetAgentID string
|
||||
Task string
|
||||
Context map[string]string
|
||||
}
|
||||
Reference in New Issue
Block a user