configtool

package
v1.11.0 Latest Latest
Warning

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

Go to latest
Published: Jul 11, 2026 License: MIT Imports: 12 Imported by: 0

Documentation

Overview

Package configtool implements the `config` tool: a single model-facing handle on evva's runtime settings, mirroring what the interactive /config overlay exposes to the user.

The package name is `configtool` (not `config`) so it doesn't collide with the pkg/config import it leans on for every read and write.

SUPPORTED_SETTINGS is the single source of truth: the tool's behaviour, its prompt body (prompt.go), and the permission posture all derive from this one table. Adding a setting here grows all three at once.

Index

Constants

This section is empty.

Variables

View Source
var SUPPORTED_SETTINGS = map[string]SettingConfig{
	"max_iterations": {
		Type:        TypeInt,
		Description: "Agent loop iteration cap; hitting it pauses for user continue",
		Get:         func(c *config.Config) any { return c.GetMaxIterations() },
		Set: func(c *config.Config, v any) error {
			n, err := coerceInt(v)
			if err != nil {
				return err
			}
			return c.SetMaxIterations(n)
		},
	},
	"max_tokens": {
		Type:        TypeInt,
		Description: "Per-completion output token cap; 0 lets the provider apply its default",
		Get:         func(c *config.Config) any { return c.GetMaxTokens() },
		Set: func(c *config.Config, v any) error {
			n, err := coerceInt(v)
			if err != nil {
				return err
			}
			return c.SetMaxTokens(n)
		},
	},
	"auto_compact_threshold": {
		Type:        TypeFloat,
		Description: "Fraction of context (0,1] at which auto-compaction triggers",
		Get:         func(c *config.Config) any { return c.GetAutoCompactThreshold() },
		Set: func(c *config.Config, v any) error {
			f, err := coerceFloat(v)
			if err != nil {
				return err
			}
			return c.SetAutoCompactThreshold(f)
		},
	},
	"display_thinking": {
		Type:        TypeBool,
		Description: "Show the model's reasoning trace in the TUI",
		Get:         func(c *config.Config) any { return c.GetDisplayThinking() },
		Set: func(c *config.Config, v any) error {
			b, err := coerceBool(v)
			if err != nil {
				return err
			}
			return c.SetDisplayThinking(b)
		},
	},
	"enable_auto_memory": {
		Type:        TypeBool,
		Description: "Enable the typed-memory directory: the prompt's memory guidance + MEMORY.md index, the write carve-out, and per-turn recall (next boot)",
		Get:         func(c *config.Config) any { return c.GetEnableAutoMemory() },
		Set: func(c *config.Config, v any) error {
			b, err := coerceBool(v)
			if err != nil {
				return err
			}
			return c.SetEnableAutoMemory(b)
		},
	},
	"enable_memory_recall": {
		Type:        TypeBool,
		Description: "Run the per-turn relevance side-query that surfaces stored memories (cost lever; turn off to keep the index but drop the extra completion per turn)",
		Get:         func(c *config.Config) any { return c.GetEnableMemoryRecall() },
		Set: func(c *config.Config, v any) error {
			b, err := coerceBool(v)
			if err != nil {
				return err
			}
			return c.SetEnableMemoryRecall(b)
		},
	},
	"memory_recall_model": {
		Type:        TypeString,
		Description: "Model id for the recall side-query; empty = a cheap model within the active provider (anthropic: sonnet, deepseek: flash, openai: gpt-5.4-mini, glm: glm-4.6 at medium effort; ollama/other: the active model + effort)",
		Get:         func(c *config.Config) any { return c.GetMemoryRecallModel() },
		Set:         func(c *config.Config, v any) error { return c.SetMemoryRecallModel(toString(v)) },
	},
	"enable_auto_dream": {
		Type:        TypeBool,
		Description: "Enable background memory consolidation (\"dream\"): when idle and enough sessions have accumulated, a fenced background agent merges, prunes, and re-indexes your memory store (off by default — a real but rare token cost)",
		Get:         func(c *config.Config) any { return c.GetEnableAutoDream() },
		Set: func(c *config.Config, v any) error {
			b, err := coerceBool(v)
			if err != nil {
				return err
			}
			return c.SetEnableAutoDream(b)
		},
	},
	"auto_dream_model": {
		Type:        TypeString,
		Description: "Model id for the background dream agent; empty = the same cheap per-provider default the recall side-query uses",
		Get:         func(c *config.Config) any { return c.GetAutoDreamModel() },
		Set:         func(c *config.Config, v any) error { return c.SetAutoDreamModel(toString(v)) },
	},
	"fetch_max_bytes": {
		Type:        TypeInt,
		Description: "Cap on the text web_fetch returns from one URL",
		Get:         func(c *config.Config) any { return c.GetFetchMaxBytes() },
		Set: func(c *config.Config, v any) error {
			n, err := coerceInt(v)
			if err != nil {
				return err
			}
			return c.SetFetchMaxBytes(n)
		},
	},
	"tavily_api_key": {
		Type:         TypeSecret,
		Description:  "Tavily API key for web_search; empty disables the tool",
		Get:          func(c *config.Config) any { return c.GetTavilyAPIKey() },
		Set:          func(c *config.Config, v any) error { return c.SetTavilyAPIKey(toString(v)) },
		FormatOnRead: maskSecret,
	},
	"default_effort": {
		Type:        TypeString,
		Description: "Thinking effort level used at boot; overridden at runtime by /effort",
		Options:     []string{"low", "medium", "high", "ultra"},
		Get:         func(c *config.Config) any { return c.Effort() },
		Set:         func(c *config.Config, v any) error { return c.SetDefaultEffort(toString(v)) },
	},
	"default_profile": {
		Type:        TypeString,
		Description: "Persona that boots on launch; must match a registered agent name. Empty = evva",
		Get:         func(c *config.Config) any { return c.GetDefaultProfile() },
		Set:         func(c *config.Config, v any) error { return c.SetDefaultProfile(toString(v)) },
	},
	"output_style": {
		Type:        TypeString,
		Description: "Output style overlaid on the main persona's voice: default (no overlay), Explanatory, Learning, or a custom output-styles/*.md name. Takes effect at the next profile rebuild (/output-style switches live)",
		Get:         func(c *config.Config) any { return c.GetOutputStyle() },
		Set: func(c *config.Config, v any) error {
			name := strings.TrimSpace(toString(v))

			styles, _ := outputstyle.LoadAll(c.AppHome, c.WorkDir)
			if _, warn := outputstyle.Resolve(styles, name); warn != "" {
				names := make([]string, 0, len(styles))
				for n := range styles {
					names = append(names, n)
				}
				sort.Strings(names)
				return fmt.Errorf("unknown output style %q; available: %s", name, strings.Join(names, ", "))
			}
			return c.SetOutputStyle(name)
		},
	},
}

SUPPORTED_SETTINGS is the model-facing setting catalog. It mirrors the /config overlay's buildConfigFields (pkg/ui/bubbletea/components/overlays/config.go), minus the session-only sampling knobs (temperature/top_k/top_p, which are never persisted and reset every boot), plus a small set of model-relevant settings the overlay doesn't surface (default_effort, default_profile).

Adding a new setting? Update buildConfigFields too — the two surfaces describe the same user-visible matrix from different angles (interactive vs. LLM-callable). TestSupportedSettingsKeys pins the key set so drift is caught in review.

Functions

func AllKeys

func AllKeys() []string

AllKeys returns every supported setting key, sorted, for the prompt generator and stable iteration.

func IsSupported

func IsSupported(key string) bool

IsSupported reports whether key is a recognized setting.

func Names

func Names() []tools.ToolName

Names is the set of tool names this family contributes to a profile's ActiveTools. Currently just CONFIG.

Types

type SettingConfig

type SettingConfig struct {
	Type        SettingType
	Description string
	// Options, when non-nil, restricts the accepted set of values.
	// Applies to TypeString only.
	Options []string
	// Get reads the current value off cfg via a typed accessor so the read
	// is race-free against a concurrent Set.
	Get func(cfg *config.Config) any
	// Set persists the new value. Implementations coerce then delegate to
	// the typed setter on cfg (SetMaxIterations, …) so validation, locking,
	// and SaveFile all happen exactly once, in the setter that owns the field.
	Set func(cfg *config.Config, value any) error
	// FormatOnRead, when non-nil, transforms the raw value for display.
	// Used by TypeSecret to mask the value (see maskSecret).
	FormatOnRead func(value any) any
}

SettingConfig describes one tunable setting the tool exposes.

Get and Set are deliberately untyped (any in / out) so one map can mix integers, floats, booleans, strings, and provider secrets. Each entry's Type tells the dispatch code how to coerce the incoming JSON value before handing it to Set.

func Get

func Get(key string) (SettingConfig, bool)

Get returns the config for key, or the zero value + false.

type SettingType

type SettingType int

SettingType discriminates how a value is coerced from JSON and rendered back for display.

const (
	TypeString SettingType = iota
	TypeBool
	TypeInt
	TypeFloat
	TypeSecret // string, but masked on read
)

type Tool

type Tool struct {
	// contains filtered or unexported fields
}

Tool implements the `config` tool: one input shape {setting, value?}, dispatched to a get (value omitted) or a set (value supplied).

func New

func New(cfg *config.Config) *Tool

New builds a config tool bound to cfg. cfg may be nil — Execute surfaces a clear error in that case.

func (*Tool) Description

func (t *Tool) Description() string

Description returns the dynamically-generated prompt body. Built from SUPPORTED_SETTINGS so the model's view of tunable settings always matches the registry (see prompt.go).

func (*Tool) Execute

func (t *Tool) Execute(_ context.Context, logger *slog.Logger, raw json.RawMessage) (tools.Result, error)

func (*Tool) Name

func (t *Tool) Name() string

func (*Tool) Schema

func (t *Tool) Schema() json.RawMessage

Jump to

Keyboard shortcuts

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