Skip to content

Release v0.10.0

Release Date: 2026-08-09

Highlights

  • Eino orchestrator rewritten around the org's Loop Engineering REAL/VEAL patterns: a bounded REAL discovery loop composed with a bounded VEAL verification loop, replacing the old linear graph and its unimplemented "Retry Research" step
  • Statistic/CandidateStatistic now carry Precision (exact/approximate/estimated/range) and AsOfDate, sourced from the LLM and propagated all the way into claims.StatisticalDetail
  • Known stats-aggregator domains (e.g. getpanto.ai) are rejected during verification instead of only being scored as low-reliability
  • Fixed a previously-silent bug where the discovery step was decoding into an unused candidates field while the research worker actually returns search_results — likely zero discovery results in production until now
  • Dependency bump to structured-evaluation v0.12.0, the real published release (no local replace directive)

New Features

REAL and VEAL Loops in the Eino Orchestrator

The orchestrator's linear graph (Research → Synthesis → Verification → QualityCheck → "Retry Research") is replaced by two composed, bounded loops:

  • REAL loop (discovery, up to 5 rounds) — reads the shortfall against MinVerifiedStats, runs one discovery round through a small Eino graph (Research → Synthesis), hands the batch to VEAL, and loops until the mission is met or attempts exhaust.
  • VEAL loop (verification, up to 3 attempts per batch) — validates each candidate, including a local aggregator-source check via models.IsKnownAggregatorURL, independent of whether the excerpt verifies. For fixable rejections, an actor attempts a targeted correction (a primary-source replacement search for aggregator-sourced claims, a re-validation pass for transient fetch failures) rather than a blind retry. Domains VEAL rejects are excluded from REAL's next round.

See REAL and VEAL Loops for the full design.

Precision and As-Of-Date on Statistics

type Statistic struct {
    Value     float32
    Unit      string
    Precision claims.Precision // exact/approximate/estimated/range
    AsOfDate  *time.Time       // when the fact was true, distinct from DateFound
    // ...
}

Both the direct LLM search prompt and the synthesis worker's extraction prompt now request precision and as_of_date per statistic, explicitly instructing the LLM never to guess an as_of_date when the source doesn't state one. Values are parsed via models.ParseAsOfDate, which treats a malformed (non-empty) date as an error rather than silently keeping a bad one. Both fields round-trip into claims.StatisticalDetail via claim.SetStatistical(...), so they survive ToClaimsReport conversion instead of only existing inside the formatted claim text.

Aggregator Source Detection

classifySourceType now checks the candidate's source URL against a knownAggregatorDomains list (starting with getpanto.ai) before falling back to the name-based authoritative-source whitelist, classifying matches as claims.ExternalAggregator (defaults to claims.ReliabilityLow). Exported as models.IsKnownAggregatorURL so the VEAL loop can reject an aggregator-sourced candidate outright rather than merely down-scoring it.

Fixed

ResearchResponse Field Mismatch

models.ResearchResponse was decoding into an unused candidates field while the research worker actually returns search_results. Fixed to match the worker's real contract (SearchResults, not Candidates), and the lossy CandidateSearchResult round-trip conversion that existed to paper over the mismatch is gone. The discovery step had likely been returning zero results in production until this fix landed.

Dependencies

Updated

  • github.com/plexusone/structured-evaluation v0.9.0 → v0.12.0 (picks up claims.ExternalAggregator and claims.StatisticalDetail)
  • github.com/plexusone/omniskill v0.10.0 → v0.12.0
  • github.com/plexusone/omniobserve v0.11.0 → v0.12.0
  • github.com/plexusone/agentkit v0.6.1 → v0.7.0
  • github.com/cloudwego/eino v0.9.12 → v0.9.13
  • github.com/modelcontextprotocol/go-sdk v1.6.1 → v1.7.0
  • github.com/grokify/mogo v0.74.6 → v0.74.7
  • google.golang.org/adk v1.5.0 → v1.5.1
  • google.golang.org/genai v1.63.0 → v1.67.0

Infrastructure

  • GitHub Actions: actions/setup-go v6 → v7
  • GitHub Actions: actions/setup-python v6 → v7
  • GitHub Actions: docker/login-action v4 → v4.6.0

Notes

  • Added a temporary exclude go.opentelemetry.io/otel/log v0.21.0 in go.mod: google.golang.org/adk v1.5.1's internal telemetry package doesn't yet compile against that otel/log release. Remove once adk ships a compatible version.

Documentation

  • New REAL and VEAL Loops page documenting the design
  • Fixed Eino Orchestration's workflow diagram and logging example, which predated the Synthesis step
  • Fixed a docs/code mismatch in 4-Agent Architecture's /synthesize API example (candidates field now shows precision/as_of_date; the earlier /research example's "candidates""search_results" mismatch is also fixed)
  • README updated with a compact "REAL/VEAL Loops" summary

Testing

  • New pkg/orchestration/eino_test.go covering rejection classification, domain-exclusion matching, the VEAL actor's per-reason behavior (including a bug the tests caught directly — unknown rejection reasons were falling through to a blind resubmit despite the doc comment saying they aren't fixable), and discovery-graph compilation