87 lines
2.2 KiB
Go
87 lines
2.2 KiB
Go
package v2
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"predictor-refactored/internal/engine"
|
|
)
|
|
|
|
// buildProfile translates a PredictionRequest into an engine.Profile via
|
|
// the engine registry.
|
|
func buildProfile(req PredictionRequest, deps engine.BuildDeps) (engine.Profile, error) {
|
|
if len(req.Profile) == 0 {
|
|
return engine.Profile{}, fmt.Errorf("profile must contain at least one stage")
|
|
}
|
|
|
|
step := req.Options.StepSeconds
|
|
if step == 0 {
|
|
step = 60
|
|
}
|
|
tol := req.Options.Tolerance
|
|
if tol == 0 {
|
|
tol = 0.01
|
|
}
|
|
|
|
dir := engine.Forward
|
|
switch req.Direction {
|
|
case "", "forward":
|
|
dir = engine.Forward
|
|
case "reverse":
|
|
dir = engine.Reverse
|
|
default:
|
|
return engine.Profile{}, fmt.Errorf("unknown direction %q", req.Direction)
|
|
}
|
|
|
|
props := make([]*engine.Propagator, len(req.Profile))
|
|
for i, stage := range req.Profile {
|
|
if stage.Name == "" {
|
|
return engine.Profile{}, fmt.Errorf("stage %d: name is required", i)
|
|
}
|
|
built, err := engine.BuildModel(stage.Model, deps)
|
|
if err != nil {
|
|
return engine.Profile{}, fmt.Errorf("stage %q model: %w", stage.Name, err)
|
|
}
|
|
constraints, err := buildConstraintList(stage.Constraints, deps)
|
|
if err != nil {
|
|
return engine.Profile{}, fmt.Errorf("stage %q: %w", stage.Name, err)
|
|
}
|
|
props[i] = &engine.Propagator{
|
|
Name: stage.Name,
|
|
Step: step,
|
|
Model: built.Model,
|
|
BuildModel: built.Build,
|
|
Constraints: constraints,
|
|
Tolerance: tol,
|
|
}
|
|
}
|
|
|
|
for i, stage := range req.Profile {
|
|
if stage.FallbackIndex == nil {
|
|
continue
|
|
}
|
|
idx := *stage.FallbackIndex
|
|
if idx < 0 || idx >= len(props) {
|
|
return engine.Profile{}, fmt.Errorf("stage %q: fallback_index %d out of range", stage.Name, idx)
|
|
}
|
|
props[i].Fallback = props[idx]
|
|
}
|
|
|
|
globals, err := buildConstraintList(req.Globals, deps)
|
|
if err != nil {
|
|
return engine.Profile{}, fmt.Errorf("globals: %w", err)
|
|
}
|
|
|
|
return engine.Profile{Stages: props, Direction: dir, Globals: globals}, nil
|
|
}
|
|
|
|
func buildConstraintList(specs []engine.ConstraintSpec, deps engine.BuildDeps) ([]engine.Constraint, error) {
|
|
out := make([]engine.Constraint, 0, len(specs))
|
|
for i, spec := range specs {
|
|
c, err := engine.BuildConstraint(spec, deps)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("constraint[%d]: %w", i, err)
|
|
}
|
|
out = append(out, c)
|
|
}
|
|
return out, nil
|
|
}
|