Repo iniciado
This commit is contained in:
@@ -0,0 +1,78 @@
|
||||
// Package effects interprets pure []decision.Action values into real side effects.
|
||||
package effects
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
|
||||
"github.com/enmanuel/agents/pkg/decision"
|
||||
"github.com/enmanuel/agents/shell/ssh"
|
||||
)
|
||||
|
||||
// Result holds the outcome of executing a single action.
|
||||
type Result struct {
|
||||
Action decision.Action
|
||||
Output string
|
||||
Err error
|
||||
}
|
||||
|
||||
// MatrixSender is satisfied by shell/matrix.Client.
|
||||
type MatrixSender interface {
|
||||
SendText(ctx context.Context, roomID, text string) error
|
||||
SendTyping(ctx context.Context, roomID string, typing bool) error
|
||||
}
|
||||
|
||||
// Runner interprets actions and executes them.
|
||||
type Runner struct {
|
||||
matrix MatrixSender
|
||||
ssh *ssh.Executor
|
||||
logger *slog.Logger
|
||||
}
|
||||
|
||||
// NewRunner creates a Runner with the provided dependencies.
|
||||
func NewRunner(matrix MatrixSender, ssh *ssh.Executor, logger *slog.Logger) *Runner {
|
||||
return &Runner{matrix: matrix, ssh: ssh, logger: logger}
|
||||
}
|
||||
|
||||
// Execute runs each action sequentially and returns results.
|
||||
func (r *Runner) Execute(ctx context.Context, roomID string, actions []decision.Action) []Result {
|
||||
results := make([]Result, 0, len(actions))
|
||||
for _, a := range actions {
|
||||
res := r.executeOne(ctx, roomID, a)
|
||||
results = append(results, res)
|
||||
if res.Err != nil {
|
||||
r.logger.Error("action failed", "kind", a.Kind, "err", res.Err)
|
||||
}
|
||||
}
|
||||
return results
|
||||
}
|
||||
|
||||
func (r *Runner) executeOne(ctx context.Context, roomID string, a decision.Action) Result {
|
||||
switch a.Kind {
|
||||
case decision.ActionKindReply:
|
||||
if a.Reply == nil {
|
||||
return Result{Action: a, Err: fmt.Errorf("nil reply action")}
|
||||
}
|
||||
target := roomID
|
||||
if a.Reply.ThreadID != "" {
|
||||
target = a.Reply.ThreadID
|
||||
}
|
||||
err := r.matrix.SendText(ctx, target, a.Reply.Content)
|
||||
return Result{Action: a, Output: a.Reply.Content, Err: err}
|
||||
|
||||
case decision.ActionKindSSH:
|
||||
if a.SSH == nil {
|
||||
return Result{Action: a, Err: fmt.Errorf("nil ssh action")}
|
||||
}
|
||||
res := r.ssh.Execute(ctx, *a.SSH)
|
||||
output := res.Stdout
|
||||
if res.Stderr != "" {
|
||||
output += "\nstderr: " + res.Stderr
|
||||
}
|
||||
return Result{Action: a, Output: output, Err: res.Err}
|
||||
|
||||
default:
|
||||
return Result{Action: a, Err: fmt.Errorf("unhandled action kind: %s", a.Kind)}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user