heroagent/pkg/openrpc/manager.go
2025-05-24 09:52:43 +04:00

118 lines
2.5 KiB
Go

package openrpc
import (
"encoding/json"
"fmt"
"io/ioutil"
"path/filepath"
"strings"
"git.ourworld.tf/herocode/heroagent/pkg/openrpc/models"
)
// ORPCManager manages OpenRPC specifications
type ORPCManager struct {
specs map[string]*models.OpenRPCSpec
}
// NewORPCManager creates a new OpenRPC Manager
func NewORPCManager() *ORPCManager {
return &ORPCManager{
specs: make(map[string]*models.OpenRPCSpec),
}
}
// LoadSpecs loads all OpenRPC specifications from a directory
func (m *ORPCManager) LoadSpecs(dir string) error {
files, err := ioutil.ReadDir(dir)
if err != nil {
return fmt.Errorf("failed to read directory: %w", err)
}
for _, file := range files {
if file.IsDir() {
continue
}
if !strings.HasSuffix(file.Name(), ".json") {
continue
}
path := filepath.Join(dir, file.Name())
if err := m.LoadSpec(path); err != nil {
return fmt.Errorf("failed to load spec %s: %w", file.Name(), err)
}
}
return nil
}
// LoadSpec loads an OpenRPC specification from a file
func (m *ORPCManager) LoadSpec(path string) error {
// Read the file
data, err := ioutil.ReadFile(path)
if err != nil {
return fmt.Errorf("failed to read file: %w", err)
}
// Parse the JSON
var spec models.OpenRPCSpec
if err := json.Unmarshal(data, &spec); err != nil {
return fmt.Errorf("failed to parse JSON: %w", err)
}
// Validate the specification
if err := spec.Validate(); err != nil {
return fmt.Errorf("invalid specification: %w", err)
}
// Store the specification
name := strings.TrimSuffix(filepath.Base(path), filepath.Ext(path))
m.specs[name] = &spec
return nil
}
// GetSpec returns an OpenRPC specification by name
func (m *ORPCManager) GetSpec(name string) *models.OpenRPCSpec {
return m.specs[name]
}
// ListSpecs returns a list of all loaded specification names
func (m *ORPCManager) ListSpecs() []string {
var names []string
for name := range m.specs {
names = append(names, name)
}
return names
}
// ListMethods returns a list of all method names in a specification
func (m *ORPCManager) ListMethods(specName string) []string {
spec := m.GetSpec(specName)
if spec == nil {
return []string{}
}
var methods []string
for _, method := range spec.Methods {
methods = append(methods, method.Name)
}
return methods
}
// GetMethod returns a method from a specification
func (m *ORPCManager) GetMethod(specName, methodName string) *models.Method {
spec := m.GetSpec(specName)
if spec == nil {
return nil
}
for _, method := range spec.Methods {
if method.Name == methodName {
return &method
}
}
return nil
}