feat(runner): wire llmSource selection and trace stamping

This commit is contained in:
pj committed 2026-06-12 10:33:20 +05:30
1 parent ad6b78c9bf
commit 8164971e0e
2 files changed
+32 -5

No files matched your search

+5 -1
View File
@@ -74,7 +74,10 @@ func Run(ctx context.Context, options Options) (Summary, error) {
// Pick the action and extractor sources once from the driver's // Pick the action and extractor sources once from the driver's
// capabilities so the step loop runs one uniform path with no per-step // capabilities so the step loop runs one uniform path with no per-step
// driver type assertion. // driver type assertion.
actionSource, extractorSource := pickSources(options) actionSource, extractorSource, err := pickSources(options)
if err != nil {
return Summary{}, err
}
summary := Summary{StartTime: time.Now()} summary := Summary{StartTime: time.Now()}
deadline := summary.StartTime.Add(options.Duration) deadline := summary.StartTime.Add(options.Duration)
@@ -217,6 +220,7 @@ func Run(ctx context.Context, options Options) (Summary, error) {
var traceAction *trace.Action var traceAction *trace.Action
if nextErr == nil { if nextErr == nil {
traceAction = traceActionFor(nextAction, tree) traceAction = traceActionFor(nextAction, tree)
stampActionSource(traceAction, actionSource)
} else if !errors.Is(nextErr, verifier.ErrNoAction) { } else if !errors.Is(nextErr, verifier.ErrNoAction) {
return summary, fmt.Errorf("step %d next action: %w", stepIndex, nextErr) return summary, fmt.Errorf("step %d next action: %w", stepIndex, nextErr)
} }
+27 -4
View File
@@ -4,8 +4,10 @@ import (
"context" "context"
"encoding/json" "encoding/json"
"fmt" "fmt"
"log/slog"
"github.com/priyanshujain/sanderling/internal/driver" "github.com/priyanshujain/sanderling/internal/driver"
"github.com/priyanshujain/sanderling/internal/openrouter"
"github.com/priyanshujain/sanderling/internal/verifier" "github.com/priyanshujain/sanderling/internal/verifier"
) )
@@ -61,12 +63,33 @@ func (s webSource) ExtractorOverrides(ctx context.Context) (map[int]json.RawMess
} }
// pickSources selects the runtime's action and extractor sources ONCE at setup // pickSources selects the runtime's action and extractor sources ONCE at setup
// from the driver's capabilities, so the step loop never type-asserts. // from the driver's capabilities and the spec, so the step loop never
func pickSources(options Options) (ActionSource, ExtractorSource) { // type-asserts. When the spec selected the LLM action backend (actions =
// llm({...})) it constructs the OpenRouter client and returns an llmSource for
// selection while extractor overrides still come from the goja path.
func pickSources(options Options) (ActionSource, ExtractorSource, error) {
if web, ok := options.Driver.(driver.WebDriver); ok { if web, ok := options.Driver.(driver.WebDriver); ok {
source := webSource{web: web} source := webSource{web: web}
return source, source return source, source, nil
}
if config, ok := options.Verifier.LLMConfig(); ok {
client, err := openrouter.New()
if err != nil {
return nil, nil, fmt.Errorf("llm action backend: %w", err)
}
logger := options.Logger
if logger == nil {
logger = slog.Default()
}
action := &llmSource{
verifier: options.Verifier,
client: client,
model: config.Model,
logger: logger,
history: newActionHistory(llmHistorySize),
}
return action, gojaSource{verifier: options.Verifier}, nil
} }
source := gojaSource{verifier: options.Verifier} source := gojaSource{verifier: options.Verifier}
return source, source return source, source, nil
} }