heroagent/pkg/heroscript/handlerfactory/core/base.go
2025-04-23 04:18:28 +02:00

96 lines
2.6 KiB
Go

package core
import (
"fmt"
"reflect"
"strings"
"github.com/freeflowuniverse/heroagent/pkg/heroscript/paramsparser"
"github.com/freeflowuniverse/heroagent/pkg/heroscript/playbook"
)
// Handler interface defines methods that all handlers must implement
type Handler interface {
GetActorName() string
Play(script string, handler interface{}) (string, error)
}
// BaseHandler provides common functionality for all handlers
type BaseHandler struct {
ActorName string
}
// GetActorName returns the actor name for this handler
func (h *BaseHandler) GetActorName() string {
return h.ActorName
}
// Play processes all actions for this handler's actor
func (h *BaseHandler) Play(script string, handler interface{}) (string, error) {
pb, err := playbook.NewFromText(script)
if err != nil {
return "", fmt.Errorf("failed to parse heroscript: %v", err)
}
// Find all actions for this actor
actions, err := pb.FindActions(0, h.ActorName, "", playbook.ActionTypeUnknown)
if err != nil {
return "", fmt.Errorf("failed to find actions: %v", err)
}
if len(actions) == 0 {
return "", fmt.Errorf("no actions found for actor: %s", h.ActorName)
}
var results []string
// Process each action
for _, action := range actions {
// Convert action name to method name (e.g., "disk_add" -> "DiskAdd")
methodName := convertToMethodName(action.Name)
// Get the method from the handler
method := reflect.ValueOf(handler).MethodByName(methodName)
if !method.IsValid() {
return "", fmt.Errorf("action not supported: %s.%s", h.ActorName, action.Name)
}
// Call the method with the action's heroscript
actionScript := action.HeroScript()
args := []reflect.Value{reflect.ValueOf(actionScript)}
result := method.Call(args)
// Get the result
if len(result) > 0 {
resultStr := result[0].String()
results = append(results, resultStr)
}
}
return strings.Join(results, "\n"), nil
}
// ParseParams parses parameters from a heroscript action
func (h *BaseHandler) ParseParams(script string) (*paramsparser.ParamsParser, error) {
pb, err := playbook.NewFromText(script)
if err != nil {
return nil, fmt.Errorf("failed to parse heroscript: %v", err)
}
// Get the first action
if len(pb.Actions) == 0 {
return nil, fmt.Errorf("no actions found in script")
}
// Get the first action
action := pb.Actions[0]
// Check if the action is for this handler
if action.Actor != h.ActorName {
return nil, fmt.Errorf("action actor '%s' does not match handler actor '%s'", action.Actor, h.ActorName)
}
// The action already has a ParamsParser, so we can just return it
return action.Params, nil
}