config

package
v0.6.2 Latest Latest
Warning

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

Go to latest
Published: Jul 4, 2026 License: Apache-2.0 Imports: 6 Imported by: 0

Documentation

Overview

Package config loads harness configuration.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ExpandTilde added in v0.6.1

func ExpandTilde(p, home string) string

ExpandTilde expands a leading "~/" (or "~\" or a bare "~") in p to home. Anything else — including "~user/..." — is returned unchanged.

Types

type Config

type Config struct {
	// Endpoint is the llama-server base URL (e.g. http://127.0.0.1:11436).
	Endpoint string `json:"endpoint"`
	// CompletionPath is the native completion route used to pass a GBNF grammar.
	CompletionPath string `json:"completion_path"`
	// Model is the default workhorse (E4B) — used for summarize/extract and as
	// the fallback for any task without a specific route. Empty = dedicated server.
	Model string `json:"model"`
	// TriageModel serves the fast tier (triage/classify). Empty = use Model.
	// NOTE on 8GB: the tiers are swap-exclusive, so routing a few triages to a
	// cold E2B costs a model swap; for latency-critical mixed workloads set this
	// to "" (let E4B handle triage) or batch same-tier calls.
	TriageModel string `json:"triage_model"`
	// EscalationModel is tried once when the primary defers (validation fail / low
	// confidence) BEFORE deferring to Opus. Empty = no escalation (defer directly).
	EscalationModel string `json:"escalation_model"`
	// ReasoningModel is the terminal LOCAL tier (grammar tasks only): after the whole
	// cascade defers, a thinking model gets one shot under a think-wrapped grammar
	// (gbnf.WrapThinking) to reclaim the deferral before falling through to Opus. Run
	// it thinking-OFF — the grammar, not the chat template, supplies the <think> span.
	// Empty = no reasoning tier (defer straight to Opus, the prior behavior).
	ReasoningModel string `json:"reasoning_model,omitempty"`
	// VisionModel is the VLM alias used for the vqa task (multimodal). Empty = no
	// vision route (vqa defers).
	VisionModel string `json:"vision_model,omitempty"`
	// VisionMaxImageBytes caps a single decoded image before it is rejected
	// (guards context/VRAM blowups). 0 = use the loader default.
	VisionMaxImageBytes int `json:"vision_max_image_bytes,omitempty"`
	// VideoFPS is the frame-sampling rate for video_describe (frames/second).
	VideoFPS float64 `json:"video_fps,omitempty"`
	// VideoMaxFrames caps how many sampled frames are sent to the VLM (bounds the
	// 8GB activation budget — frames, not weights, are the VRAM pressure).
	VideoMaxFrames int `json:"video_max_frames,omitempty"`
	// VideoFrameWidth scales each sampled frame to this width (px), aspect kept.
	VideoFrameWidth int `json:"video_frame_width,omitempty"`
	// FFmpegPath is the ffmpeg executable used to sample frames. Default "ffmpeg".
	FFmpegPath string `json:"ffmpeg_path,omitempty"`
	// --- STT / transcribe (Phase A.2) ---
	// STTModel is the llama-swap alias for the default whisper-server upstream
	// (large-v3-turbo). Empty = no STT route (transcribe defers).
	STTModel string `json:"stt_model,omitempty"`
	// STTModelHQ is the quality-escalation whisper upstream (large-v3), used when
	// a transcribe request passes hq=true. Empty = hq falls back to STTModel.
	STTModelHQ string `json:"stt_model_hq,omitempty"`
	// STTLanguage forces the transcription language ("en"/"es"); "" = auto-detect.
	// Per-call params["language"] overrides this. Forcing is more reliable on
	// noisy/code-switching field audio than auto-detect.
	STTLanguage string `json:"stt_language,omitempty"`
	// STTVAD enables Silero VAD (server launched with -vm + --vad) — the biggest
	// hallucination reducer on noisy field audio. Default true.
	STTVAD bool `json:"stt_vad,omitempty"`
	// STTMaxInlineSegments caps how many timestamped segments are inlined in the
	// result (the rest live in the on-disk .segments.json pointer). Default 120.
	STTMaxInlineSegments int `json:"stt_max_inline_segments,omitempty"`
	// STTUnloadAfter force-unloads the whisper upstream after each transcription
	// (zero-always-warm). Default true; set false for a known batch loop.
	STTUnloadAfter bool `json:"stt_unload_after,omitempty"`
	// STTRequestTimeoutSec bounds one transcription HTTP call (long audio at
	// 5-8x realtime). Default 1800 (30 min). Separate from RequestTimeoutSec.
	STTRequestTimeoutSec int `json:"stt_request_timeout_sec,omitempty"`
	// MediaDir is where transcribe writes .srt/.txt/.segments.json. Default
	// <base>/media.
	MediaDir string `json:"media_dir,omitempty"`
	// SVGDir is where generate_svg writes rendered .svg files. Default <base>/svg.
	SVGDir string `json:"svg_dir,omitempty"`
	// --- image generation (generate_image) ---
	// ImageGenScript is the absolute path to render/comfy-generate.mjs (the Node
	// lifecycle wrapper around comfy-render.mjs). Empty = no image route (the task
	// defers), exactly like an empty STTModel/VisionModel.
	ImageGenScript string `json:"imagegen_script,omitempty"`
	// NodePath is the node executable used to run the image script. Default "node".
	NodePath string `json:"node_path,omitempty"`
	// ComfyDir is the local ComfyUI install dir (passed to the script as COMFY_DIR).
	// Default "C:/ComfyUI".
	ComfyDir string `json:"comfy_dir,omitempty"`
	// ImageGenTimeoutSec bounds one render: ComfyUI cold-start (~4min) + first SDXL
	// render (~6min) + margin. Default 720 (12min).
	ImageGenTimeoutSec int `json:"imagegen_timeout_sec,omitempty"`
	// --- video / audio generation (generate_video / generate_audio) ---
	// VideoGenScript is the path to render/comfy-video.mjs (the I2V lifecycle wrapper).
	// Empty = no video route (the task defers cleanly), like an empty ImageGenScript.
	VideoGenScript string `json:"videogen_script,omitempty"`
	// VoiceGenScript is the path to render/tts.mjs (Chatterbox TTS; comfyManaged:false).
	// It serves generate_audio kind=voice. Empty = voice defers.
	VoiceGenScript string `json:"voicegen_script,omitempty"`
	// MusicGenScript is the path to the ACE-Step music worker (render/comfy-music.mjs,
	// ComfyUI). It serves generate_audio kind=music. Default render/comfy-music.mjs (the
	// B3 worker); set "" to disable (music defers) if the ACE-Step checkpoint isn't present.
	MusicGenScript string `json:"musicgen_script,omitempty"`
	// VideoGenTimeoutSec bounds one video render: ComfyUI cold-start + a long I2V
	// render (Wan native two-stage is slow). Default 1500 (25min).
	VideoGenTimeoutSec int `json:"videogen_timeout_sec,omitempty"`
	// AudioGenTimeoutSec bounds one audio synthesis (TTS or ACE-Step). Default 720 (12min).
	AudioGenTimeoutSec int `json:"audiogen_timeout_sec,omitempty"`
	// VideoGenWaitMs is how long a queued video job waits for the single GPU slot before
	// deferring (passed to the runner as GPU_LOCK waitMs). Long because video is the hero
	// job. Default 1200000 (20min).
	VideoGenWaitMs int `json:"videogen_wait_ms,omitempty"`
	// AudioGenWaitMs is how long a queued audio job waits for the GPU slot before deferring.
	// Kept SHORTER than video so a cheap queued TTS isn't starved by a 20-min video job —
	// it defers cleanly after this window. Default 120000 (2min).
	AudioGenWaitMs int `json:"audiogen_wait_ms,omitempty"`
	// GPULockPath overrides the single-slot GPU lock DIRECTORY shared with the render
	// runners (render/gpu-lock.mjs). Empty = the runners' own default (the GPU_LOCK env,
	// else <os-tmpdir>/local-offload-gpu.lock). When set it is also threaded to every gen
	// runner as the GPU_LOCK env, so the Go-side vision gate (LO-1) and the Node runners
	// always contend on the SAME lock.
	GPULockPath string `json:"gpu_lock_path,omitempty"`
	// VisionGPUWaitSec is how long a vision call (vqa/ocr/assess_image/video_describe)
	// waits for the GPU lock held by a generation job before deferring (polled every 2s).
	// While a gen job owns the GPU, llama-swap cannot (re)load the VLM — calling anyway
	// just burns an http_5xx defer to the expensive cloud model (LO-1: 295 of the 337
	// all-time defers landed in ONE such hour). Default 90.
	VisionGPUWaitSec int `json:"vision_gpu_wait_sec,omitempty"`
	// MemoryStack lists the CPU-only, zero-VRAM llama-swap models the GPU-free helper
	// must NEVER unload (the load-bearing mem0 stack). Sourced here (not a buried const)
	// so a renamed/added 3rd CPU member is honored. Threaded to the runner via the
	// MEMORY_STACK env. Default {embeddinggemma, bge-reranker-v2-m3}.
	MemoryStack []string `json:"memory_stack,omitempty"`
	// Temperature for deterministic structured output (default 0).
	Temperature float64 `json:"temperature"`
	// MaxRetries is how many correction re-prompts before deferring.
	MaxRetries int `json:"max_retries"`
	// ClassifyMinConfidence: classify results below this (self-reported) defer.
	ClassifyMinConfidence float64 `json:"classify_min_confidence"`
	// ConfidenceMarginThreshold: for triage/classify, if the logprob-derived
	// top-2 legal-class margin at the decision token is below this, escalate to a
	// larger tier (catches genuinely torn calls, e.g. eager-YES). 0 disables the
	// logprob gate. Default 0.35.
	ConfidenceMarginThreshold float64 `json:"confidence_margin_threshold"`
	// MaxInputChars caps input length before context-budget trimming.
	MaxInputChars int `json:"max_input_chars"`
	// CachePath / LedgerPath are bbolt files.
	CachePath  string `json:"cache_path"`
	LedgerPath string `json:"ledger_path"`
	// --- self-learning artifacts (written by the offline `calibrate`/`health`/
	// `train-router`/`optimize` jobs; read at pipeline startup). Empty = feature off. ---
	ThresholdsPath         string             `json:"thresholds_path,omitempty"`          // Phase 2: per-task conformal margin thresholds
	TierOverridesPath      string             `json:"tier_overrides_path,omitempty"`      // Phase 4: health-driven entry-tier bumps + P95 timeouts
	RouterWeightsPath      string             `json:"router_weights_path,omitempty"`      // Phase 5: logistic entry-tier router
	ConfHeadPath           string             `json:"confhead_path,omitempty"`            // Phase 2: logistic correctness head
	RouterLabelsPath       string             `json:"router_labels_path,omitempty"`       // Phase B: synthesized E2B-counterfactual router label sidecar
	ConfHeadLabelsPath     string             `json:"confhead_labels_path,omitempty"`     // Phase 2: cascade-agreement correctness-label sidecar (classify/triage)
	ConfHeadThresholdsPath string             `json:"confhead_thresholds_path,omitempty"` // Phase 2: per-task conformal p(correct) escalation thresholds (Task 3)
	ConfHeadEnabled        bool               `json:"confhead_enabled,omitempty"`         // Phase 2 Task 4: opt-in — gate ADOPT tasks on the head's p(correct). Default false.
	ExemplarsDir           string             `json:"exemplars_dir,omitempty"`            // Phase 6: few-shot exemplar sidecar + selected pool
	ExemplarShots          int                `json:"exemplar_shots,omitempty"`           // Phase 6: 0 = disabled
	AutoHeal               bool               `json:"auto_heal,omitempty"`                // Phase 7: opt-in autonomous tier reload
	TargetErrorRate        map[string]float64 `json:"target_error_rate,omitempty"`        // Phase 2: per-task α for calibration
	// OpusInputPricePerMTok estimates dollar savings ($ per 1M input tokens).
	OpusInputPricePerMTok float64 `json:"opus_input_price_per_mtok"`
	// RequestTimeoutSec for a single model call.
	RequestTimeoutSec int `json:"request_timeout_sec"`
	// --- shadow-labeling flywheel (Phase A.3) ---
	// ShadowEnabled gates sampled capture of non-escalated classify/triage/extract
	// entry-tier rows to the shadow queue for nightly counterfactual labeling.
	// Default false (off by default; never affects request latency or behavior).
	ShadowEnabled bool `json:"shadow_enabled,omitempty"`
	// ShadowRate is the fraction of eligible rows to capture (0.0–1.0).
	// Default 0.10 (10 %). A value of 0 disables capture even when ShadowEnabled.
	ShadowRate float64 `json:"shadow_rate,omitempty"`
	// ShadowQueuePath is the append-only JSONL file for captured shadow items.
	// Default <DataDir>/shadow-queue.jsonl.
	ShadowQueuePath string `json:"shadow_queue_path,omitempty"`
	// SummarizeSimThreshold is the minimum cosine similarity (0..1) between the
	// entry-tier and escalation-tier summary embeddings to count as "agreed".
	// Used by the B2 summarize judge in shadow-label. Default 0.80.
	SummarizeSimThreshold float64 `json:"summarize_sim_threshold,omitempty"`
	// --- P6: agentic-trajectory flywheel (off by default; mirrors ShadowEnabled) ---
	// AgentTrajectoryCaptureEnabled gates sampled capture of standalone agent
	// trajectories to the trajectory queue for offline counterfactual labeling.
	// Default false (off; never affects request latency or agent behavior).
	AgentTrajectoryCaptureEnabled bool `json:"agent_trajectory_capture_enabled,omitempty"`
	// AgentTrajectoryRate is the fraction of completed goals to capture (0.0–1.0).
	// Default 0.10. A value of 0 disables capture even when enabled.
	AgentTrajectoryRate float64 `json:"agent_trajectory_rate,omitempty"`
	// AgentTrajectoryQueuePath is the append-only JSONL capture queue.
	// Default <DataDir>/agent-trajectory-queue.jsonl.
	AgentTrajectoryQueuePath string `json:"agent_trajectory_queue_path,omitempty"`
	// AgentTrajectoryLabelsPath is the correctness-label SIDECAR the P6 flywheel
	// writes (via ledger.AppendLabel — NEVER the savings ledger).
	// Default <DataDir>/agent-trajectory-labels.jsonl.
	AgentTrajectoryLabelsPath string `json:"agent_trajectory_labels_path,omitempty"`
	// --- zero-training kNN entry-tier pre-filter (meta-router v2) ---
	// KNNPreFilterEnabled gates the kNN pre-filter — a bridge before the LR
	// router (router_weights) is trained. When on, classify/triage inputs are
	// embedded and matched against KNNIndexPath to decide whether to skip the
	// E2B tier; it yields to the LR router once that task is trained. Default
	// false; with it off the request path is byte-identical to the prior build.
	KNNPreFilterEnabled bool `json:"knn_prefilter_enabled,omitempty"`
	// KNNIndexPath is the JSONL substrate (task, vec, accept) appended by the
	// nightly shadow-label drain. Default <base>/knn-index.jsonl.
	KNNIndexPath string `json:"knn_index_path,omitempty"`
	// KNNPreFilterK is how many nearest neighbors to poll. Default 7.
	KNNPreFilterK int `json:"knn_prefilter_k,omitempty"`
	// KNNMinNeighbors is the minimum usable rows-per-task before the kNN acts
	// (guards against a too-thin substrate). Default 20.
	KNNMinNeighbors int `json:"knn_min_neighbors,omitempty"`
	// KNNPreFilterThreshold: skip E2B when the fraction of the k nearest
	// neighbors that accepted at E2B is below this. Default 0.5.
	KNNPreFilterThreshold float64 `json:"knn_prefilter_threshold,omitempty"`
	// KNNEmbedTimeoutMs bounds the request-path embedding call (fail-open on
	// timeout). Default 2000.
	KNNEmbedTimeoutMs int `json:"knn_embed_timeout_ms,omitempty"`
	// --- explicit remote NIM tool (`nim` subcommand / offload_nim) ---
	// An opt-in path to an OpenAI-compatible NVIDIA NIM endpoint, separate from the
	// local cascade: the GBNF grammar path and the savings ledger are untouched.
	// NIMEndpoint is the base (with the /v1 segment): NVIDIA's hosted API by
	// default, or a self-hosted NIM container (e.g. http://127.0.0.1:8000/v1).
	NIMEndpoint string `json:"nim_endpoint,omitempty"`
	// NIMModel is the default model id (override per call with --model). The hosted
	// catalog has dozens of free endpoints — browse with `nim --list-models`.
	NIMModel string `json:"nim_model,omitempty"`
	// NIMMaxTokens caps a nim completion when the caller sets none. Reasoning models
	// need headroom (they spend tokens thinking before answering). Default 1024.
	NIMMaxTokens int `json:"nim_max_tokens,omitempty"`
	// NIMTimeoutSec bounds one nim call (large hosted models can be slow). Default 120.
	NIMTimeoutSec int `json:"nim_timeout_sec,omitempty"`
}

Config controls endpoint, model, thresholds, and storage paths.

func Default

func Default() Config

Default returns a config suitable for the verified E4B-QAT+MTP setup.

func Load

func Load(path string) (Config, error)

Load merges a JSON config file over the defaults. Missing file => defaults. A leading "~/" in any path-typed field is expanded to the user home dir (LO-4: config.example.json ships "~/.local-offload/..." paths that were previously taken literally, silently creating a "~" directory in the cwd).

func (Config) EnsureDirs

func (c Config) EnsureDirs() error

EnsureDirs creates the parent dirs for the store files.

Jump to

Keyboard shortcuts

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