run

package
v0.2.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 25, 2026 License: Apache-2.0 Imports: 12 Imported by: 0

Documentation

Overview

Package run executes Pluto packs against a target and rolls the results up into a qual.Scorecard. It is the shared execution core behind both pkg/plutotest (offline, go-test-driven runs) and the CLI (live runs against a real inference client): both re-express their own Spec in terms of this package's Execute and never re-implement the plan -> eval.Run -> scorecard pipeline themselves.

pkg/run never constructs an inference.Client itself ("dependency confinement"): BuildTarget accepts a caller-supplied client and turns a table's environment template plus the run's manifest into a live eval.Target. Offline runs never call BuildTarget at all; they hand Execute a pre-built fixture target directly.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func BuildTarget

func BuildTarget(client inference.Client, m qual.Manifest, env *packfile.Environment, tableRevision eval.Revision) (eval.Target, error)

BuildTarget constructs the live inference target for one table: it expands env into the provider-neutral request template (Environment.Template, pkg/packfile), stamps the manifest's model onto that template, and wraps both in an eval.Target revisioned to tableRevision so Sample.Validate accepts observations against that table's suite (ground rule 2). client is supplied by the caller (the CLI module) — BuildTarget never constructs one itself.

A nil env is legal (a table without an environment yields a zero request template, per Environment.Template). m is validated before use, so an unknown or malformed manifest field — including an unknown capability — is rejected here rather than silently producing an under- or over-permissioned model descriptor.

func DecodeManifest

func DecodeManifest(r io.Reader) (qual.Manifest, error)

DecodeManifest strictly decodes r (via packfile.StrictDecode, so an unknown field is rejected the same way the rest of the packfile YAML corpus rejects one) into a qual.Manifest and validates it before returning. This package never imports gopkg.in/yaml.v3 itself, reusing packfile's strict-decode logic instead; pkg/gen imports yaml.v3 directly for an unrelated concern (encode-side yaml.Node surgery).

func DecodeProfile

func DecodeProfile(r io.Reader) (profile.Profile, error)

DecodeProfile strictly decodes r (via packfile.StrictDecode) into a profile.Profile and validates it before returning.

func ManifestModel

func ManifestModel(m qual.Manifest) model.Model

ManifestModel maps a secret-free qual.Manifest onto the inference module's model.Model descriptor used to build a live target: Provider, Model (as Name), APIFormat, and BaseURL carry across directly, Effort becomes the model's default Sampling.Effort, and each qual.Capability sets the matching model.Capabilities field (Tools, StructuredOutput, Images -> AcceptsImages, Thinking -> Thinking). ManifestModel assumes m is already valid (m.Capabilities holds only known values); BuildTarget validates m first, so an unknown capability is rejected there rather than silently dropped here.

Types

type Result

type Result struct {
	Scorecard qual.Scorecard
	Reports   []eval.Report
	Skipped   []qual.TablePlan
}

Result binds the rolled-up scorecard to its per-table eval reports and the skipped-table plans (visible coverage, never silent).

func Execute

func Execute(ctx context.Context, s Spec) (Result, error)

Execute plans every pack in s against s.Manifest and runs each runnable table plan through eval.Run using the plan's own Suite and Evaluators. A non-runnable plan (missing capability) contributes a Skipped TableResult and is retained verbatim in Result.Skipped; it is never executed and never silently dropped. Execute returns an error from Spec validation, from qual.Plan (an ill-formed pack or manifest), from Spec.TargetForTable, or from eval.Run's own preflight check. Only Spec validation failure (before any pack is planned or any target invoked) yields a zero-value Result: once any table has actually been planned or run, a later failure returns the Result accumulated from every pack/table processed successfully so far ALONGSIDE the error, rather than discarding it. This extends the same "visible coverage, never silent" philosophy behind Result.Skipped to the error path — an operator running many tables against a live target should not lose every already-executed (and potentially paid) table's report just because a later table hit a transient error. Callers must check the error to know whether the run as a whole completed; a non-nil error always means something failed, but the accompanying Result may still carry partial, trustworthy coverage worth reporting.

type Spec

type Spec struct {
	Manifest       qual.Manifest
	Packs          []qual.Pack
	Target         eval.Target
	TargetForTable func(qual.TablePlan) (eval.Target, error)
	Config         eval.RunConfig // zero value = eval defaults

	// Progress, if non-nil, is called once per table plan in pack/plan order,
	// just before that table is executed or recorded as skipped. It is a UI
	// hook for live per-table feedback during a long live run (a run of many
	// tables against a real model emits nothing else until the final report);
	// offline callers like plutotest leave it nil. It must not mutate the plan.
	Progress func(qual.TablePlan)

	// OnResult, if non-nil, is called once per RUNNABLE table immediately after
	// it executes, with that table's eval.Report — the companion to Progress
	// for a live UI that shows each table's pass/fail outcome as it completes.
	// It never fires for a skipped table (those have no report) and must not
	// mutate the report. Under table concurrency it is called from a worker
	// goroutine, possibly for several tables at once, so an implementation must
	// be safe for concurrent use.
	OnResult func(qual.TablePlan, eval.Report)

	// TableConcurrency is how many tables execute in parallel. 0 or 1 runs them
	// sequentially (the default, preserving strict pack/table order and
	// stop-at-first-error). A value >1 runs up to that many tables at once
	// through a worker pool — the throughput win for a corpus of many
	// single-scenario tables, where eval's own per-sample Config.Concurrency
	// cannot help. Per-provider request load is bounded independently by the
	// caller's rate-limited client (pluto's --max-concurrent-requests/--max-rpm).
	TableConcurrency int
}

Spec is one qualification execution. Target may be any eval.Target (scripted fixture or live inference target); pkg/run never constructs clients (design: "Dependency confinement").

Exactly one of Target and TargetForTable must be set. Target is used as-is for every table (the offline case: one fixture target answers every scenario in every pack). TargetForTable builds one target per table plan (the live case: the CLI constructs a fresh live target per table from that table's own environment via BuildTarget). Setting both, or neither, is a configuration error rejected by Execute before any pack is planned or any target is invoked.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL