Run D&D spell lanes through typed artifacts

This commit is contained in:
2026-07-17 07:19:58 +00:00
parent 52e6b31408
commit 66de1a5520
17 changed files with 699 additions and 56 deletions

View File

@@ -1,6 +1,7 @@
package pipeline
import (
"context"
"fmt"
"reflect"
"sort"
@@ -47,6 +48,7 @@ type typedValidatorEntry struct {
valueType reflect.Type
validateOptions OptionValidator
builder func(BuildRequest) (any, error)
validate typedValidateOperation
}
type chunkValidatorEntry struct {
@@ -159,6 +161,17 @@ func RegisterTypedValidatorBuilder[T any](registry *ValidatorRegistry, kind cont
builder: func(request BuildRequest) (any, error) {
return builder(cloneBuildRequest(request))
},
validate: func(ctx context.Context, implementation any, target typedValidationTarget) (contracts.ValidationResult, error) {
validator, ok := implementation.(contracts.TypedValidator[T])
if !ok {
return contracts.ValidationResult{}, fmt.Errorf("validator %q has incompatible implementation %T", normalizedSpec.Key, implementation)
}
value, err := exactTypedValue[T]("validate artifact value", target.value)
if err != nil {
return contracts.ValidationResult{}, err
}
return validator.Validate(ctx, contracts.TypedValidationRequest[T]{Stage: string(target.stage), LaneID: target.laneID, ModuleKey: target.moduleKey, Source: target.source, SourceID: target.sourceID, SourceInput: target.sourceInput, SessionID: target.sessionID, References: target.references, LLMProfile: target.llmProfile, Metadata: target.metadata, Chunk: target.chunk, Chunks: target.chunks, Ref: target.ref, Value: value})
},
}
return nil
}
@@ -302,6 +315,20 @@ func (r *ValidatorRegistry) Spec(key string) (ValidatorSpec, bool) {
return ValidatorSpec{}, false
}
spec, ok := r.legacySpecs[strings.TrimSpace(key)]
if ok {
return spec, true
}
normalized := strings.TrimSpace(key)
if entry, found := r.chunkEntries[normalized]; found {
return entry.spec, true
}
if entry, found := r.serializedEntries[normalized]; found {
return entry.spec.ValidatorSpec, true
}
if kinds := r.registeredTypedKinds(normalized); len(kinds) > 0 {
entry, found := r.typedEntry(normalized, kinds[0])
return entry.spec, found
}
return spec, ok
}