Documentation
¶
Overview ¶
Package config carries the runtime configuration the evva agent and its bundled tools read at startup and during a session.
The package is brand-neutral: a Config is constructed via Load(appName, appHome, workdir) so downstream apps can choose their own home directory (e.g. ~/.myapp/) and binary name. LoadDefault preserves evva's historical behavior (~/.evva/) for the bundled CLI.
There is no package-level singleton. Callers construct one Config per process (or per agent, if running multiple agents with different configurations) and pass it through agent.New via WithConfig.
Index ¶
- Constants
- Variables
- func DisplayVersion() string
- func ResolveDefaultModel(provider, model string) (constant.LLMProvider, constant.Model, error)
- func SaveFileConfig(path string, cfg FileConfig) error
- type APIConfig
- type Config
- func (c *Config) Clone() *Config
- func (c *Config) DeleteCustom(key string) error
- func (c *Config) Effort() string
- func (c *Config) GetAutoCompactThreshold() float64
- func (c *Config) GetCustom(key string) (any, bool)
- func (c *Config) GetDisplayThinking() bool
- func (c *Config) GetEnableAutoMemory() bool
- func (c *Config) IsDevelopment() bool
- func (c *Config) IsProduction() bool
- func (c *Config) LLMTemperature() *float64
- func (c *Config) LLMTopK() *int
- func (c *Config) LLMTopP() *float64
- func (c *Config) SaveFile() error
- func (c *Config) SetAutoCompactThreshold(v float64) error
- func (c *Config) SetCustom(key string, value any) error
- func (c *Config) SetDefaultEffort(level string) error
- func (c *Config) SetDefaultModel(provider constant.LLMProvider, model constant.Model) error
- func (c *Config) SetDefaultProfile(name string) error
- func (c *Config) SetDisplayThinking(v bool) error
- func (c *Config) SetEnableAutoMemory(v bool) error
- func (c *Config) SetFetchMaxBytes(n int) error
- func (c *Config) SetLLMTemperature(v *float64) error
- func (c *Config) SetLLMTopK(v *int) error
- func (c *Config) SetLLMTopP(v *float64) error
- func (c *Config) SetMaxIterations(n int) error
- func (c *Config) SetMaxTokens(n int) error
- func (c *Config) SetProviderAPIKey(name, key string) error
- func (c *Config) SetProviderAPIURL(name, url string) error
- func (c *Config) SetProviderCredentials(name, apiURL, apiKey string) error
- func (c *Config) SetTavilyAPIKey(s string) error
- type EnvOverride
- type FileConfig
- type FileProviderConfig
- type LoadOptions
- type ProviderCredsFromEnv
Examples ¶
Constants ¶
const ( DefaultAppName = "evva" DefaultAppVersion = version.Version )
Default values that appear unchanged across all Config instances.
Variables ¶
var BuildDate string
BuildDate is the UTC build timestamp injected at build time. Empty in dev builds.
var CommitSHA string
CommitSHA is the git commit hash injected at build time via ldflags. Empty in dev builds.
var Version string
Version is the canonical version string injected at build time via ldflags:
go build -ldflags "-X github.com/johnny1110/evva/pkg/config.Version=v1.2.3"
When empty (dev builds, go run), DefaultAppVersion is used as the fallback.
Functions ¶
func DisplayVersion ¶
func DisplayVersion() string
DisplayVersion returns the best available version string: the ldflags-injected Version, or DefaultAppVersion if not set, followed by the commit and build date when available. The result is meant for --version output.
func ResolveDefaultModel ¶
ResolveDefaultModel parses the (provider name, model name) pair from the YAML and returns the typed constants. Validates that the model is actually one the provider lists — a typo or a model/provider mismatch fails fast at startup with a clear message rather than a confusing runtime "unknown model" from the LLM API.
func SaveFileConfig ¶
func SaveFileConfig(path string, cfg FileConfig) error
SaveFileConfig writes cfg to path atomically (temp file + rename) so a crash mid-write never leaves a truncated YAML behind.
Types ¶
type APIConfig ¶
APIConfig carries the per-provider credentials an LLM client needs to talk to its backend. The host (cmd/evva or a downstream consumer) constructs one APIConfig per provider from whatever config source it uses (YAML, env vars, secret manager) and passes it to the registry-resolved ClientFactory in pkg/llm.
Defined in pkg/config rather than pkg/llm to avoid a cycle: pkg/llm imports pkg/tools, pkg/tools imports pkg/config (for the State.Config() return type). pkg/config sits at the bottom and is imported by both pkg/llm (via alias) and pkg/tools.
type Config ¶
type Config struct {
// OS / runtime
OS string
// Logging
LogLevel string // default: "info"
LogFormat string // default: "text"
LogDir *string // default: nil → stdout only
// Application
AppEnv string // default: "development"
AppName string // default: "evva" — the binary / brand name; drives AppHome layout.
AppVersion string
// Per-user home dir layout
AppHome string
AppHomeSkillsDir string
AppHomeUserProfile string
AppHomeConfigFile string // absolute path to <app>-config.yml under AppHome/config/
AutoCompactThreshold float64
// Workdir layout
WorkDir string
WorkDirSkillsDir string
// llm providers(from <app>-config.yml) key: provider name, value: provider APIConfig
LLMProviderConfig map[string]APIConfig
// DefaultProvider / DefaultModel are the (provider, model) the agent
// boots with. Sourced from <app>-config.yml; the /model switch updates
// them in-memory and persists via SaveFile().
DefaultProvider constant.LLMProvider
DefaultModel constant.Model
// DefaultEffort is the user-facing effort level name: low|medium|high|ultra.
// Defaults to "medium". Sourced from <app>-config.yml; /effort updates it.
DefaultEffort string
// DefaultProfile is the persona the root agent boots into ("evva", "nono",
// etc). Sourced from <app>-config.yml; /profile updates it. Empty falls
// back to "evva" at bootstrap so old configs keep working.
DefaultProfile string
// PermissionMode is the startup permission stance: one of
// default|accept_edits|plan|bypass|auto. The -permission-mode CLI flag
// overrides this at boot; the TUI's Shift+Tab cycle mutates the
// in-memory value via SetPermissionMode (not yet persisted).
PermissionMode string
// Loaded metadata
LoadedAt time.Time
// DefaultMaxIterations is the loop's safety cap. Hitting it emits a
// KindIterLimit event and pauses the agent; the caller may invoke
// Continue(ctx) to keep going.
DefaultMaxIterations int
// DefaultMaxTokens is the per-completion output-token cap passed to
// the LLM. 0 → let the provider apply its own default.
DefaultMaxTokens int
// UI
DisplayThinking bool
// Auto-memory subsystem. When true (default), update_user_profile +
// update_project_memory tools are registered on Main and the system
// prompt carries the auto-memory guidance + project-memory index.
// /config (or hand-edit) flips this; EVVA_AUTO_MEMORY=0 forces off at
// boot regardless of the YAML.
EnableAutoMemory bool
// Web tools
TavilyAPIKey string // empty → web_search reports "not configured"
FetchMaxBytes int // cap on extracted text returned by web_fetch
// CustomConfig holds downstream-app-defined settings. Reads/writes go
// through GetCustom / SetCustom / DeleteCustom under c.mu. Values
// round-trip through YAML as a `custom:` section; complex types are
// encoded as whatever gopkg.in/yaml.v3 produces for any (typically a
// map[string]any tree). Consumers cast at use-site — pkg/config does
// not know the value shapes.
//
// Use this slot for downstream-private secrets/settings that don't fit
// the typed fields above (e.g. friday's broker URL, a billing token,
// feature flags). evva itself never reads from CustomConfig.
CustomConfig map[string]any
// LLMParamsTemperature / LLMParamsTopP / LLMParamsTopK are session-only
// sampling knobs the /config form mutates at runtime. nil → provider
// default (not sent in API request). Reset to nil on every evva start;
// never persisted to YAML.
LLMParamsTemperature *float64
LLMParamsTopP *float64
LLMParamsTopK *int
// contains filtered or unexported fields
}
Config holds all parsed runtime configuration. Most fields are populated once during Load and treated as read-only; the small subset that the /config and /model setters mutate at runtime is guarded by c.mu.
AppHome-prefixed paths point inside the per-user home dir (~/.<app>/) where skills, USER_PROFILE.md, evva-config.yml, and logs live. WorkDir-prefixed paths point inside the process's current working directory where workdir-local resources (skills, EVVA.md, plans) live.
func Get ¶
func Get() *Config
Get returns a process-wide Config initialized lazily via LoadDefault. Subsequent calls return the same pointer.
Get is a host-side convenience for the bundled cmd/evva binary and for the reference TUI (which reads runtime settings without an injected pointer). Library code inside the agent loop and tools must NOT call Get — they receive *Config through dependency injection (agent.WithConfig, toolset.ToolState.SetConfig, function parameters).
Downstream hosts that want a non-default AppHome should call Load with explicit LoadOptions and pass the result into agent.WithConfig.
func Load ¶
func Load(opts LoadOptions) (*Config, error)
Load parses env vars + the per-user YAML and returns a populated Config. Each LoadOptions field has a sensible default (see LoadOptions doc).
Unlike LoadDefault, Load returns an error instead of calling os.Exit so downstream hosts can surface it through their own error path.
Example ¶
ExampleLoad demonstrates the canonical downstream-app load: pick an AppName + AppHome, let Load auto-create the YAML on first run, and trust the returned *Config from then on.
AppName drives the AppHome layout (~/.{AppName}/) AND the first-run YAML's `default_profile` value — running this with AppName="friday" stamps `default_profile: friday`, not "evva" (Phase 19b).
package main
import (
"fmt"
"path/filepath"
"strings"
"github.com/johnny1110/evva/pkg/config"
)
func main() {
tmp, _ := filepath.Abs("/tmp/evva-example-load")
cfg, err := config.Load(config.LoadOptions{
AppName: "friday",
AppHome: tmp,
WorkDir: tmp + "/work",
})
if err != nil {
fmt.Println("error:", err)
return
}
fmt.Println("app:", cfg.AppName)
fmt.Println("default_profile:", cfg.DefaultProfile)
fmt.Println("config_file_endswith:", strings.HasSuffix(cfg.AppHomeConfigFile, "friday-config.yml"))
}
Output: app: friday default_profile: friday config_file_endswith: true
func LoadDefault ¶
func LoadDefault() *Config
LoadDefault returns a Config populated with evva's historical defaults: AppName="evva", AppHome=~/.evva/, WorkDir=os.Getwd(). Intended for the bundled cmd/evva binary and for backward-compatible callers.
Startup failures (missing/invalid YAML, unknown provider/model) bail with os.Exit so the user gets a clear single-line error rather than a panic stack from deep inside the agent boot path.
func (*Config) Clone ¶
Clone returns a shallow copy of c with fresh mutexes. Used by callers that need to override a small subset of fields (notably WorkDir) for a scoped agent — the AgentTool isolation path does this so a subagent can run with cfg.WorkDir = <worktree path> while the parent keeps its own. The copy reads through c.mu so concurrent mutations don't tear across fields.
"Shallow" — the LLMProviderConfig map is reused by reference. That's safe today because providers are loaded once at boot and never mutated after; if that invariant ever changes, this method should deep-copy the map.
func (*Config) DeleteCustom ¶
DeleteCustom removes key from CustomConfig and persists. A missing key is a no-op (no error). Persists via SaveFile so the YAML reflects the removal immediately.
func (*Config) GetAutoCompactThreshold ¶
GetAutoCompactThreshold returns the current threshold under the read lock. compact.go reads this every turn.
func (*Config) GetCustom ¶
GetCustom returns the value stored under key in CustomConfig. ok=false when the key is absent. Reads under c.mu.RLock.
Values are stored as `any` — cast at use-site. After a YAML reload the concrete type is whatever yaml.v3 decoded into (typically string, int, float64, bool, []any, or map[string]any). Round-tripping through SaveFile is lossy for typed Go structs unless the caller (or yaml tags on a value-type) preserves the shape.
func (*Config) GetDisplayThinking ¶
GetDisplayThinking returns the current DisplayThinking flag under the read lock. Agent code reads this every turn (state_machine.go, stream.go); the UI may write it via /config.
func (*Config) GetEnableAutoMemory ¶
GetEnableAutoMemory returns the auto-memory flag under the read lock. Read by agent.Main (to decide whether to attach the memory tools) and by the sysprompt builder (to decide whether to inject the auto-memory guidance section).
func (*Config) IsDevelopment ¶
IsDevelopment / IsProduction — semantic helpers so call sites don't hardcode string literals scattered across the codebase.
func (*Config) IsProduction ¶
func (*Config) LLMTemperature ¶
LLMTemperature returns the current temperature or nil (provider default).
func (*Config) SaveFile ¶
SaveFile re-serializes the user-tunable subset to AppHomeConfigFile. The /config setters and the runtime /model switch both call this.
Snapshots all fields under c.mu.RLock, releases that lock before blocking on disk I/O, then takes c.saveMu so concurrent saves don't interleave on the file.
func (*Config) SetAutoCompactThreshold ¶
SetAutoCompactThreshold validates 0 < v <= 1 and persists.
func (*Config) SetCustom ¶
SetCustom stores value under key in CustomConfig and persists the change to AppHomeConfigFile via SaveFile. An empty key is rejected.
Nil values are stored as-is — call DeleteCustom to remove the entry. Concurrent SetCustom calls are serialized by c.mu.
Example ¶
ExampleConfig_SetCustom shows the CustomConfig extension slot. Use it for downstream-private settings that don't fit the typed Config fields (broker URLs, feature flags, tenant secrets). Values round-trip through YAML as a `custom:` section under the AppHome config file; consumers cast at use-site.
package main
import (
"fmt"
"path/filepath"
"github.com/johnny1110/evva/pkg/config"
)
func main() {
tmp, _ := filepath.Abs("/tmp/evva-example-custom")
cfg, _ := config.Load(config.LoadOptions{
AppName: "friday", AppHome: tmp, WorkDir: tmp,
})
_ = cfg.SetCustom("broker.url", "https://broker.internal")
_ = cfg.SetCustom("flags", map[string]any{"beta_ui": true})
if v, ok := cfg.GetCustom("broker.url"); ok {
fmt.Println("broker:", v.(string))
}
if v, ok := cfg.GetCustom("flags"); ok {
fmt.Println("beta_ui:", v.(map[string]any)["beta_ui"])
}
}
Output: broker: https://broker.internal beta_ui: true
func (*Config) SetDefaultEffort ¶
SetDefaultEffort validates the effort level name and persists it.
func (*Config) SetDefaultModel ¶
SetDefaultModel updates the (provider, model) pair the agent boots with and persists it. Phase-3's runtime /model swap calls this after rebuilding the Agent's llm.Client so next launch starts with the user's last choice. Validates that the model is actually offered by the provider.
func (*Config) SetDefaultProfile ¶
SetDefaultProfile persists the chosen persona name. Validation against the agent registry happens at the call site (AgentRegistry lives in internal/agent, which can't be imported from config without a cycle). Empty string is accepted — bootstrap interprets "" as "fall back to evva".
func (*Config) SetDisplayThinking ¶
SetDisplayThinking mutates the in-memory flag and persists to disk.
func (*Config) SetEnableAutoMemory ¶
SetEnableAutoMemory toggles the auto-memory subsystem and persists. Takes effect for the prompt and tool registration on next agent boot.
func (*Config) SetFetchMaxBytes ¶
SetFetchMaxBytes validates > 0 and persists.
func (*Config) SetLLMTemperature ¶
SetLLMTemperature updates the session-only temperature. nil clears it (provider default). Validates 0 ≤ v ≤ 2. Never persisted to disk.
func (*Config) SetLLMTopK ¶
SetLLMTopK updates the session-only top_k. nil clears it (provider default). Validates v > 0. Never persisted to disk.
func (*Config) SetLLMTopP ¶
SetLLMTopP updates the session-only top_p. nil clears it (provider default). Validates 0 ≤ v ≤ 1. Never persisted to disk.
func (*Config) SetMaxIterations ¶
SetMaxIterations validates >0 and persists. NOTE: this only updates the YAML default; the live cap on a running agent is on Agent itself — call Controller.SetMaxIterations to mutate it.
func (*Config) SetMaxTokens ¶
SetMaxTokens validates >=0 and persists. 0 means "provider default". Effective on next launch — the agent's profile snapshots this at construction.
func (*Config) SetProviderAPIKey ¶
SetProviderAPIKey installs an api key for the named provider and persists. Empty key removes the provider from LLMProviderConfig (cloud providers require a key to be listed). The constant.LLMProvider must already be known.
func (*Config) SetProviderAPIURL ¶
SetProviderAPIURL overrides the api_url for the named provider. Empty resets to the provider's built-in default.
func (*Config) SetProviderCredentials ¶
SetProviderCredentials writes the (apiURL, apiKey) pair for the named LLM provider into Config.LLMProviderConfig under the mutex.
This is the documented path for downstream apps to install credentials at runtime — direct map assignment (`cfg.LLMProviderConfig["deepseek"] = ...`) still works but races with concurrent reads. SetProviderCredentials takes c.mu so two goroutines wiring different providers at startup don't tear.
An empty name is rejected. Unknown provider names are NOT rejected: downstream apps register custom providers into pkg/llm's registry without touching constant, and the agent's LLM-build step will surface the typo if no factory matches. apiURL may be empty — providers with a sane default (DeepSeek, Anthropic) fall back to it. apiKey may be empty for local providers (Ollama, ...).
Models on the existing APIConfig (if any) are preserved. Pass through the public map slot when a custom Models list is also needed.
Example ¶
ExampleConfig_SetProviderCredentials shows the Phase 19b thread-safe setter for LLM credentials. Prefer this over direct map assignment when wiring providers at runtime — direct writes race concurrent reads on the same *Config.
package main
import (
"fmt"
"path/filepath"
"github.com/johnny1110/evva/pkg/config"
)
func main() {
tmp, _ := filepath.Abs("/tmp/evva-example-creds")
cfg, _ := config.Load(config.LoadOptions{
AppName: "alpha", AppHome: tmp, WorkDir: tmp,
})
if err := cfg.SetProviderCredentials(
"deepseek",
"https://api.deepseek.com",
"sk-example-key",
); err != nil {
fmt.Println("error:", err)
return
}
got := cfg.LLMProviderConfig["deepseek"]
fmt.Println("api_url:", got.ApiURL)
fmt.Println("api_secret_present:", got.ApiSecret != "")
}
Output: api_url: https://api.deepseek.com api_secret_present: true
func (*Config) SetTavilyAPIKey ¶
SetTavilyAPIKey persists the key. Empty string disables web_search.
type EnvOverride ¶
EnvOverride is one entry in LoadOptions.EnvOverrides. The Name is used only for diagnostics — when Fn returns an error, Load wraps it as `config: EnvOverrides[<Name>]: <err>` so the failing override is identifiable in logs without re-running Load.
type FileConfig ¶
type FileConfig struct {
MaxIterations int `yaml:"max_iterations"`
MaxTokens int `yaml:"max_tokens"`
AutoCompactThreshold float64 `yaml:"auto_compact_threshold"`
DisplayThinking bool `yaml:"display_thinking"`
// DefaultProvider / DefaultModel are the (provider, model) pair the
// agent boots with. Phase 3's /model switch will mutate these and call
// Save to persist across launches.
DefaultProvider string `yaml:"default_provider"`
DefaultModel string `yaml:"default_model"`
DefaultEffort string `yaml:"default_effort"`
// DefaultProfile is the persona the root agent boots into. Phase 6's
// /profile switch mutates this and calls Save to persist across launches.
// Empty falls back to "evva" at bootstrap.
DefaultProfile string `yaml:"default_profile"`
// PermissionMode is the agent's startup stance. One of:
// "default" | "accept_edits" | "plan" | "bypass" | "auto". Defaults to
// "default" when omitted. The -permission-mode CLI flag overrides this.
PermissionMode string `yaml:"permission_mode"`
FetchMaxBytes int `yaml:"fetch_max_bytes"`
TavilyAPIKey string `yaml:"tavily_api_key"`
// EnableAutoMemory gates the auto-memory subsystem (update_user_profile,
// update_project_memory tools + the per-session prompt section). Default
// true; users opt out via /config or by setting this to false. Pointer so
// missing-key in YAML preserves the default rather than zeroing.
EnableAutoMemory *bool `yaml:"enable_auto_memory,omitempty"`
Providers map[string]FileProviderConfig `yaml:"providers"`
// Custom is the downstream-app extension slot. Values round-trip through
// YAML as the `custom:` section. Empty / nil produces no `custom:` key in
// the output. Decoded as map[string]any — consumers cast at use-site.
Custom map[string]any `yaml:"custom,omitempty"`
}
FileConfig is the on-disk schema for $EvvaHome/config/evva-config.yml. It owns the user-tunable subset of configuration; deployment knobs (LOG_LEVEL, APP_ENV, ...) stay in .env.
func LoadFileConfig ¶
func LoadFileConfig(path, appName string) (FileConfig, bool, error)
LoadFileConfig reads the YAML at path. On first launch (file absent) it writes a default YAML whose default_profile is the caller's appName — so a friday-flavoured Load writes "default_profile: friday" instead of bleeding evva's persona into a sibling app's config.
Returns (cfg, created, err):
- created=true means the file didn't exist and was just written with defaults; callers can use this to surface a one-time first-launch notice.
- Missing keys in an existing file fall back to defaultFileConfig values via pre-population, so partial YAML never crashes startup.
type FileProviderConfig ¶
FileProviderConfig carries per-provider credentials. Empty ApiURL falls back to the constant's built-in default.
type LoadOptions ¶
type LoadOptions struct {
AppName string // brand identifier; drives the AppHome layout. Defaults to "evva".
AppHome string // absolute path; defaults to ~/.<AppName>/.
WorkDir string // process cwd; defaults to os.Getwd().
AppVersion string // version string for diagnostics; defaults to DefaultAppVersion.
// EnvAliases maps the caller's preferred env-var names onto evva's
// canonical ones BEFORE godotenv.Load runs. Useful when a downstream
// app advertises friendlier spellings — e.g. `{"LOGDIR": "LOG_DIR",
// "LOGLEVEL": "LOG_LEVEL"}` lets a friday user write either form in
// `~/.friday/.env` and have evva's loader pick it up.
//
// The promotion is non-overriding: an alias only seeds the canonical
// name when that canonical name is unset. Existing canonical exports
// win, so a deliberate `LOG_DIR=...` is never clobbered by a stray
// alias.
EnvAliases map[string]string
// EnvOverrides runs AFTER the YAML + canonical env-vars have built
// the Config. Each entry gets the populated *Config and can fold in
// env vars that don't have a native hook inside Load (e.g.
// MAX_ITERS → cfg.SetMaxIterations). The first error short-circuits
// the rest and is returned from Load wrapped with the failing
// override's Name — `config: EnvOverrides[<name>]: <wrapped>` — so
// a downstream app with several overrides can identify the culprit
// without grepping stack traces.
//
// Use this to translate downstream-flavoured env conventions
// (APIKEY → cfg.SetProviderCredentials, MAX_ITERS → cfg.SetMaxIterations)
// in one place instead of post-Load shim code at every call site.
EnvOverrides []EnvOverride
// ProviderCredentials wires LLM provider credentials from env vars
// declaratively — the alternative to writing a separate EnvOverride
// that reads os.Getenv(...) and calls cfg.SetProviderCredentials.
//
// Keyed by provider name (matches pkg/llm.DefaultRegistry); the
// ProviderCredsFromEnv value names the env vars to read. EnvAliases
// promotion runs first, so aliased names (e.g. `APIKEY` → `DEEPSEEK_API_KEY`)
// reach this layer through their canonical form. Empty env-var values
// are passed through to SetProviderCredentials — the agent's LLM-build
// step will surface "API_KEY not set" loudly on first Run.
//
// Example:
//
// LoadOptions{
// ProviderCredentials: map[string]config.ProviderCredsFromEnv{
// "deepseek": {APIKeyEnv: "DEEPSEEK_API_KEY",
// APIURLDefault: constant.DEEPSEEK.ApiUrl},
// },
// }
//
// Applied AFTER the YAML loader populates LLMProviderConfig but
// BEFORE EnvOverrides run, so an EnvOverride can still mutate the
// installed creds if it needs to.
ProviderCredentials map[string]ProviderCredsFromEnv
// SeedEnvTemplate is written to <AppHome>/.env on first launch when
// the file is missing. Useful for closing the "evva creates the YAML
// but the user doesn't know to create .env" first-run gap.
//
// Empty means "don't write a .env template" (the historical behaviour).
// An existing .env is never overwritten, even with SeedEnvTemplate set.
SeedEnvTemplate string
}
LoadOptions tunes Load. Zero-value fields fall back to LoadDefault behavior — AppName="evva", AppHome=~/.evva/, WorkDir=os.Getwd(), AppVersion=DefaultAppVersion. Downstream apps that want a different home dir or app name fill in the relevant fields.
type ProviderCredsFromEnv ¶
type ProviderCredsFromEnv struct {
// APIKeyEnv is the env-var name carrying the provider's API key
// (e.g. "DEEPSEEK_API_KEY"). Empty means "no key from env".
APIKeyEnv string
// APIURLEnv is the env-var name carrying the provider's API URL.
// Most consumers leave this empty and lean on APIURLDefault.
APIURLEnv string
// APIURLDefault is the URL to use when APIURLEnv is empty or unset.
// Typically a constant from pkg/constant (e.g. constant.DEEPSEEK.ApiUrl).
APIURLDefault string
}
ProviderCredsFromEnv declares which env vars carry a provider's credentials. Empty fields are skipped (the YAML default wins for that slot). See LoadOptions.ProviderCredentials.