refactor: extraer campo sender en Agent para desacoplar envio de mensajes
Añade un campo `sender effects.MatrixSender` al struct Agent que reemplaza las llamadas directas a `a.matrix` para enviar mensajes (sendReply, typing, SendMarkdown en handleTaskEvent). En produccion, sender apunta al mismo *matrix.Client. Esto permite inyectar un spy en tests sin requerir una conexion real a Matrix. El campo `a.matrix` se mantiene para operaciones que no son de envio (SetPresence, Raw, etc.). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
+8
-8
@@ -29,8 +29,8 @@ func (a *Agent) handleEvent(ctx context.Context, msgCtx decision.MessageContext,
|
|||||||
a.roomCtx.Set(roomID)
|
a.roomCtx.Set(roomID)
|
||||||
|
|
||||||
if a.cfg.Personality.Behavior.TypingIndicator {
|
if a.cfg.Personality.Behavior.TypingIndicator {
|
||||||
_ = a.matrix.SendTyping(ctx, roomID, true)
|
_ = a.sender.SendTyping(ctx, roomID, true)
|
||||||
defer a.matrix.SendTyping(ctx, roomID, false)
|
defer a.sender.SendTyping(ctx, roomID, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── Command flow ─────────────────────────────────────────────────
|
// ── Command flow ─────────────────────────────────────────────────
|
||||||
@@ -233,8 +233,8 @@ func (a *Agent) handleTaskEvent(ctx context.Context, msg bus.AgentMessage) {
|
|||||||
a.roomCtx.Set(roomID)
|
a.roomCtx.Set(roomID)
|
||||||
|
|
||||||
if a.cfg.Personality.Behavior.TypingIndicator {
|
if a.cfg.Personality.Behavior.TypingIndicator {
|
||||||
_ = a.matrix.SendTyping(ctx, roomID, true)
|
_ = a.sender.SendTyping(ctx, roomID, true)
|
||||||
defer a.matrix.SendTyping(ctx, roomID, false)
|
defer a.sender.SendTyping(ctx, roomID, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build a synthetic MessageContext from the task
|
// Build a synthetic MessageContext from the task
|
||||||
@@ -261,7 +261,7 @@ func (a *Agent) handleTaskEvent(ctx context.Context, msg bus.AgentMessage) {
|
|||||||
if rejected {
|
if rejected {
|
||||||
a.logger.Warn("orchestrated task rejected by sanitizer",
|
a.logger.Warn("orchestrated task rejected by sanitizer",
|
||||||
"task_id", task.TaskID, "sender", task.OriginalSender)
|
"task_id", task.TaskID, "sender", task.OriginalSender)
|
||||||
_ = a.matrix.SendMarkdown(ctx, roomID, "El mensaje fue rechazado por el filtro de seguridad.")
|
_ = a.sender.SendMarkdown(ctx, roomID, "El mensaje fue rechazado por el filtro de seguridad.")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
msgCtx.Content = sanitized
|
msgCtx.Content = sanitized
|
||||||
@@ -294,7 +294,7 @@ func (a *Agent) handleTaskEvent(ctx context.Context, msg bus.AgentMessage) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Send reply to Matrix room
|
// Send reply to Matrix room
|
||||||
if sendErr := a.matrix.SendMarkdown(ctx, roomID, reply); sendErr != nil {
|
if sendErr := a.sender.SendMarkdown(ctx, roomID, reply); sendErr != nil {
|
||||||
a.logger.Error("failed to send orchestrated reply to Matrix", "err", sendErr)
|
a.logger.Error("failed to send orchestrated reply to Matrix", "err", sendErr)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -321,9 +321,9 @@ func (a *Agent) handleTaskEvent(ctx context.Context, msg bus.AgentMessage) {
|
|||||||
// If threadID is non-empty, the reply is sent as part of that thread.
|
// If threadID is non-empty, the reply is sent as part of that thread.
|
||||||
func (a *Agent) sendReply(ctx context.Context, roomID, eventID, threadID, markdown string) error {
|
func (a *Agent) sendReply(ctx context.Context, roomID, eventID, threadID, markdown string) error {
|
||||||
if threadID != "" {
|
if threadID != "" {
|
||||||
return a.matrix.SendThreadMarkdown(ctx, roomID, threadID, eventID, markdown)
|
return a.sender.SendThreadMarkdown(ctx, roomID, threadID, eventID, markdown)
|
||||||
}
|
}
|
||||||
return a.matrix.SendReplyMarkdown(ctx, roomID, eventID, markdown)
|
return a.sender.SendReplyMarkdown(ctx, roomID, eventID, markdown)
|
||||||
}
|
}
|
||||||
|
|
||||||
// parseSeverity converts a config string to sanitize.Severity.
|
// parseSeverity converts a config string to sanitize.Severity.
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ type Agent struct {
|
|||||||
rules []decision.Rule
|
rules []decision.Rule
|
||||||
llm coretypes.CompleteFunc // nil when no LLM configured (simple_bot)
|
llm coretypes.CompleteFunc // nil when no LLM configured (simple_bot)
|
||||||
matrix *matrix.Client
|
matrix *matrix.Client
|
||||||
|
sender effects.MatrixSender // used by sendReply; same object as matrix in production
|
||||||
runner *effects.Runner
|
runner *effects.Runner
|
||||||
listener *matrix.Listener
|
listener *matrix.Listener
|
||||||
toolReg *tools.Registry
|
toolReg *tools.Registry
|
||||||
@@ -157,6 +158,7 @@ func New(cfg *config.AgentConfig, rules []decision.Rule, agentACL acl.ACL, logge
|
|||||||
rules: rules,
|
rules: rules,
|
||||||
llm: llmFunc,
|
llm: llmFunc,
|
||||||
matrix: matrixClient,
|
matrix: matrixClient,
|
||||||
|
sender: matrixClient,
|
||||||
runner: runner,
|
runner: runner,
|
||||||
toolReg: toolReg,
|
toolReg: toolReg,
|
||||||
logger: logger,
|
logger: logger,
|
||||||
|
|||||||
Reference in New Issue
Block a user