96 lines
2.6 KiB
Go
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
|
|
}
|