fizeau

package module
v0.9.26 Latest Latest
Warning

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

Go to latest
Published: May 1, 2026 License: MIT Imports: 44 Imported by: 0

README

Fizeau

Embeddable Go agent runtime - local-model-first via LM Studio.

CI Release

Fizeau is a Go library that implements a coding agent runtime - a tool-calling LLM loop with file read/write, shell execution, navigation helpers, and structured I/O. Designed to be embedded in DDx and other build orchestrators. Prioritizes local model inference via LM Studio and Ollama, with transparent escalation to cloud providers.

Install

curl -fsSL https://raw.githubusercontent.com/DocumentDrivenDX/fizeau/master/install.sh | bash

Or with Go:

go install github.com/DocumentDrivenDX/fizeau/cmd/fiz@latest

Quick Start

Start LM Studio with a model that supports tool calling (Qwen 3.5+, Llama 3.2+), then:

fiz -p "Read main.go and tell me the package name"

Fizeau connects to localhost:1234 by default.

With Anthropic
export FIZEAU_PROVIDER=anthropic
export FIZEAU_API_KEY=sk-ant-...
export FIZEAU_MODEL=claude-sonnet-4-20250514
fiz -p "Read main.go and tell me the package name"

Demos

Read a file and explain it

asciicast

$ fiz -p 'Read main.go and explain what this program does'

This program is a simple HTTP server that listens on port 8080 and responds
with "Hello from Fizeau!" to any request.
[success] tokens: 1861 in / 70 out
Edit a config file
$ fiz -p 'Read config.yaml, change the server port from 8080 to 9090, then verify'

Done. The server port in config.yaml has been changed from 8080 to 9090.
[success] tokens: 4082 in / 127 out
Explore project structure
$ fiz -p 'List all Go files and summarize the package structure'

Package Structure:
├── cmd/server/main.go       (package main)
├── internal/api/handler.go  (package api)
├── internal/api/middleware.go (package api)
└── internal/db/postgres.go  (package db)

A typical Go project with cmd/ for entry points, internal/ for private packages.
[success] tokens: 6388 in / 297 out

As a Library

import (
    "context"
    "fmt"

    "github.com/DocumentDrivenDX/fizeau"
    _ "github.com/DocumentDrivenDX/fizeau/configinit"
)

func main() {
    svc, err := fizeau.New(fizeau.ServiceOptions{})
    if err != nil {
        panic(err)
    }
    events, err := svc.Execute(context.Background(), fizeau.ServiceExecuteRequest{
        Prompt:   "Read main.go and tell me the package name",
        ModelRef: "cheap",
        WorkDir:  ".",
    })
    if err != nil {
        panic(err)
    }
    for event := range events {
        fmt.Println(event.Type)
    }
}

Features

  • Embeddable libraryfizeau.New(...).Execute(ctx, request), no subprocess overhead
  • Local-model-first — LM Studio, Ollama via OpenAI-compatible API
  • Multi-provider — OpenAI-compatible, Anthropic Claude, virtual (test replay)
  • 9 built-in tools — read, write, edit, bash, find, grep, ls, patch, task
  • Session logging — JSONL with replay and cost tracking
  • System prompt composition — pi-style builder with context file discovery
  • Standalone CLIfiz -p "prompt" with config, logging, replay

Configuration

# .fizeau/config.yaml
providers:
  local:
    type: lmstudio
    base_url: http://localhost:1234/v1
    model: qwen3.5-7b
default: local
preset: default                  # system prompt style (see below)
max_iterations: 20
session_log_dir: .fizeau/sessions
tools:
  bash:
    output_filter:
      mode: off                  # off | rtk | auto
      rtk_binary: rtk
      max_bytes: 51200

Environment overrides: FIZEAU_PROVIDER, FIZEAU_BASE_URL, FIZEAU_API_KEY, FIZEAU_MODEL

tools.bash.output_filter.mode: rtk proxies allowlisted noisy commands such as git status and go test through an installed rtk binary. If rtk is not available, bash runs the original command and includes a fallback marker. Built-in read, find, grep, and ls are not filtered.

System Prompt Presets

Fizeau ships built-in system prompt presets that describe prompt intent. Select one with --preset or the top-level preset config field:

Preset Description
default Balanced, tool-aware prompt
smart Rich, thorough prompt for quality-sensitive runs
cheap Pragmatic, direct prompt for latency/cost-sensitive runs
minimal Bare minimum — one sentence
benchmark Non-interactive prompt optimized for evaluation

When no preset is specified, default is used.

Session Replay

Every run is logged. Replay past sessions:

fiz log                  # list sessions
fiz replay <session-id>  # human-readable replay

Documentation

Contributing

See CONTRIBUTING.md.

License

MIT

Documentation

Index

Examples

Constants

View Source
const (
	ReasoningAuto    = reasoning.ReasoningAuto
	ReasoningOff     = reasoning.ReasoningOff
	ReasoningLow     = reasoning.ReasoningLow
	ReasoningMedium  = reasoning.ReasoningMedium
	ReasoningHigh    = reasoning.ReasoningHigh
	ReasoningMinimal = reasoning.ReasoningMinimal
	ReasoningXHigh   = reasoning.ReasoningXHigh
	ReasoningMax     = reasoning.ReasoningMax
)
View Source
const (
	EventSessionStart = agentcore.EventSessionStart
	EventSessionEnd   = agentcore.EventSessionEnd
	StatusSuccess     = agentcore.StatusSuccess
)
View Source
const (
	CachePolicyDefault = "default"
	CachePolicyOff     = "off"
)

Valid CachePolicy values.

View Source
const (
	FilterReasonUnhealthy            = "unhealthy"
	FilterReasonContextTooSmall      = "context_too_small"
	FilterReasonNoToolSupport        = "no_tool_support"
	FilterReasonReasoningUnsupported = "reasoning_unsupported"
	FilterReasonScoredBelowTop       = "scored_below_top"
)

FilterReason* enumerate the canonical disqualification reasons surfaced in RouteCandidate.FilterReason and the routing-decision event.

View Source
const (
	ServiceEventTypeTextDelta        = "text_delta"
	ServiceEventTypeToolCall         = "tool_call"
	ServiceEventTypeToolResult       = "tool_result"
	ServiceEventTypeCompaction       = "compaction"
	ServiceEventTypeRoutingDecision  = "routing_decision"
	ServiceEventTypeStall            = "stall"
	ServiceEventTypeFinal            = "final"
	ServiceEventTypeOverride         = "override"
	ServiceEventTypeRejectedOverride = "rejected_override"
)
View Source
const RouteStatusRoutingQualityWindow = 100

RouteStatusRoutingQualityWindow caps how many recent Execute calls contribute to RouteStatusReport.RoutingQuality. ADR-006 §5 calls for a "recent window"; the constant is exported so operator UIs can label the metric appropriately.

Variables

This section is empty.

Functions

func DiscoverModels

func DiscoverModels(ctx context.Context, baseURL, apiKey string) ([]string, error)

func ErrDiscoveryUnsupported

func ErrDiscoveryUnsupported() error

ErrDiscoveryUnsupported returns the sentinel. Callers compare via errors.Is(err, ErrDiscoveryUnsupported()).

func NormalizeModelID

func NormalizeModelID(requested string, catalog []string) (string, error)

func RegisterConfigLoader

func RegisterConfigLoader(fn func(dir string) (ServiceConfig, error))

RegisterConfigLoader is called by the config package's init() to install the config-loading function. Do not call this from application code.

func ValidateCachePolicy

func ValidateCachePolicy(v string) error

ValidateCachePolicy returns nil when v is one of the accepted CachePolicy values ("", "default", "off") and a typed error otherwise. The empty string is treated as "default".

func ValidatePowerBounds

func ValidatePowerBounds(minPower, maxPower int) error

ValidatePowerBounds returns nil when the optional numeric routing power bounds are unset or coherent. Zero means "unset"; positive values are on the catalog's 1-10 power scale.

func ValidateUsageSince

func ValidateUsageSince(spec string) error

ValidateUsageSince returns nil when spec is a usage window value accepted by UsageReport. CLI subcommands call this to surface exit-code-2 validation errors before invoking the service.

Types

type AccountStatus

type AccountStatus struct {
	Authenticated   bool
	Unauthenticated bool
	Email           string
	PlanType        string
	OrgName         string
	Source          string
	CapturedAt      time.Time
	Fresh           bool
	Detail          string
}

AccountStatus describes authentication/account state without exposing provider-specific native files to consumers.

type BashOutputFilterConfig

type BashOutputFilterConfig = tool.BashOutputFilterConfig

type CatalogProbeFunc

type CatalogProbeFunc func(ctx context.Context) (ids []string, err error)

CatalogProbeFunc performs a single /v1/models discovery request against a specific endpoint. Implementations should return:

  • a ReachabilityError (see internal/provider/openai) when the endpoint is unreachable or returns 5xx.
  • a sentinel-wrapped error (errDiscoveryUnsupported) when /v1/models returns 404 — the endpoint exists but doesn't expose discovery.
  • a plain error otherwise (auth failures etc. — cache records but does not treat as unreachable).

The ids slice should preserve server-returned order.

type CatalogResult

type CatalogResult struct {
	IDs                []string  // server-order model IDs; empty when discovery unsupported or never fetched successfully
	FetchedAt          time.Time // zero when no successful fetch has occurred
	DiscoverySupported bool      // false when /v1/models returned 404; callers passthrough
	LastErr            error     // last probe's error if any; may be a ReachabilityError
	FromCache          bool      // true when served from cache (fresh or stale)
	Stale              bool      // true when served from a stale cache entry (async refresh kicked)
}

CatalogResult is what callers receive from Get. All fields are copies — mutating them does not affect cache state.

type CompactionConfig

type CompactionConfig = compaction.Config

func DefaultCompactionConfig

func DefaultCompactionConfig() CompactionConfig

type CooldownState

type CooldownState struct {
	Reason      string    // "consecutive_failures" | "route_attempt_failure" | "manual" | etc.
	Until       time.Time // when the cooldown expires
	FailCount   int       // number of consecutive failures that triggered the cooldown
	LastError   string    // last recorded error message, if available
	LastAttempt time.Time // when the feedback was recorded
}

CooldownState describes an active routing cooldown for a provider.

type CostInfo

type CostInfo struct {
	InputPerMTok  float64 // USD per 1M input tokens; 0 = unknown/free
	OutputPerMTok float64 // USD per 1M output tokens; 0 = unknown/free
}

CostInfo holds per-token cost metadata for a model.

type DecisionWithCandidates

type DecisionWithCandidates interface {
	error
	// RouteCandidates returns the evaluated candidates that led to the error.
	RouteCandidates() []RouteCandidate
}

DecisionWithCandidates is implemented by routing errors that retain the evaluated candidate trace for a failed ResolveRoute call.

type DrainExecuteResult

type DrainExecuteResult struct {
	Events           []ServiceDecodedEvent
	TextDeltas       []ServiceTextDeltaData
	ToolCalls        []ServiceToolCallData
	ToolResults      []ServiceToolResultData
	Compactions      []ServiceCompactionData
	Stalls           []ServiceStallData
	RoutingDecision  *ServiceRoutingDecisionData
	Override         *ServiceOverrideData
	RejectedOverride *ServiceOverrideData
	Final            *ServiceFinalData

	FinalStatus    string
	FinalText      string
	Usage          *ServiceFinalUsage
	Warnings       []ServiceFinalWarning
	CostUSD        float64
	SessionLogPath string
	RoutingActual  *ServiceRoutingActual
	TerminalError  string
}

DrainExecuteResult is a typed aggregate of one Execute event stream.

func DrainExecute

func DrainExecute(ctx context.Context, events <-chan ServiceEvent) (*DrainExecuteResult, error)

type EndpointStatus

type EndpointStatus struct {
	Name          string
	BaseURL       string
	ProbeURL      string
	Status        string // connected|unreachable|unauthenticated|error|unknown
	Source        string
	CapturedAt    time.Time
	Fresh         bool
	LastSuccessAt time.Time
	ModelCount    int
	LastError     *StatusError
}

EndpointStatus describes one configured provider endpoint probe.

type ErrHarnessModelIncompatible

type ErrHarnessModelIncompatible struct {
	// Harness is the canonical harness name supplied by the caller.
	Harness string
	// Model is the exact concrete model pin supplied by the caller.
	Model string
	// SupportedModels is the harness allow-list that rejected Model.
	SupportedModels []string
}

ErrHarnessModelIncompatible reports an explicit Harness+Model pin that the harness allow-list cannot serve.

DDx preflight callers should use errors.As to extract Harness, Model, and SupportedModels for worker logs or bead failure records. errors.Is matches a zero-value ErrHarnessModelIncompatible, even after callers wrap the error with fmt.Errorf and %w.

Example
package main

import (
	"errors"
	"fmt"
	"strings"

	fizeau "github.com/DocumentDrivenDX/fizeau"
)

func main() {
	err := fmt.Errorf("ddx preflight: %w", &fizeau.ErrHarnessModelIncompatible{
		Harness:         "gemini",
		Model:           "minimax/minimax-m2.7",
		SupportedModels: []string{"gemini-2.5-pro", "gemini-2.5-flash"},
	})

	var routeErr *fizeau.ErrHarnessModelIncompatible
	if errors.As(err, &routeErr) {
		fmt.Printf("ddx failed bead: harness=%s model=%s supported=%s\n",
			routeErr.Harness,
			routeErr.Model,
			strings.Join(routeErr.SupportedModels, ","))
	}
	fmt.Println(errors.Is(err, fizeau.ErrHarnessModelIncompatible{}))

}
Output:
ddx failed bead: harness=gemini model=minimax/minimax-m2.7 supported=gemini-2.5-pro,gemini-2.5-flash
true

func (ErrHarnessModelIncompatible) Error

func (ErrHarnessModelIncompatible) Is

func (e ErrHarnessModelIncompatible) Is(target error) bool

func (ErrHarnessModelIncompatible) Unwrap

type ErrNoLiveProvider

type ErrNoLiveProvider struct {
	PromptTokens  int
	RequiresTools bool
	StartingTier  string
}

ErrNoLiveProvider reports that profile-tier escalation walked the entire cheap → standard → smart ladder without finding a live provider that could serve the request. The message names the prompt size and tool requirement so operators know what capability is missing across all tiers, rather than the engine's "no viable routing candidate" jargon.

func (ErrNoLiveProvider) Error

func (e ErrNoLiveProvider) Error() string

func (ErrNoLiveProvider) Is

func (e ErrNoLiveProvider) Is(target error) bool

func (ErrNoLiveProvider) Unwrap

func (e ErrNoLiveProvider) Unwrap() error

type ErrNoProfileCandidate

type ErrNoProfileCandidate struct {
	Profile           string
	MissingCapability string
	Rejected          int
}

ErrNoProfileCandidate reports that a profile's hard placement requirement could not be satisfied by any routed candidate.

func (ErrNoProfileCandidate) Error

func (e ErrNoProfileCandidate) Error() string

func (ErrNoProfileCandidate) Is

func (e ErrNoProfileCandidate) Is(target error) bool

func (ErrNoProfileCandidate) Unwrap

func (e ErrNoProfileCandidate) Unwrap() error

type ErrProfilePinConflict

type ErrProfilePinConflict struct {
	// Profile is the explicit profile requested by the caller.
	Profile string
	// ConflictingPin names the explicit pin that violates the profile, such as
	// "Harness=claude" or "Model=local-model".
	ConflictingPin string
	// ProfileConstraint is a short description of the profile placement rule,
	// such as "local-only" or "subscription-only".
	ProfileConstraint string
}

ErrProfilePinConflict reports an explicit Profile whose placement constraint contradicts another explicit caller pin.

DDx preflight callers should use errors.As to extract Profile, ConflictingPin, and ProfileConstraint for worker logs or bead failure records. errors.Is matches a zero-value ErrProfilePinConflict, even after callers wrap the error with fmt.Errorf and %w.

Example
package main

import (
	"errors"
	"fmt"

	fizeau "github.com/DocumentDrivenDX/fizeau"
)

func main() {
	err := fmt.Errorf("ddx preflight: %w", &fizeau.ErrProfilePinConflict{
		Profile:           "local",
		ConflictingPin:    "Harness=claude",
		ProfileConstraint: "local-only",
	})

	var routeErr *fizeau.ErrProfilePinConflict
	if errors.As(err, &routeErr) {
		fmt.Printf("ddx failed bead: profile=%s conflict=%s constraint=%s\n",
			routeErr.Profile,
			routeErr.ConflictingPin,
			routeErr.ProfileConstraint)
	}
	fmt.Println(errors.Is(err, fizeau.ErrProfilePinConflict{}))

}
Output:
ddx failed bead: profile=local conflict=Harness=claude constraint=local-only
true

func (ErrProfilePinConflict) Error

func (e ErrProfilePinConflict) Error() string

func (ErrProfilePinConflict) Is

func (e ErrProfilePinConflict) Is(target error) bool

func (ErrProfilePinConflict) Unwrap

func (e ErrProfilePinConflict) Unwrap() error

type ErrRejectedOverride

type ErrRejectedOverride struct {
	// Inner is the underlying pin error (e.g., *ErrHarnessModelIncompatible).
	Inner error
	// Event is the rejected_override payload (no outcome).
	Event ServiceOverrideData
}

ErrRejectedOverride wraps a pin-rejection error and carries the rejected_override event payload that was generated for the failed pin. Callers can extract the payload via errors.As to surface override-quality telemetry even when Execute returns a typed pin error rather than a channel.

func (*ErrRejectedOverride) Error

func (e *ErrRejectedOverride) Error() string

func (*ErrRejectedOverride) Unwrap

func (e *ErrRejectedOverride) Unwrap() error

type ErrUnknownProfile

type ErrUnknownProfile struct {
	Profile string
}

ErrUnknownProfile reports an explicit profile name that is not present in the model catalog.

func (ErrUnknownProfile) Error

func (e ErrUnknownProfile) Error() string

func (ErrUnknownProfile) Is

func (e ErrUnknownProfile) Is(target error) bool

func (ErrUnknownProfile) Unwrap

func (e ErrUnknownProfile) Unwrap() error

type ErrUnknownProvider

type ErrUnknownProvider struct {
	// Provider is the provider name supplied by the caller.
	Provider string
	// KnownProviders is the set of provider names the service knows about
	// (empty when no ServiceConfig is configured).
	KnownProviders []string
}

ErrUnknownProvider reports an explicit Provider pin that is not present in the service configuration. This is a pre-dispatch pin failure: the caller asked for a provider name that the service has no record of, so no route can be constructed.

func (ErrUnknownProvider) Error

func (e ErrUnknownProvider) Error() string

func (ErrUnknownProvider) Is

func (e ErrUnknownProvider) Is(target error) bool

func (ErrUnknownProvider) Unwrap

func (e ErrUnknownProvider) Unwrap() error

type FizeauService

type FizeauService interface {
	Execute(ctx context.Context, req ServiceExecuteRequest) (<-chan ServiceEvent, error)
	TailSessionLog(ctx context.Context, sessionID string) (<-chan ServiceEvent, error)
	ListHarnesses(ctx context.Context) ([]HarnessInfo, error)
	ListProviders(ctx context.Context) ([]ProviderInfo, error)
	ListModels(ctx context.Context, filter ModelFilter) ([]ModelInfo, error)
	ListProfiles(ctx context.Context) ([]ProfileInfo, error)
	ResolveProfile(ctx context.Context, name string) (*ResolvedProfile, error)
	ProfileAliases(ctx context.Context) (map[string]string, error)
	HealthCheck(ctx context.Context, target HealthTarget) error
	ResolveRoute(ctx context.Context, req RouteRequest) (*RouteDecision, error)
	RecordRouteAttempt(ctx context.Context, attempt RouteAttempt) error
	RouteStatus(ctx context.Context) (*RouteStatusReport, error)

	// Historical session-log projections. CONTRACT-003 owns these so CLI
	// subcommands such as log/replay/usage do not need to read the
	// internal session-log JSONL schema.
	UsageReport(ctx context.Context, opts UsageReportOptions) (*UsageReport, error)
	ListSessionLogs(ctx context.Context) ([]SessionLogEntry, error)
	WriteSessionLog(ctx context.Context, sessionID string, w io.Writer) error
	ReplaySession(ctx context.Context, sessionID string, w io.Writer) error
}

FizeauService is the entire public Go surface of the fizeau module. See CONTRACT-003 for the full specification.

func New

func New(opts ServiceOptions) (FizeauService, error)

New constructs a FizeauService. When opts.ServiceConfig is nil, New attempts to load configuration automatically:

  1. If opts.ConfigPath is non-empty, load from filepath.Dir(opts.ConfigPath).
  2. Otherwise, load from the default global config location.

Automatic loading requires the config package to be imported somewhere in the binary (it registers the loader via init). If the config package is not imported and ServiceConfig is nil, the service starts without provider config (ListProviders/HealthCheck will return errors until config is injected).

type HarnessCapability

type HarnessCapability struct {
	Status HarnessCapabilityStatus
	Detail string
}

HarnessCapability describes one capability row for one harness.

type HarnessCapabilityMatrix

type HarnessCapabilityMatrix struct {
	ExecutePrompt   HarnessCapability
	ModelDiscovery  HarnessCapability
	ModelPinning    HarnessCapability
	WorkdirContext  HarnessCapability
	ReasoningLevels HarnessCapability
	PermissionModes HarnessCapability
	ProgressEvents  HarnessCapability
	UsageCapture    HarnessCapability
	FinalText       HarnessCapability
	ToolEvents      HarnessCapability
	QuotaStatus     HarnessCapability
	RecordReplay    HarnessCapability
}

HarnessCapabilityMatrix is the public, per-harness capability table exposed by ListHarnesses. The fields intentionally match CONTRACT-003's required capability categories.

type HarnessCapabilityStatus

type HarnessCapabilityStatus string

HarnessCapabilityStatus classifies one harness capability in the public ListHarnesses capability matrix.

const (
	HarnessCapabilityRequired      HarnessCapabilityStatus = "required"
	HarnessCapabilityOptional      HarnessCapabilityStatus = "optional"
	HarnessCapabilityUnsupported   HarnessCapabilityStatus = "unsupported"
	HarnessCapabilityNotApplicable HarnessCapabilityStatus = "not_applicable"
)

type HarnessInfo

type HarnessInfo struct {
	Name                 string
	Type                 string // "native" | "subprocess"
	Available            bool
	Path                 string
	Error                string
	IsLocal              bool
	IsSubscription       bool
	AutoRoutingEligible  bool
	TestOnly             bool
	ExactPinSupport      bool
	DefaultModel         string   // built-in default model when no override is supplied
	SupportedPermissions []string // subset of {"safe","supervised","unrestricted"}
	SupportedReasoning   []string // values such as {"low","medium","high","xhigh","max"}
	CostClass            string   // "local" | "cheap" | "medium" | "expensive"
	Quota                *QuotaState
	Account              *AccountStatus
	UsageWindows         []UsageWindow
	LastError            *StatusError
	CapabilityMatrix     HarnessCapabilityMatrix
}

HarnessInfo describes a registered harness as defined in CONTRACT-003.

type HealthTarget

type HealthTarget struct {
	Type string // "harness" | "provider"
	Name string
}

HealthTarget identifies what to health-check.

type ModelFilter

type ModelFilter struct {
	Harness  string
	Provider string
}

ModelFilter filters ListModels results.

type ModelInfo

type ModelInfo struct {
	ID              string
	Provider        string
	ProviderType    string
	Harness         string
	EndpointName    string
	EndpointBaseURL string
	ContextLength   int
	Capabilities    []string
	Cost            CostInfo
	PerfSignal      PerfSignal
	Power           int
	AutoRoutable    bool
	ExactPinOnly    bool
	Available       bool
	IsConfigured    bool   // matches an explicit model_routes entry
	IsDefault       bool   // matches the configured default model
	CatalogRef      string // canonical catalog reference if recognized
	RankPosition    int    // ordinal in latest discovery rank; -1 if unranked
}

ModelInfo describes a model with full metadata per CONTRACT-003.

type OverrideClassBucket

type OverrideClassBucket struct {
	PromptFeatureBucket string `json:"prompt_feature_bucket"`
	Axis                string `json:"axis"`
	Match               bool   `json:"match"`
	Count               int    `json:"count"`

	SuccessOutcomes   int `json:"success_outcomes"`
	StalledOutcomes   int `json:"stalled_outcomes"`
	FailedOutcomes    int `json:"failed_outcomes"`
	CancelledOutcomes int `json:"cancelled_outcomes"`
	UnknownOutcomes   int `json:"unknown_outcomes"`
}

OverrideClassBucket is one cell in the override-class pivot.

Each override event contributes one bucket per overridden axis: an override that pins both Harness and Model produces two breakdown rows for that event, with axis="harness" and axis="model" respectively. The PromptFeatureBucket coalesces estimated_tokens / requires_tools / reasoning into a coarse string so operators can read the pivot without drowning in cardinality.

type PerfSignal

type PerfSignal struct {
	SpeedTokensPerSec float64 // 0 = unknown
	SWEBenchVerified  float64 // 0 = unknown
}

PerfSignal holds observed performance data for a model.

type ProfileInfo

type ProfileInfo struct {
	Name               string
	Target             string
	AliasOf            string
	ProviderPreference string
	Deprecated         bool
	Replacement        string
	CatalogVersion     string
	ManifestSource     string
	ManifestVersion    int
}

type ProfileSurface

type ProfileSurface struct {
	Name                    string
	Harness                 string
	ProviderSystem          string
	Model                   string
	Candidates              []string
	PlacementOrder          []string
	CostCeilingInputPerMTok *float64
	ReasoningDefault        Reasoning
	FailurePolicy           string
}

type ProviderInfo

type ProviderInfo struct {
	Name           string
	Type           string // "openai" | "openrouter" | "lmstudio" | "omlx" | "ollama" | "anthropic" | "virtual"
	BaseURL        string
	Endpoints      []ServiceProviderEndpoint
	Status         string // "connected" | "unreachable" | "error: <msg>"
	ModelCount     int
	Capabilities   []string       // e.g. {"tool_use","streaming","json_mode"}
	IsDefault      bool           // matches the configured default_provider
	DefaultModel   string         // per-provider configured default model, if any
	CooldownState  *CooldownState // nil if not in cooldown
	Auth           AccountStatus
	EndpointStatus []EndpointStatus
	Quota          *QuotaState
	UsageWindows   []UsageWindow
	LastError      *StatusError
}

ProviderInfo describes a provider with live status per CONTRACT-003.

type QuotaState

type QuotaState struct {
	Windows    []harnesses.QuotaWindow `json:"windows"`
	CapturedAt time.Time               `json:"captured_at"`
	Fresh      bool                    `json:"fresh"`
	Source     string                  `json:"source,omitempty"`
	Status     string                  `json:"status,omitempty"` // ok|stale|unavailable|unauthenticated|unknown
	LastError  *StatusError            `json:"last_error,omitempty"`
}

QuotaState is a live quota snapshot for a harness. Nil means not applicable.

type Reasoning

type Reasoning = reasoning.Reasoning

func ReasoningTokens

func ReasoningTokens(n int) Reasoning

type ResolvedProfile

type ResolvedProfile struct {
	Name            string
	Target          string
	Deprecated      bool
	Replacement     string
	CatalogVersion  string
	ManifestSource  string
	ManifestVersion int
	Surfaces        []ProfileSurface
}

type RouteAttempt

type RouteAttempt struct {
	Harness   string
	Provider  string
	Model     string
	Endpoint  string
	Status    string
	Reason    string
	Error     string
	Duration  time.Duration
	Timestamp time.Time // zero = time.Now()
}

RouteAttempt is caller feedback about one attempted route candidate. Status="success" clears matching active failures; any other non-empty status records a same-process failure until the service health cooldown expires.

type RouteCandidate

type RouteCandidate struct {
	// Harness is the candidate harness name.
	Harness string
	// Provider is the candidate provider name for native agent routes.
	Provider string
	// Endpoint is the provider endpoint name when applicable.
	Endpoint string
	// Model is the candidate concrete model.
	Model string
	// Score is the routing score assigned before final ordering.
	Score float64
	// CostUSDPer1kTokens is the estimated blended USD cost per 1,000 tokens.
	CostUSDPer1kTokens float64
	// CostSource indicates whether cost came from catalog, subscription,
	// user-config, or is unknown.
	CostSource string
	// Eligible reports whether the candidate passed all routing gates.
	Eligible bool
	// Reason is the scoring reason for eligible candidates or the rejection
	// reason for ineligible candidates.
	Reason string
	// FilterReason names the gate that disqualified an ineligible candidate.
	// Empty when Eligible. See the FilterReason* constants.
	FilterReason string
	// Components carries the per-axis score inputs (power, cost, latency,
	// success rate, quota, capability) that fed the final Score. Consumers use these to
	// explain rankings without parsing the free-form Reason.
	Components RouteCandidateComponents
}

RouteCandidate is one routing candidate evaluated by ResolveRoute.

type RouteCandidateComponents

type RouteCandidateComponents struct {
	// Power is the catalog model power used by automatic routing. Zero means
	// unknown or not contributing.
	Power int
	// Cost is the per-1k-token cost expressed as a numeric component (USD).
	// Mirrors RouteCandidate.CostUSDPer1kTokens; surfaced here so the event
	// payload carries a single component bundle.
	Cost float64
	// CostClass is the candidate cost class used by the router.
	CostClass string
	// LatencyMS is the observed median latency for this candidate, in
	// milliseconds. Zero when no observations are available.
	LatencyMS float64
	// SpeedTPS is the observed output speed in tokens per second. Zero when
	// no observations are available.
	SpeedTPS float64
	// SuccessRate is the observed success rate (0–1) for this candidate.
	// Negative means insufficient data; zero means unknown.
	SuccessRate float64
	// QuotaOK/QuotaPercentUsed/QuotaTrend are subscription quota inputs used
	// by routing. They are zero values for non-subscription candidates.
	QuotaOK          bool
	QuotaPercentUsed int
	QuotaTrend       string
	// Capability is a coarse capability score derived from the candidate's
	// cost class / surface (higher = more capable).
	Capability float64
}

RouteCandidateComponents breaks down the inputs that fed a candidate's final Score so consumers can explain rankings without parsing the free-form Reason. Zero fields mean "unknown / not contributing".

type RouteCandidateStatus

type RouteCandidateStatus struct {
	Provider                string
	Model                   string
	Priority                int
	Healthy                 bool
	Cooldown                *CooldownState
	RecentLatencyMS         float64 // observation-derived; 0 when unavailable
	ProviderReliabilityRate float64 // 0-1; 0 when unavailable. Legacy success-rate field, relabeled per ADR-006 §5 to disambiguate from routing-quality.
}

RouteCandidateStatus describes a single candidate within a route.

ProviderReliabilityRate is the per-(provider, model) observed completion rate (the legacy "success rate" metric). Per ADR-006 §5 it is labeled "provider reliability" to distinguish it from RoutingQualityMetrics on the parent report — the two metrics measure different things and are surfaced as separate fields.

type RouteDecision

type RouteDecision struct {
	// Harness is the selected harness name.
	Harness string
	// Provider is the selected provider for native agent routes.
	Provider string
	// Endpoint is the selected named endpoint when the provider exposes more
	// than one endpoint.
	Endpoint string
	// Model is the selected concrete model.
	Model string
	// Reason summarizes why the selected candidate won.
	Reason string
	// Candidates is the full ranked decision trace, including rejected
	// candidates and their rejection reasons.
	Candidates []RouteCandidate
}

RouteDecision is the result of ResolveRoute.

Example (Candidates)
package main

import (
	"fmt"

	fizeau "github.com/DocumentDrivenDX/fizeau"
)

func main() {
	decision := &fizeau.RouteDecision{
		Candidates: []fizeau.RouteCandidate{
			{Harness: "agent", Provider: "local", Model: "qwen", Eligible: false, Reason: "provider is in cooldown"},
			{Harness: "codex", Model: "gpt-5.4", Eligible: true, Reason: "score=71.2"},
		},
	}

	for _, candidate := range decision.Candidates {
		fmt.Printf("%s/%s eligible=%t reason=%s\n",
			candidate.Harness,
			candidate.Model,
			candidate.Eligible,
			candidate.Reason)
	}

}
Output:
agent/qwen eligible=false reason=provider is in cooldown
codex/gpt-5.4 eligible=true reason=score=71.2

type RouteRequest

type RouteRequest struct {
	Profile     string // optional named policy bundle: cheap|standard|smart|custom
	Model       string
	Provider    string
	Harness     string
	ModelRef    string
	Reasoning   Reasoning
	Permissions string
	MinPower    int
	MaxPower    int

	// EstimatedPromptTokens, when > 0, filters out candidates whose context
	// window cannot accommodate the prompt (with a safety margin).
	EstimatedPromptTokens int

	// RequiresTools, when true, filters out candidates that do not support
	// tool calling.
	RequiresTools bool

	// CachePolicy mirrors ServiceExecuteRequest.CachePolicy. Routing decisions
	// today do not act on it; it is carried through so callers using
	// ResolveRoute as a public surface can plumb the same opt-out the
	// Execute path honors.
	CachePolicy string
}

RouteRequest specifies a routing query.

type RouteStatusEntry

type RouteStatusEntry struct {
	Model          string // route key
	Strategy       string // "priority-round-robin" | "first-available" | etc.
	Candidates     []RouteCandidateStatus
	LastDecision   *RouteDecision // most recent ResolveRoute result for this key (cached)
	LastDecisionAt time.Time
}

RouteStatusEntry describes one configured model route.

type RouteStatusReport

type RouteStatusReport struct {
	Routes          []RouteStatusEntry
	GeneratedAt     time.Time
	GlobalCooldowns []CooldownState
	// RoutingQuality holds the three first-class routing-quality metrics
	// over a recent window (last RouteStatusRoutingQualityWindow requests).
	RoutingQuality RoutingQualityMetrics
}

RouteStatusReport is returned by RouteStatus.

RoutingQuality (ADR-006 §5) is the operator-facing measure of how often auto-routing produces an acceptable decision. It is intentionally distinct from per-(provider, model) provider-reliability surfaced on each RouteCandidateStatus: the two compose, and conflating them is the UI bug ADR-006 fixes.

type RoutingQualityMetrics

type RoutingQualityMetrics struct {
	// AutoAcceptanceRate = no-override requests / total requests. Higher is
	// better. The headline number for routing health.
	AutoAcceptanceRate float64 `json:"auto_acceptance_rate"`

	// OverrideDisagreementRate = overrides where the user pin differs from
	// auto on at least one overridden axis / total overrides. Lower is
	// better. Coincidental-agreement overrides land in the denominator but
	// not the numerator.
	OverrideDisagreementRate float64 `json:"override_disagreement_rate"`

	// OverrideClassBreakdown is a pivot of (prompt_features bucket,
	// axis_overridden, match_per_axis) → count + outcome aggregates.
	// Sorted deterministically by (PromptFeatureBucket, Axis, Match) so
	// snapshot tests remain stable across runs.
	OverrideClassBreakdown []OverrideClassBucket `json:"override_class_breakdown,omitempty"`

	// TotalRequests is the total Execute count over the metric window
	// (including overridden requests). Surface for operator UIs that want
	// to display "k out of N" alongside the rate.
	TotalRequests int `json:"total_requests"`

	// TotalOverrides is the total override count over the metric window.
	// Equal to TotalRequests-(no-override requests).
	TotalOverrides int `json:"total_overrides"`
}

RoutingQualityMetrics is the bundle of three first-class metrics ADR-006 makes operator-visible. AutoAcceptanceRate and OverrideDisagreementRate are fractions in [0,1]; OverrideClassBreakdown is the diagnostic pivot. All fields zero when the underlying window contains no requests.

type ScoredModel

type ScoredModel = oaiProvider.ScoredModel

func RankModels

func RankModels(candidates []string, knownModels map[string]string, pattern string) ([]ScoredModel, error)

type ServiceCompactionData

type ServiceCompactionData struct {
	MessagesBefore int `json:"messages_before"`
	MessagesAfter  int `json:"messages_after"`
	TokensFreed    int `json:"tokens_freed"`
}

type ServiceConfig

type ServiceConfig interface {
	// ProviderNames returns provider names in stable order (default first).
	ProviderNames() []string
	// DefaultProviderName returns the name of the configured default provider.
	DefaultProviderName() string
	// Provider returns the raw config values for a named provider.
	Provider(name string) (ServiceProviderEntry, bool)
	// ModelRouteNames returns configured model-route names.
	ModelRouteNames() []string
	// ModelRouteCandidates returns the provider names referenced by a route.
	ModelRouteCandidates(routeName string) []string
	// ModelRouteConfig returns the full route config for a named route.
	// Returns zero value when the route is not found.
	ModelRouteConfig(routeName string) ServiceModelRouteConfig
	// HealthCooldown returns the configured cooldown duration (0 = use default 30s).
	HealthCooldown() time.Duration
	// WorkDir is the base directory for file-backed health state.
	WorkDir() string
	// SessionLogDir returns the configured sessions directory.
	SessionLogDir() string
	// RouteHealthPath returns the path to the route health file for a given route key.
	RouteHealthPath(routeKey string) string
}

ServiceConfig provides provider and routing data to the service without creating an import cycle from the root package into agent/config. Callers wrap their loaded *config.Config in a type that satisfies this interface.

type ServiceDecodedEvent

type ServiceDecodedEvent struct {
	Type     string
	Sequence int64
	Time     time.Time
	Metadata map[string]string

	TextDelta        *ServiceTextDeltaData
	ToolCall         *ServiceToolCallData
	ToolResult       *ServiceToolResultData
	Compaction       *ServiceCompactionData
	RoutingDecision  *ServiceRoutingDecisionData
	Stall            *ServiceStallData
	Final            *ServiceFinalData
	Override         *ServiceOverrideData
	RejectedOverride *ServiceOverrideData
}

ServiceDecodedEvent is a typed view of one ServiceEvent. Exactly one payload pointer is non-nil for a known event type.

func DecodeServiceEvent

func DecodeServiceEvent(ev ServiceEvent) (ServiceDecodedEvent, error)

type ServiceEvent

type ServiceEvent = harnesses.Event

ServiceEvent is a contract-level event (mirrors harnesses.Event).

type ServiceExecuteRequest

type ServiceExecuteRequest struct {
	Prompt            string
	SystemPrompt      string
	Model             string
	Provider          string
	Harness           string
	ModelRef          string
	Profile           string
	WorkDir           string
	Temperature       *float32
	TopP              *float64
	TopK              *int
	MinP              *float64
	RepetitionPenalty *float64
	Seed              *int64
	// SamplingSource is the comma-separated layer attribution produced by
	// internal/sampling.Resolve. Plumbed through to the llm.request
	// telemetry event for ADR-007 override-tracking; never on the wire.
	SamplingSource string
	Reasoning      Reasoning
	NoStream       bool
	Permissions    string
	// Tools overrides the built-in native agent tool set when Harness is
	// "agent". Nil uses the native built-ins for ToolPreset and WorkDir.
	Tools []Tool
	// ToolPreset selects native built-in tool availability when Tools is nil.
	// Empty means the default preset; "benchmark" excludes the task tool.
	ToolPreset string

	// EstimatedPromptTokens, when > 0, drives auto-selection's
	// context-window gate (filter out candidates whose context window is
	// too small for the prompt + safety margin).
	EstimatedPromptTokens int
	// RequiresTools, when true, drives auto-selection's tool-support gate
	// (filter out candidates that cannot invoke tools).
	RequiresTools bool
	MinPower      int
	MaxPower      int

	// CachePolicy is the public opt-out for prompt caching. Empty (the zero
	// value) and "default" both request the per-provider default caching
	// behavior; "off" disables caching for this request. Any other value is
	// rejected at the service boundary (see ValidateCachePolicy). Providers
	// that do not implement caching ignore the field; this field is read by
	// the Anthropic cache_control writer (bead C) and the cache-aware cost
	// attribution path (bead D).
	CachePolicy string

	// Three independent timeout knobs:
	//   Timeout         — wall-clock cap on the entire request.
	//   IdleTimeout     — streaming-quiet cap; per-stream gap.
	//   ProviderTimeout — per-HTTP-request cap to the provider.
	Timeout         time.Duration
	IdleTimeout     time.Duration
	ProviderTimeout time.Duration

	// Optional native-loop overrides used when Harness == "agent". These let
	// the CLI and other callers route fully-resolved execution settings through
	// the service path instead of maintaining a divergent direct loop path.
	MaxIterations           int
	MaxTokens               int
	ReasoningByteLimit      int
	ReasoningStallTimeout   time.Duration
	CompactionContextWindow int
	CompactionReserveTokens int

	// Optional stall policy. When non-nil agent enforces and ends with
	// Status="stalled" if any limit hits. Default policy applies when nil.
	StallPolicy *StallPolicy

	// SessionLogDir overrides the default session-log directory for this
	// request (e.g. an execute-bead per-bundle evidence directory).
	SessionLogDir string

	// SelectedRoute is the configured model-route name the caller picked
	// (e.g. "code-pool"). Recorded into the service-owned session log so
	// post-hoc routing analytics can correlate logs to route keys without
	// reconstructing attribution from the event stream.
	SelectedRoute string

	// ResolvedModelRef is the profile/model reference (e.g. "code-medium")
	// that was mapped onto the concrete Model for this request. Paired with
	// ModelRef (the caller-requested reference) in the session log.
	ResolvedModelRef string

	// Metadata is bidirectional: echoed back in every Event AND stamped
	// onto every line of the session log so external consumers correlate.
	Metadata map[string]string
}

ServiceExecuteRequest is the public ExecuteRequest type per CONTRACT-003. See docs/helix/02-design/contracts/CONTRACT-003-fizeau-service.md (§"Public types") for the canonical shape; this struct is its in-process twin under the agent module.

type ServiceFinalData

type ServiceFinalData struct {
	Status         string                `json:"status"`
	ExitCode       int                   `json:"exit_code"`
	Error          string                `json:"error,omitempty"`
	FinalText      string                `json:"final_text,omitempty"`
	DurationMS     int64                 `json:"duration_ms"`
	Usage          *ServiceFinalUsage    `json:"usage,omitempty"`
	Warnings       []ServiceFinalWarning `json:"warnings,omitempty"`
	CostUSD        float64               `json:"cost_usd,omitempty"`
	SessionLogPath string                `json:"session_log_path,omitempty"`
	RoutingActual  *ServiceRoutingActual `json:"routing_actual,omitempty"`
}

type ServiceFinalUsage

type ServiceFinalUsage struct {
	InputTokens      *int                         `json:"input_tokens,omitempty"`
	OutputTokens     *int                         `json:"output_tokens,omitempty"`
	CacheReadTokens  *int                         `json:"cache_read_tokens,omitempty"`
	CacheWriteTokens *int                         `json:"cache_write_tokens,omitempty"`
	CacheTokens      *int                         `json:"cache_tokens,omitempty"`
	ReasoningTokens  *int                         `json:"reasoning_tokens,omitempty"`
	TotalTokens      *int                         `json:"total_tokens,omitempty"`
	Source           string                       `json:"source,omitempty"`
	Fresh            *bool                        `json:"fresh,omitempty"`
	CapturedAt       string                       `json:"captured_at,omitempty"`
	Sources          []ServiceUsageSourceEvidence `json:"sources,omitempty"`
}

ServiceFinalUsage is the public token-usage payload emitted on service final events. Token-count fields are *int so callers can distinguish an explicit upstream zero from "harness did not report this dimension":

  • nil pointer → the harness did not emit this token count (unknown). Consumers MUST NOT treat nil as zero or use it for budgeting.
  • non-nil *int → the harness emitted this exact value (including 0). Zero means the upstream provider explicitly reported zero usage; it is a real signal, not a gap.

Consumers that aggregate or compare usage across runs should branch on presence (nil vs non-nil) before reading the int. Per CONTRACT-003, the service preserves provider provenance verbatim — emitters at the harness boundary are forbidden from silently substituting zero for unknown.

type ServiceFinalWarning

type ServiceFinalWarning struct {
	Code    string                       `json:"code"`
	Message string                       `json:"message,omitempty"`
	Sources []ServiceUsageSourceEvidence `json:"sources,omitempty"`
}

type ServiceModelRouteConfig

type ServiceModelRouteConfig struct {
	Strategy   string                       // "priority-round-robin" | "ordered-failover" | "smart" | ""
	Candidates []ServiceRouteCandidateEntry // ordered candidate list
}

ServiceModelRouteConfig carries the routing strategy and candidates for one route.

type ServiceOptions

type ServiceOptions struct {
	ConfigPath string    // optional override; default $XDG_CONFIG_HOME/fizeau/config.yaml
	Logger     io.Writer // optional; agent writes structured session logs internally regardless

	// ServiceConfig, when non-nil, supplies provider and routing data for
	// ListProviders and HealthCheck. Pass a value wrapping the loaded config.
	// When nil, those methods return an error.
	ServiceConfig ServiceConfig

	// QuotaRefreshDebounce is the minimum interval between live quota probes for
	// a primary subscription harness. Zero uses the service default.
	QuotaRefreshDebounce time.Duration
	// QuotaRefreshStartupWait bounds startup waiting when the durable quota
	// cache is missing, stale, or incomplete. Zero uses the service default.
	QuotaRefreshStartupWait time.Duration
	// QuotaRefreshInterval enables periodic refresh for long-running server
	// processes. Zero disables the timer; cache refresh still happens on startup
	// and service activity.
	QuotaRefreshInterval time.Duration
	// QuotaRefreshContext optionally cancels the periodic server refresh worker.
	// When nil, the worker uses context.Background().
	QuotaRefreshContext context.Context

	// LocalCostUSDPer1kTokens is the operator-supplied electricity/operations
	// estimate for local endpoint providers under the embedded agent harness.
	// Zero means local endpoint cost is unknown.
	LocalCostUSDPer1kTokens float64
	// SubscriptionCostCurve optionally overrides the default subscription
	// effective-cost curve used by routing.
	SubscriptionCostCurve *SubscriptionCostCurve

	// SessionLogDir overrides the directory used by historical session-log
	// projections (UsageReport, ListSessionLogs, WriteSessionLog,
	// ReplaySession). Empty falls back to ServiceConfig.SessionLogDir().
	// Per-Execute requests still set their own
	// ServiceExecuteRequest.SessionLogDir.
	SessionLogDir string
	// contains filtered or unexported fields
}

ServiceOptions configures a FizeauService instance.

seamOptions is embedded so production builds (no testseam tag) get an empty struct — making it a compile-time error to set seam fields without the build tag. Test builds inherit the four CONTRACT-003 seams (FakeProvider, PromptAssertionHook, CompactionAssertionHook, ToolWiringHook) automatically.

type ServiceOverrideAutoComponents

type ServiceOverrideAutoComponents struct {
	Power            int     `json:"power"`
	Cost             float64 `json:"cost"`
	CostClass        string  `json:"cost_class,omitempty"`
	LatencyMS        float64 `json:"latency_ms"`
	SpeedTPS         float64 `json:"speed_tps"`
	SuccessRate      float64 `json:"success_rate"`
	QuotaOK          bool    `json:"quota_ok"`
	QuotaPercentUsed int     `json:"quota_percent_used"`
	QuotaTrend       string  `json:"quota_trend,omitempty"`
	Capability       float64 `json:"capability"`
}

ServiceOverrideAutoComponents mirrors RouteCandidateComponents for the candidate the unconstrained auto pipeline would have picked. Zero fields mean "unknown / not contributing".

type ServiceOverrideData

type ServiceOverrideData struct {
	SessionID      string                        `json:"session_id,omitempty"`
	UserPin        ServiceOverridePin            `json:"user_pin"`
	AutoDecision   ServiceOverridePin            `json:"auto_decision"`
	AxesOverridden []string                      `json:"axes_overridden"`
	MatchPerAxis   map[string]bool               `json:"match_per_axis"`
	AutoScore      float64                       `json:"auto_score"`
	AutoComponents ServiceOverrideAutoComponents `json:"auto_components"`
	PromptFeatures ServiceOverridePromptFeatures `json:"prompt_features"`
	ReasonHint     string                        `json:"reason_hint,omitempty"`
	Outcome        *ServiceOverrideOutcome       `json:"outcome,omitempty"`
	RejectionError string                        `json:"rejection_error,omitempty"`
}

ServiceOverrideData is the payload for both override and rejected_override events. Outcome is nil for rejected_override and populated post-execution for override.

func AsRejectedOverride

func AsRejectedOverride(err error) (ServiceOverrideData, bool)

AsRejectedOverride extracts the rejected_override payload from err if present. Returns (data, true) when err carries the wrapper, (zero, false) otherwise.

type ServiceOverrideOutcome

type ServiceOverrideOutcome struct {
	Status     string  `json:"status"`
	CostUSD    float64 `json:"cost_usd,omitempty"`
	DurationMS int64   `json:"duration_ms"`
}

ServiceOverrideOutcome carries post-execution status mirrored from the final event. Always omitted on rejected_override events.

type ServiceOverridePin

type ServiceOverridePin struct {
	Harness  string `json:"harness"`
	Provider string `json:"provider"`
	Model    string `json:"model"`
}

ServiceOverridePin captures a (harness, provider, model) tuple, used both for the user-supplied pin and the unconstrained auto decision in override / rejected_override events. Empty fields mean "axis not asserted / not produced" rather than zero.

type ServiceOverridePromptFeatures

type ServiceOverridePromptFeatures struct {
	EstimatedTokens *int   `json:"estimated_tokens,omitempty"`
	RequiresTools   bool   `json:"requires_tools"`
	Reasoning       string `json:"reasoning,omitempty"`
}

ServiceOverridePromptFeatures captures prompt-classification inputs that fed routing — used by post-hoc analysis to pivot override-class breakdowns. EstimatedTokens is nullable (nil = harness tokenizer did not produce a value); RequiresTools is the boolean carried on the request; Reasoning is the request's Reasoning level as a string.

type ServiceProviderEndpoint

type ServiceProviderEndpoint struct {
	Name    string
	BaseURL string
}

ServiceProviderEndpoint is one configured provider serving endpoint.

type ServiceProviderEntry

type ServiceProviderEntry struct {
	Type      string // "openai" | "openrouter" | "lmstudio" | "omlx" | "ollama" | "anthropic"
	BaseURL   string
	Endpoints []ServiceProviderEndpoint
	APIKey    string
	Model     string // configured default model (may be empty)
}

ServiceProviderEntry carries the minimal provider data the service needs.

type ServiceRouteCandidateEntry

type ServiceRouteCandidateEntry struct {
	Provider string
	Model    string // may be empty (provider default)
	Priority int
}

ServiceRouteCandidateEntry is one candidate inside a model route.

type ServiceRoutingActual

type ServiceRoutingActual struct {
	Harness            string   `json:"harness"`
	Provider           string   `json:"provider,omitempty"`
	Model              string   `json:"model"`
	FallbackChainFired []string `json:"fallback_chain_fired,omitempty"`
	FailureClass       string   `json:"failure_class,omitempty"`
}

type ServiceRoutingDecisionCandidate

type ServiceRoutingDecisionCandidate struct {
	Harness            string                           `json:"harness"`
	Provider           string                           `json:"provider,omitempty"`
	Endpoint           string                           `json:"endpoint,omitempty"`
	Model              string                           `json:"model,omitempty"`
	Score              float64                          `json:"score"`
	CostUSDPer1kTokens float64                          `json:"cost_usd_per_1k_tokens,omitempty"`
	CostSource         string                           `json:"cost_source,omitempty"`
	Eligible           bool                             `json:"eligible"`
	Reason             string                           `json:"reason,omitempty"`
	FilterReason       string                           `json:"filter_reason,omitempty"`
	Components         ServiceRoutingDecisionComponents `json:"components"`
}

ServiceRoutingDecisionCandidate is one entry in the routing-decision event's candidates list. Mirrors RouteCandidate but with JSON tags suited for event consumers.

type ServiceRoutingDecisionComponents

type ServiceRoutingDecisionComponents struct {
	Power            int     `json:"power"`
	Cost             float64 `json:"cost"`
	CostClass        string  `json:"cost_class,omitempty"`
	LatencyMS        float64 `json:"latency_ms"`
	SpeedTPS         float64 `json:"speed_tps"`
	SuccessRate      float64 `json:"success_rate"`
	QuotaOK          bool    `json:"quota_ok"`
	QuotaPercentUsed int     `json:"quota_percent_used"`
	QuotaTrend       string  `json:"quota_trend,omitempty"`
	Capability       float64 `json:"capability"`
}

ServiceRoutingDecisionComponents exposes the per-axis score inputs.

type ServiceRoutingDecisionData

type ServiceRoutingDecisionData struct {
	Harness       string   `json:"harness"`
	Provider      string   `json:"provider,omitempty"`
	Endpoint      string   `json:"endpoint,omitempty"`
	Model         string   `json:"model"`
	Reason        string   `json:"reason"`
	FallbackChain []string `json:"fallback_chain,omitempty"`
	SessionID     string   `json:"session_id,omitempty"`

	// Candidates exposes the full ranked decision trace. Each candidate
	// carries per-axis component scores (cost / latency / success rate /
	// capability) plus an explicit filter_reason for rejected entries.
	Candidates []ServiceRoutingDecisionCandidate `json:"candidates,omitempty"`
}

type ServiceStallData

type ServiceStallData struct {
	Reason string `json:"reason"`
	Count  int64  `json:"count"`
}

type ServiceTextDeltaData

type ServiceTextDeltaData struct {
	Text string `json:"text"`
}

type ServiceToolCallData

type ServiceToolCallData struct {
	ID    string          `json:"id"`
	Name  string          `json:"name"`
	Input json.RawMessage `json:"input,omitempty"`
}

type ServiceToolResultData

type ServiceToolResultData struct {
	ID         string `json:"id"`
	Output     string `json:"output,omitempty"`
	Error      string `json:"error,omitempty"`
	DurationMS int64  `json:"duration_ms,omitempty"`
}

type ServiceUsageSourceEvidence

type ServiceUsageSourceEvidence struct {
	Source     string                   `json:"source"`
	Fresh      *bool                    `json:"fresh,omitempty"`
	CapturedAt string                   `json:"captured_at,omitempty"`
	Usage      *ServiceUsageTokenCounts `json:"usage,omitempty"`
	Warning    string                   `json:"warning,omitempty"`
}

type ServiceUsageTokenCounts

type ServiceUsageTokenCounts struct {
	InputTokens      *int `json:"input_tokens,omitempty"`
	OutputTokens     *int `json:"output_tokens,omitempty"`
	CacheReadTokens  *int `json:"cache_read_tokens,omitempty"`
	CacheWriteTokens *int `json:"cache_write_tokens,omitempty"`
	CacheTokens      *int `json:"cache_tokens,omitempty"`
	ReasoningTokens  *int `json:"reasoning_tokens,omitempty"`
	TotalTokens      *int `json:"total_tokens,omitempty"`
}

type SessionEndData

type SessionEndData = session.SessionEndData

type SessionEvent

type SessionEvent = agentcore.Event

func NewSessionEvent

func NewSessionEvent(sessionID string, seq int, eventType SessionEventType, data any) SessionEvent

func ReadSessionEvents

func ReadSessionEvents(path string) ([]SessionEvent, error)

type SessionEventType

type SessionEventType = agentcore.EventType

type SessionLogEntry

type SessionLogEntry struct {
	SessionID string    `json:"session_id"`
	ModTime   time.Time `json:"mod_time"`
	Size      int64     `json:"size"`
}

SessionLogEntry describes one historical session log file projected from the service-owned session-log directory. Consumers display these without reading directory contents directly.

type SessionLogger

type SessionLogger = session.Logger

SessionLogger writes session log events. CLI tests construct one to seed log fixtures that the running CLI later reads back.

func NewSessionLogger

func NewSessionLogger(dir, sessionID string) *SessionLogger

type SessionStartData

type SessionStartData = session.SessionStartData

type SessionStatus

type SessionStatus = agentcore.Status

type StallPolicy

type StallPolicy struct {
	MaxReadOnlyToolIterations int // 0 = disabled
	MaxNoopCompactions        int // 0 = disabled
}

StallPolicy bounds how long the agent will spin without making progress before terminating with Status="stalled". A nil policy resolves to the default in service_execute.go.

type StatusError

type StatusError struct {
	Type      string    // unavailable|unauthenticated|error
	Detail    string    // human-readable detail, safe for diagnostics
	Source    string    // config path, endpoint, cache path, or probe name
	Timestamp time.Time // zero when the source did not include a timestamp
}

StatusError describes the most recent normalized status error for a harness, provider, or endpoint.

type SubscriptionCostCurve

type SubscriptionCostCurve struct {
	FreeUntilPercent   int
	LowUntilPercent    int
	MediumUntilPercent int
	LowMultiplier      float64
	MediumMultiplier   float64
	HighMultiplier     float64
}

SubscriptionCostCurve tunes effective subscription cost by quota utilization. Thresholds are percentages used, and multipliers are applied to the equivalent pay-per-token catalog rate.

type TokenUsage

type TokenUsage = agentcore.TokenUsage

type Tool

type Tool = agentcore.Tool

func BuiltinToolsForPreset

func BuiltinToolsForPreset(workDir, preset string, bashFilter BashOutputFilterConfig) []Tool

type UsageReport

type UsageReport struct {
	Window         *UsageReportWindow    `json:"window,omitempty"`
	Rows           []UsageReportRow      `json:"rows"`
	Totals         UsageReportRow        `json:"totals"`
	RoutingQuality RoutingQualityMetrics `json:"routing_quality"`
}

UsageReport is the public, service-owned aggregation over historical session logs. CLI subcommands consume this projection rather than re-reading the session-log JSONL schema directly.

RoutingQuality (ADR-006 §5) summarizes how often auto-routing produced an acceptable decision over the report window. It is intentionally distinct from the per-(provider, model) provider-reliability rate carried on each UsageReportRow (Row.SuccessRate); the two metrics measure different things and should be presented as separate numbers in operator UIs.

type UsageReportOptions

type UsageReportOptions struct {
	// Since limits the report window. Supported values include "today", "7d",
	// "30d", a date range "YYYY-MM-DD..YYYY-MM-DD", or a single start date.
	// Empty means no window filter (all sessions).
	Since string
	// Now is the reference time for relative windows. Zero means time.Now().
	Now time.Time
}

UsageReportOptions configures FizeauService.UsageReport.

type UsageReportRow

type UsageReportRow struct {
	Provider            string   `json:"provider"`
	Model               string   `json:"model"`
	Sessions            int      `json:"sessions"`
	SuccessSessions     int      `json:"success_sessions"`
	FailedSessions      int      `json:"failed_sessions"`
	InputTokens         int      `json:"input_tokens"`
	OutputTokens        int      `json:"output_tokens"`
	TotalTokens         int      `json:"total_tokens"`
	DurationMs          int64    `json:"duration_ms"`
	KnownCostUSD        *float64 `json:"known_cost_usd"`
	UnknownCostSessions int      `json:"unknown_cost_sessions"`
	CacheReadTokens     int      `json:"cache_read_tokens"`
	CacheWriteTokens    int      `json:"cache_write_tokens"`
}

UsageReportRow aggregates usage for one provider/model pair.

func (UsageReportRow) CacheHitRate

func (r UsageReportRow) CacheHitRate() float64

CacheHitRate returns the fraction of input tokens served from cache (0..1).

func (UsageReportRow) CostPerSuccess

func (r UsageReportRow) CostPerSuccess() *float64

CostPerSuccess returns the known cost divided by successful sessions, or nil if there are no successes or cost is unknown.

func (UsageReportRow) InputTokensPerSecond

func (r UsageReportRow) InputTokensPerSecond() float64

InputTokensPerSecond returns the average input-token throughput.

func (UsageReportRow) OutputTokensPerSecond

func (r UsageReportRow) OutputTokensPerSecond() float64

OutputTokensPerSecond returns the average output-token throughput.

func (UsageReportRow) SuccessRate

func (r UsageReportRow) SuccessRate() float64

SuccessRate returns the fraction of sessions that succeeded (0 if no sessions).

type UsageReportWindow

type UsageReportWindow struct {
	Start time.Time `json:"start"`
	End   time.Time `json:"end"`
}

UsageReportWindow describes the active reporting window.

type UsageWindow

type UsageWindow struct {
	Name                string
	Source              string
	CapturedAt          time.Time
	Fresh               bool
	InputTokens         int
	OutputTokens        int
	TotalTokens         int
	CacheReadTokens     int
	CacheWriteTokens    int
	ReasoningTokens     int
	CostUSD             float64
	KnownCostUSD        *float64
	UnknownCostSessions int
}

UsageWindow describes normalized usage attribution over a time window. Empty token/cost totals mean the service has no historical usage source yet.

Directories

Path Synopsis
Package agentcli exposes the fiz command runner for binaries and embedding callers that need to invoke the CLI without os.Exit.
Package agentcli exposes the fiz command runner for binaries and embedding callers that need to invoke the CLI without os.Exit.
cmd
bench command
Command bench discovers (harness, provider, model) candidates from agent config and runs a corpus of small tasks to produce per-task metrics.
Command bench discovers (harness, provider, model) candidates from agent config and runs a corpus of small tasks to produce per-task metrics.
benchscore command
catalogdist command
fiz command
Command fiz is a standalone CLI that wraps the fizeau library.
Command fiz is a standalone CLI that wraps the fizeau library.
renamecheck command
Package configinit is a public marker package whose sole purpose is to trigger the init() in internal/config that registers the ConfigPath-backed ServiceConfig loader with the root agent package.
Package configinit is a public marker package whose sole purpose is to trigger the init() in internal/config that registers the ConfigPath-backed ServiceConfig loader with the root agent package.
internal
benchmark/external/termbench
Package termbench is the TerminalBench external-benchmark adapter.
Package termbench is the TerminalBench external-benchmark adapter.
benchmark/profile
Package profile is the canonical reader for v7 benchmark profile YAML files under scripts/benchmark/profiles/.
Package profile is the canonical reader for v7 benchmark profile YAML files under scripts/benchmark/profiles/.
compaction
Package compaction provides conversation compaction for the agent loop.
Package compaction provides conversation compaction for the agent loop.
comparison
Package comparison provides cross-harness comparison, benchmarking, and quorum primitives for the fizeau integration suite.
Package comparison provides cross-harness comparison, benchmarking, and quorum primitives for the fizeau integration suite.
config
Package config provides multi-provider configuration loading for agent.
Package config provides multi-provider configuration loading for agent.
core
Package core contains the internal agent loop and provider-facing DTOs.
Package core contains the internal agent loop and provider-facing DTOs.
corpus
Package corpus implements the internal benchmark corpus: a curated, capability-tagged set of closed beads worth tracking over time.
Package corpus implements the internal benchmark corpus: a curated, capability-tagged set of closed beads worth tracking over time.
observations
Package observations tracks per-(provider,model) speed samples for use by routing strategies.
Package observations tracks per-(provider,model) speed samples for use by routing strategies.
prompt
Package prompt provides composable system prompt construction for agent.
Package prompt provides composable system prompt construction for agent.
provider/anthropic
Package anthropic implements a agent.Provider for the Anthropic Claude API.
Package anthropic implements a agent.Provider for the Anthropic Claude API.
provider/conformance
Package conformance contains shared provider behavior tests.
Package conformance contains shared provider behavior tests.
provider/lucebox
Package lucebox wraps the OpenAI-compat HTTP shape exposed by the lucebox-hub dflash server (https://github.com/Luce-Org/lucebox-hub).
Package lucebox wraps the OpenAI-compat HTTP shape exposed by the lucebox-hub dflash server (https://github.com/Luce-Org/lucebox-hub).
provider/openai
Package openai implements a agent.Provider for any OpenAI-compatible API endpoint (LM Studio, Ollama, OpenAI, Azure, Groq, Together, OpenRouter).
Package openai implements a agent.Provider for any OpenAI-compatible API endpoint (LM Studio, Ollama, OpenAI, Azure, Groq, Together, OpenRouter).
provider/registry
Package registry is the single source of truth for provider-type → factory mappings.
Package registry is the single source of truth for provider-type → factory mappings.
provider/virtual
Package virtual implements a agent.Provider that replays recorded responses from a dictionary.
Package virtual implements a agent.Provider that replays recorded responses from a dictionary.
provider/vllm
Package vllm wraps the OpenAI-compat HTTP surface exposed by `vllm serve` (https://docs.vllm.ai/).
Package vllm wraps the OpenAI-compat HTTP surface exposed by `vllm serve` (https://docs.vllm.ai/).
pty
Package pty documents the internal direct-PTY substrate boundary.
Package pty documents the internal direct-PTY substrate boundary.
pty/cassette
Package cassette records and replays versioned direct-PTY evidence.
Package cassette records and replays versioned direct-PTY evidence.
pty/session
Package session owns direct PTY process lifecycle and timed raw/input events.
Package session owns direct PTY process lifecycle and timed raw/input events.
pty/terminal
Package terminal derives rendered VT frames from raw PTY bytes.
Package terminal derives rendered VT frames from raw PTY bytes.
ptytest
Package ptytest provides test-only PTY cassette scenario assertions.
Package ptytest provides test-only PTY cassette scenario assertions.
routing
Package routing implements the unified routing engine for fizeau.
Package routing implements the unified routing engine for fizeau.
sampling
Package sampling owns the sampling-profile data type and the resolution chain that decides which sampler fields land on the wire for a given (model, profile, provider-override) tuple.
Package sampling owns the sampling-profile data type and the resolution chain that decides which sampler fields land on the wire for a given (model, profile, provider-override) tuple.
sdk/openaicompat
Package openaicompat contains shared OpenAI-compatible Chat Completions protocol plumbing.
Package openaicompat contains shared OpenAI-compatible Chat Completions protocol plumbing.
session
Package session provides JSONL session logging, cost tracking, and replay for agent runs.
Package session provides JSONL session logging, cost tracking, and replay for agent runs.
sessionlog
Package sessionlog centralizes opening per-request session log files for harness runners and the agent service.
Package sessionlog centralizes opening per-request session log files for harness runners and the agent service.
tool
Package tool provides the built-in agent tools: read, write, edit, and bash.
Package tool provides the built-in agent tools: read, write, edit, and bash.
Package occompat provides compatibility for importing configurations from opencode.
Package occompat provides compatibility for importing configurations from opencode.
Package picompat provides compatibility for importing configurations from pi.
Package picompat provides compatibility for importing configurations from pi.
Package main provides the coverage ratchet enforcement tool.
Package main provides the coverage ratchet enforcement tool.

Jump to

Keyboard shortcuts

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