mirror of
https://github.com/Twigpine/zero.git
synced 2026-11-11 23:40:28 -10:00
Module 2 of the runtime-core split (off main, after #105). Scope: internal/modelregistry only — fully additive (the whole tree builds unchanged against it). - Regex MatchPatterns aliases + pattern-based Resolve. - DeprecationRule with FallbackID; ResolveWithFallback returns the active fallback model + a user notice for deprecated ids; NewRegistry validates every Deprecation.FallbackID resolves (fail-fast on misconfig). - ReasoningEffort support: per-model ReasoningEfforts + DefaultReasoningEffort (validated to be a member of the model's set) + EffectiveReasoningEffort(). - Mode presets (modes.go: smart/deep/fast/large/precise -> model id + reasoning effort). These are the registry-capability layer; the CLI/agent adoption (--model deprecation-fallback, --mode, -r/--reasoning-effort, enhanced 'zero models') lands in a later module to keep PRs reviewable. Build/vet/full-suite/-race green; no new deps. Co-authored-by: KRATOS <[email protected]> Co-authored-by: Claude Opus 4.8 (1M context) <[email protected]>
105 lines
3.3 KiB
Go
105 lines
3.3 KiB
Go
package modelregistry
|
|
|
|
import "strings"
|
|
|
|
// Mode bundles a model selection, reasoning effort, agent-loop turn budget, and
|
|
// an optional tool filter behind a single short name. Modes are presets that let
|
|
// callers switch the whole agent profile (smart/deep/fast/...) with one flag or
|
|
// command instead of tuning --model/--reasoning-effort/--max-turns by hand.
|
|
//
|
|
// Model holds a registry id or alias (resolved through Resolve/ResolveWithFallback
|
|
// at apply time so deprecation fallbacks and fuzzy aliases stay honored). MaxTurns
|
|
// of 0 means "leave the configured/default turn budget untouched". Effort of ""
|
|
// means "let the model's effective default apply".
|
|
type Mode struct {
|
|
Name string
|
|
Description string
|
|
Model string
|
|
Effort ReasoningEffort
|
|
MaxTurns int
|
|
// EnabledTools / DisabledTools optionally narrow the tool surface for the
|
|
// mode. Empty slices leave the existing tool selection untouched.
|
|
EnabledTools []string
|
|
DisabledTools []string
|
|
}
|
|
|
|
// defaultModes is the canonical preset catalog. It is kept data-driven so the
|
|
// CLI flag, the TUI command, and tests all read from one source of truth. Models
|
|
// reference real registry ids (see catalog.go); efforts reference real
|
|
// ReasoningEffort values.
|
|
var defaultModes = []Mode{
|
|
{
|
|
Name: "smart",
|
|
Description: "Balanced daily driver for high-quality agent work.",
|
|
Model: "claude-sonnet-4.5",
|
|
Effort: ReasoningEffortMedium,
|
|
},
|
|
{
|
|
Name: "deep",
|
|
Description: "Hardest tasks: deep reasoning with a larger turn budget.",
|
|
Model: "claude-opus-4.1",
|
|
Effort: ReasoningEffortHigh,
|
|
MaxTurns: 50,
|
|
},
|
|
{
|
|
Name: "fast",
|
|
Description: "Low-latency support for quick edits and summaries.",
|
|
Model: "claude-haiku-4.5",
|
|
Effort: ReasoningEffortLow,
|
|
MaxTurns: 15,
|
|
},
|
|
{
|
|
Name: "large",
|
|
Description: "Long-context work over large inputs.",
|
|
Model: "gemini-2.5-pro",
|
|
Effort: ReasoningEffortMedium,
|
|
},
|
|
{
|
|
Name: "precise",
|
|
Description: "Careful, high-effort reasoning for exacting changes.",
|
|
Model: "claude-sonnet-4.5",
|
|
Effort: ReasoningEffortHigh,
|
|
},
|
|
}
|
|
|
|
// Modes returns a copy of the preset catalog, preserving declaration order so
|
|
// list output and help text stay stable.
|
|
func Modes() []Mode {
|
|
modes := make([]Mode, len(defaultModes))
|
|
for index, mode := range defaultModes {
|
|
modes[index] = cloneMode(mode)
|
|
}
|
|
return modes
|
|
}
|
|
|
|
// LookupMode returns the preset registered under name (case-insensitive,
|
|
// whitespace-trimmed). The second result reports whether a preset matched.
|
|
func LookupMode(name string) (Mode, bool) {
|
|
normalized := strings.ToLower(strings.TrimSpace(name))
|
|
if normalized == "" {
|
|
return Mode{}, false
|
|
}
|
|
for _, mode := range defaultModes {
|
|
if mode.Name == normalized {
|
|
return cloneMode(mode), true
|
|
}
|
|
}
|
|
return Mode{}, false
|
|
}
|
|
|
|
// ModeNames returns the preset names in declaration order, handy for usage and
|
|
// error messages that need to list the valid modes.
|
|
func ModeNames() []string {
|
|
names := make([]string, len(defaultModes))
|
|
for index, mode := range defaultModes {
|
|
names[index] = mode.Name
|
|
}
|
|
return names
|
|
}
|
|
|
|
func cloneMode(mode Mode) Mode {
|
|
mode.EnabledTools = append([]string{}, mode.EnabledTools...)
|
|
mode.DisabledTools = append([]string{}, mode.DisabledTools...)
|
|
return mode
|
|
}
|