Files
agentmon/internal/event/validate.go
T
2026-03-26 11:22:34 -07:00

91 lines
2.5 KiB
Go

package event
import (
"errors"
"fmt"
)
var validTypes = map[string]bool{
"session.start": true,
"session.end": true,
"run.start": true,
"run.end": true,
"span.start": true,
"span.end": true,
"error": true,
"metric.snapshot": true,
"openclaw.snapshot": true,
"swarm.snapshot": true,
"swarm.service.snapshot": true,
}
type ValidationError struct {
Field string
Message string
}
func (e ValidationError) Error() string {
return fmt.Sprintf("%s: %s", e.Field, e.Message)
}
func Validate(m map[string]any) error {
// Check schema
schema, ok := m["schema"].(map[string]any)
if !ok {
return ValidationError{Field: "schema", Message: "missing or invalid"}
}
if name, _ := schema["name"].(string); name != "agentmon.event" && name != "agentmon.openclaw" {
return ValidationError{Field: "schema.name", Message: "must be 'agentmon.event' or 'agentmon.openclaw'"}
}
if ver, _ := schema["version"].(float64); ver != 1 {
return ValidationError{Field: "schema.version", Message: "must be 1"}
}
// Check event
event, ok := m["event"].(map[string]any)
if !ok {
return ValidationError{Field: "event", Message: "missing or invalid"}
}
if id, _ := event["id"].(string); id == "" {
return ValidationError{Field: "event.id", Message: "required"}
}
eventType, _ := event["type"].(string)
if eventType == "" {
return ValidationError{Field: "event.type", Message: "required"}
}
if !validTypes[eventType] {
return ValidationError{Field: "event.type", Message: fmt.Sprintf("invalid type '%s'", eventType)}
}
if event["ts"] == nil {
return ValidationError{Field: "event.ts", Message: "required"}
}
// Source is optional for openclaw.snapshot events
if eventType != "openclaw.snapshot" && eventType != "swarm.snapshot" && eventType != "swarm.service.snapshot" {
source, ok := event["source"].(map[string]any)
if !ok {
return ValidationError{Field: "event.source", Message: "missing or invalid"}
}
if fw, _ := source["framework"].(string); fw == "" {
return ValidationError{Field: "event.source.framework", Message: "required"}
}
if cid, _ := source["client_id"].(string); cid == "" {
return ValidationError{Field: "event.source.client_id", Message: "required"}
}
if host, _ := source["host"].(string); host == "" {
return ValidationError{Field: "event.source.host", Message: "required"}
}
}
return nil
}
func IsValidationError(err error) bool {
var ve ValidationError
return errors.As(err, &ve)
}