Documentation
¶
Overview ¶
Package config provides configuration management for Celeste CLI.
Package config provides configuration management for Celeste CLI. This file handles session persistence (conversation history).
Package config — personality slider persistence.
Sliders modulate Celeste's voice inside whatever register is active. They do NOT select registers, override invariants, or touch canonical collection files. They compose ON TOP of the persona baseline at position 6 in the assembly order (after voice_and_tone, before active register body).
Persistence: ~/.celeste/slider.yaml (or slider.json — we use JSON to match the existing config pattern). Loaded at startup, written on every slider change via the /persona TUI panel.
Package config provides configuration management for Celeste CLI. This file provides thin wrappers around ctxmgr for token estimation and model limit queries. Session-specific helpers that depend on config types (SessionMessage, Session) remain here.
Package config — user identity persistence.
Stores who Celeste is currently talking to so she calibrates her relationship dynamic appropriately. Without this, she defaults to addressing everyone as Kusanagi (twin/Onii-chan), which is wrong for other users.
Persistence: ~/.celeste/user.json Set via: /user <name> in TUI, or edit the file directly.
Index ¶
- Constants
- Variables
- func ApplyEnvOverrides(cfg *Config)
- func CalculateCost(model string, inputTokens, outputTokens int) float64
- func CheckHome() error
- func DefaultModelForBaseURL(baseURL string) string
- func EnableLocalWindowProbe()
- func EstimateMessageTokens(msg SessionMessage) int
- func EstimateSessionTokens(session *Session) int
- func EstimateSessionTokensByRole(session *Session) (int, int, int)
- func EstimateTokens(text string) int
- func FormatCost(cost float64) string
- func FormatNumber(n int) string
- func FormatTokenCount(tokens int) string
- func GenerateNameFromMessage(content string) string
- func GetAnalyticsPath() string
- func GetExportDir() string
- func HomeDir() (string, error)
- func ListConfigs() ([]string, error)
- func LocalWindowNoWait(on bool, onChange func())
- func LookupModelLimit(model string) (int, bool)
- func MigrateConfigDir()
- func NamedConfigPath(name string) string
- func Paths() (configDir, configFile, secretsFile, skillsFile string)
- func ProbeLocalWindow(ctx context.Context, hc *http.Client, baseURL, apiKey, model string) int
- func RedactSecretCommand(line string) string
- func ResolveContextLimit(baseURL, model string, override int, apiKey string) (limit int, known bool)
- func ResolveContextLimitSource(baseURL, model string, override int, apiKey string) (int, string)
- func ResolveDefaultName() string
- func SameProject(a, b string) bool
- func Save(config *Config) error
- func SaveCollections(cfg *Config) error
- func SaveNamed(name string, config *Config) error
- func SaveSecrets(config *Config) error
- func SaveSkillsConfig(skillsConfig *Config) error
- func SetDefaultProfile(name string) error
- func SetLocalWindowProbe(fn func(baseURL, apiKey, model string) int)
- func SliderPath() string
- func SnapToAnchor(value int) int
- func UniqueNanoID() string
- func UnknownContextNotice(model string, limit int) string
- func UserPath() string
- func ValidateProfileName(name string) error
- func WebFetchPrivateAllowed() bool
- func WorkspaceConfigPath(workspace string) string
- type AlchemyConfig
- type BlockmonConfig
- type CollectionsConfig
- type Config
- func (c *Config) CompletionGateMode() string
- func (c *Config) GetFirstByteTimeout() time.Duration
- func (c *Config) GetTimeout() time.Duration
- func (c *Config) JevGateMode() string
- func (c *Config) JevPruneMode() string
- func (c *Config) JevRouteMode() string
- func (c *Config) ModelPinned() bool
- func (c *Config) OracleMode() string
- func (c *Config) ResolveAgentModel() string
- func (c *Config) ResolveServedModel(ctx context.Context, baseURL, apiKey, model string) (resolved, note string)
- func (c *Config) ResolveServedModels(ctx context.Context) (notes []string)
- func (c *Config) ResolveServedModelsCached() (notes []string, pending bool)
- func (c *Config) ResolveSmallModel() string
- func (c *Config) StreamRulesMode() string
- func (c *Config) WatchdogMode() string
- type ConfigLoader
- func (l *ConfigLoader) GetAlchemyConfig() (AlchemyConfig, error)
- func (l *ConfigLoader) GetBlockmonConfig() (BlockmonConfig, error)
- func (l *ConfigLoader) GetIPFSConfig() (IPFSConfig, error)
- func (l *ConfigLoader) GetTarotConfig() (TarotConfig, error)
- func (l *ConfigLoader) GetTwitchConfig() (TwitchConfig, error)
- func (l *ConfigLoader) GetVeniceConfig() (VeniceConfig, error)
- func (l *ConfigLoader) GetWalletSecurityConfig() (WalletSecuritySettingsConfig, error)
- func (l *ConfigLoader) GetWeatherConfig() (WeatherConfig, error)
- func (l *ConfigLoader) GetYouTubeConfig() (YouTubeConfig, error)
- type ContextTracker
- func (ct *ContextTracker) EstimateMessagesUntilLimit(avgTokensPerMsg int) int
- func (ct *ContextTracker) GetContextSummary() string
- func (ct *ContextTracker) GetRemainingTokens() int
- func (ct *ContextTracker) GetUsagePercentage() float64
- func (ct *ContextTracker) GetWarningLevel() string
- func (ct *ContextTracker) ShouldCompact() bool
- func (ct *ContextTracker) UpdateTokens(prompt, completion, total int)
- type DailyStats
- type Exporter
- type GlobalAnalytics
- type IPFSConfig
- type LaneConfig
- type ModelStats
- type OrchestratorConfig
- type PricingTier
- type ProviderBlocks
- type ProviderStats
- type Sandbox
- type Session
- func (s *Session) ClearMessages()
- func (s *Session) GetCommandHistory() []string
- func (s *Session) GetEndpoint() string
- func (s *Session) GetMessages() []SessionMessage
- func (s *Session) GetMessagesRaw() interface{}
- func (s *Session) GetModel() string
- func (s *Session) GetModelPinned() bool
- func (s *Session) GetModelUnverified() bool
- func (s *Session) GetNSFWMode() bool
- func (s *Session) GetProvider() string
- func (s *Session) GetWorkspace() string
- func (s *Session) InitializeUsageMetrics()
- func (s *Session) SetCommandHistory(history []string)
- func (s *Session) SetEndpoint(endpoint string)
- func (s *Session) SetMessagesRaw(msgs interface{})
- func (s *Session) SetModel(model string)
- func (s *Session) SetModelPinned(pinned bool)
- func (s *Session) SetModelUnverified(unverified bool)
- func (s *Session) SetNSFWMode(enabled bool)
- func (s *Session) SetName(name string)
- func (s *Session) SetWorkspace(ws string)
- func (s *Session) Summarize() SessionSummary
- func (s *Session) SummarizeRaw() interface{}
- func (s *Session) UpdateUsageMetrics(inputTokens, outputTokens int)
- type SessionManager
- func (m *SessionManager) AddMessage(session *Session, role, content string)
- func (m *SessionManager) AddMessageWithTokens(session *Session, role, content string, inputTokens, outputTokens int)
- func (m *SessionManager) Clear() error
- func (m *SessionManager) Delete(id string) error
- func (m *SessionManager) GetCurrentID() string
- func (m *SessionManager) List() ([]Session, error)
- func (m *SessionManager) Load(id string) (*Session, error)
- func (m *SessionManager) LoadLatest() (*Session, error)
- func (m *SessionManager) MergeSessions(session1, session2 *Session) *Session
- func (m *SessionManager) NewSession() *Session
- func (m *SessionManager) Save(session *Session) error
- type SessionMessage
- type SessionSummary
- type SessionToolCall
- type SliderConfig
- type SliderPreset
- type TarotConfig
- type TwitchConfig
- type UsageMetrics
- type UserIdentity
- type VeniceConfig
- type WalletSecuritySettingsConfig
- type WeatherConfig
- type XAIFeaturesConfig
- type YouTubeConfig
Constants ¶
const ( EnvAPIKey = "CELESTE_API_KEY" EnvAPIEndpoint = "CELESTE_API_ENDPOINT" EnvTarotToken = "TAROT_AUTH_TOKEN" )
Environment overrides. Precedence is environment > config file. They apply to this run only: ApplyEnvOverrides is called by the entry points that run a session (chat, message, agent, serve), never by the loads that are saved back, so a variable's value is never written to disk.
const ( ModeOff = "off" ModeShadow = "shadow" // ask and log, never act ModeOn = "on" )
Steering modes (2.0 W3, #175). Every mechanism is off or in shadow mode by default and fails open; an unknown value is the default.
const ( SourceConfigured = "configured" SourceReported = "reported by the server" SourceModel = "model default" SourceFallback = "fallback" )
Where ResolveContextLimitSource's window came from.
const DefaultMaxToolIterations = 25
DefaultMaxToolIterations is the chat's turn cap (#144 renamed it from claw_max_tool_iterations; migrate.go maps the old key).
const DefaultProvider = "sakana"
DefaultProvider seeds a brand-new install that has no config file yet. It only names a provider in the registry — the BaseURL and model come from there, so retiring/renaming a model is a one-line registry edit, never a hunt across config.go, main.go templates, and the registry that diverge over time.
const DefaultTimeoutSeconds = 60
DefaultTimeoutSeconds is the request timeout a new profile gets: how long a request may receive nothing from the provider before it fails.
const DefaultTypingSpeed = 60
DefaultTypingSpeed is typing_speed's default, in characters per second (3 characters per 50ms animation tick).
const LocalFirstByteSeconds = 1800
LocalFirstByteSeconds is how long a request to a local server may wait for the first byte of the reply (GetFirstByteTimeout). Prefill sends nothing: on a loaded machine a 32K prompt on a 14B model took ~563 s to the first byte, and a full re-prefill after plan mode 11.5 min (#359).
const LocalTimeoutSeconds = 600
LocalTimeoutSeconds replaces DefaultTimeoutSeconds for a server on this machine or the local network (providers.IsLocalEndpoint). A local model sends nothing while it reads the prompt: a cold 16K-token first turn on a 14B model took longer than 300 s.
const WebFetchAllowPrivateEnv = "CELESTE_WEB_FETCH_ALLOW_PRIVATE"
WebFetchAllowPrivateEnv set to 1 lets web_fetch reach non-public addresses.
Variables ¶
var ErrNoHome = errors.New("no home directory: set HOME (USERPROFILE on Windows) to an absolute path")
ErrNoHome is HomeDir's error when there is no usable home directory.
MigrationWarn prints the one-line note for each migrated key. Tests replace it.
var ModelLimits = ctxmgr.ModelLimits
ModelLimits is kept as an alias for backward compatibility. Canonical data lives in ctxmgr.ModelLimits.
var ModelPricing = map[string]PricingTier{
"gpt-4.1-nano": {0.15, 0.60},
"grok-build-0.1": {1.00, 2.00},
"grok-4-1-fast": {0.20, 0.50},
"claude-sonnet-4": {3.00, 15.00},
"gemini-2.0-flash": {0.10, 0.40},
"venice-uncensored": {0.20, 0.90},
}
ModelPricing is the legacy pricing table for backwards compatibility. The canonical pricing source is costs/pricing.go (costs.ModelPricing). This table is used by the stats dashboard for historical cost estimates.
Functions ¶
func ApplyEnvOverrides ¶
func ApplyEnvOverrides(cfg *Config)
ApplyEnvOverrides lets CELESTE_API_KEY, CELESTE_API_ENDPOINT and TAROT_AUTH_TOKEN replace the loaded api_key, base_url and tarot_auth_token. An unset or blank variable changes nothing.
func CalculateCost ¶
CalculateCost calculates the estimated cost based on token usage and model pricing
func CheckHome ¶
func CheckHome() error
CheckHome is HomeDir's check for the start of a celeste command.
func DefaultModelForBaseURL ¶
DefaultModelForBaseURL resolves the default model for a config from its own provider (detected via the registry), falling back to the seed provider's model when the URL is unknown. This is the dynamic resolution that replaces a hard-coded model string.
func EnableLocalWindowProbe ¶
func EnableLocalWindowProbe()
EnableLocalWindowProbe installs the caching HTTP probe.
func EstimateMessageTokens ¶
func EstimateMessageTokens(msg SessionMessage) int
EstimateMessageTokens counts tokens in a message.
func EstimateSessionTokens ¶
EstimateSessionTokens counts total tokens in session.
func EstimateSessionTokensByRole ¶
EstimateSessionTokensByRole calculates separate input/output token counts. Returns (promptTokens, completionTokens, totalTokens).
func EstimateTokens ¶
EstimateTokens approximates token count (delegates to ctxmgr).
func FormatCost ¶
FormatCost formats a cost value as a currency string
func FormatNumber ¶
FormatNumber formats a number with thousand separators
func FormatTokenCount ¶
FormatTokenCount formats token count with K/M suffix (delegates to ctxmgr).
func GenerateNameFromMessage ¶
GenerateNameFromMessage creates a session name from first user message. Extracts first 40-50 chars, intelligently truncates at word boundary.
func GetAnalyticsPath ¶
func GetAnalyticsPath() string
GetAnalyticsPath returns the path to the analytics file
func GetExportDir ¶
func GetExportDir() string
GetExportDir returns the path to the exports directory
func HomeDir ¶
HomeDir returns the user's home directory, or ErrNoHome when it is unset, empty or relative. It fails closed: joining ".celeste" onto an empty or relative home would read config, skills, hooks and permission rules from the current directory, which may be an untrusted checkout.
func ListConfigs ¶
ListConfigs returns all available config names.
func LocalWindowNoWait ¶
func LocalWindowNoWait(on bool, onChange func())
LocalWindowNoWait switches the installed probe to never wait (on) or back. The TUI turns it on once its prompt is composed: its Update and View must do no I/O, so an endpoint the probe has no answer for yet gets the fallback at once, the server is asked in the background, and onChange runs (on that goroutine) when an answer changes a window.
func LookupModelLimit ¶
LookupModelLimit reports the limit and whether the model is known (delegates to ctxmgr). Callers validating a user-configured window need the second value: for an unknown model the limit is a fallback, not knowledge.
func MigrateConfigDir ¶
func MigrateConfigDir()
MigrateConfigDir migrates every config*.json profile in the config directory once, up front. Call it from the chat startup path before the Bubble Tea alt screen opens (main.go's runChatTUI): by the time a running chat switches profiles (/endpoint, SwitchEndpoint), every file is already migrated, so migrateFile is a no-op instead of printing notes into the alt screen on every switch (#144 W6b review, I1(a)). Notes still go to MigrationWarn, which is stderr at this point — the alt screen isn't open yet. Load and LoadNamed still call migrateFile defensively; this just does the work for every profile before either of them needs to.
func NamedConfigPath ¶
NamedConfigPath returns the path for a named config file. If name is empty, returns the default config path.
func Paths ¶
func Paths() (configDir, configFile, secretsFile, skillsFile string)
Paths returns the configuration directory and file paths.
func ProbeLocalWindow ¶
ProbeLocalWindow asks the server at baseURL (an OpenAI-compatible base, usually ending in /v1) for the context window it runs model with, and returns 0 when it does not say. apiKey, when set, is sent as a Bearer token (a llama.cpp or LM Studio server started with a key answers only with it); callers send it to a local host only. It tries Ollama's running models and the model's num_ctx, llama.cpp's /props, then LM Studio's model entry. A model's trained maximum (Ollama's model_info, LM Studio's max_context_length) is never used: the server runs it with less.
func RedactSecretCommand ¶
RedactSecretCommand returns line with the key of a set-key command replaced by ***, and any other line unchanged. Input history, which is saved with the session and its exports, keeps only the redacted form.
func ResolveContextLimit ¶
func ResolveContextLimit(baseURL, model string, override int, apiKey string) (limit int, known bool)
ResolveContextLimit returns the effective context window and whether that number is actually knowledge.
An explicit override always wins. A local endpoint whose server reports its window (the probe EnableLocalWindowProbe installs) gets that. Otherwise local endpoints get ctxmgr.LocalDefaultLimit even when the model name is in the table: a local server names its model whatever it likes, so a hit is coincidence. That mattered in practice — a fresh profile inherits the seed default's model (fugu), so pointing it at a local server produced a confident 1,000,000-token budget for a server that might have 8k. Unknown hosted models get the table's 128k default (#201).
func ResolveContextLimitSource ¶
ResolveContextLimitSource is ResolveContextLimit with where the number came from (`celeste config` shows it). apiKey is the endpoint's key: a local server started with one answers the probe only with it.
func ResolveDefaultName ¶
func ResolveDefaultName() string
ResolveDefaultName returns the name of the config.<name>.json file flagged "default": true, or "" if none is flagged (or the dir is unreadable). Files are scanned in directory order; the first match wins.
func SameProject ¶
SameProject reports whether two workspaces are the same project: the same git root, or the same directory when neither is in a repository (2.0 W4 ruling 1). An empty workspace is no project.
func SaveCollections ¶
SaveCollections writes cfg's collections block back to the file cfg was loaded from: the named profile LoadNamed read, or config.json. Only the "collections" key changes; every other key stays as the file has it, so nothing a load merged in (config.json's sandbox, skills.json and secrets.json values, defaults) is copied into the wrong file (#324).
func SaveNamed ¶
SaveNamed writes the config to a named profile file (config.<name>.json). Named profiles store everything inline, including the API key — that is how LoadNamed reads them — so unlike Save there is no separate secrets file. An empty name falls back to the default Save path.
func SaveSecrets ¶
SaveSecrets saves API key to secrets file (backward compatibility).
func SaveSkillsConfig ¶
SaveSkillsConfig saves skill-specific configuration to skills.json.
func SetDefaultProfile ¶
SetDefaultProfile marks config.<name>.json as the default profile and clears the flag on every other named profile, so exactly one stays flagged.
func SetLocalWindowProbe ¶
SetLocalWindowProbe installs fn as the probe ResolveContextLimit asks about a local endpoint with no context_limit; nil removes it. fn returns the window in tokens, or 0 when the server did not say.
func SnapToAnchor ¶
SnapToAnchor returns the nearest anchor index (0-3) for a slider value 0-10. Anchors are at 0, 3, 7, 10.
func UniqueNanoID ¶
func UniqueNanoID() string
UniqueNanoID is the current time in nanoseconds from clock.Now, which never repeats in this process: Windows' clock is coarse, and two sessions with one ID overwrite each other's file.
func UnknownContextNotice ¶
UnknownContextNotice returns the one-time warning for a model whose window was guessed, and "" on every later call for the same model (#201).
func ValidateProfileName ¶
ValidateProfileName reports whether name can name a profile file, config.<name>.json in ~/.celeste: a plain file-name part, with no path separator, drive or stream colon, NUL, or dot segment. A name read from elsewhere (a resumed session's endpoint) otherwise could load or write a file outside the config directory.
func WebFetchPrivateAllowed ¶
func WebFetchPrivateAllowed() bool
WebFetchPrivateAllowed reports whether web_fetch may reach loopback, private-network, link-local and other non-public addresses: CELESTE_WEB_FETCH_ALLOW_PRIVATE=1, or "web_fetch_allow_private": true in the config this session was started with.
func WorkspaceConfigPath ¶
WorkspaceConfigPath is a workspace's own config file.
Types ¶
type AlchemyConfig ¶
AlchemyConfig holds Alchemy API configuration.
type BlockmonConfig ¶
type BlockmonConfig struct {
AlchemyAPIKey string
WebhookURL string
DefaultNetwork string
PollIntervalSeconds int
}
BlockmonConfig holds blockchain monitoring configuration.
type CollectionsConfig ¶
type CollectionsConfig struct {
Enabled bool `json:"enabled"`
ActiveCollections []string `json:"active_collections"`
AutoEnable bool `json:"auto_enable"`
}
CollectionsConfig holds collections settings
type Config ¶
type Config struct {
// API settings
APIKey string `json:"api_key"`
BaseURL string `json:"base_url"`
Model string `json:"model"`
// AgentModel is the model used for agent / orchestrate / subagent work
// (free tool-selection). Chat/TTS use Model. Empty falls back to Model.
// Lets you pin a reasoning/tool-capable model for agent work while keeping a
// cheap non-reasoning model for chat (model-router guardrail, task e8775b91).
AgentModel string `json:"agent_model,omitempty"`
// SmallModel is a cheaper model for housekeeping calls such as context
// compaction summaries (#174). Empty falls back to Model.
SmallModel string `json:"small_model,omitempty"`
// PinModel turns live model resolution off: the configured models are
// sent as written even if the provider no longer lists them. Same as
// CELESTE_PIN_MODEL=1.
PinModel bool `json:"pin_model,omitempty"`
// WebFetchAllowPrivate lets web_fetch reach loopback, private-network,
// link-local and other non-public addresses, which it refuses by default.
// For local docs servers. Same as CELESTE_WEB_FETCH_ALLOW_PRIVATE=1.
WebFetchAllowPrivate bool `json:"web_fetch_allow_private,omitempty"`
// JevPrune turns on TypeSafe Jev as a judge for context pruning (#175).
// "shadow" asks Jev in the background and only logs what it would have
// pruned; "on" (2.0 W3) elides the least-needed results first, asking
// Jev inside the loop (2.5 s cap, rules on any error); anything else is
// off. Redacted excerpts of old tool results go to TypeSafe. The key
// comes from TYPESAFE_API_KEY or ~/.celeste/typesafe.key.
JevPrune string `json:"jev_prune,omitempty"`
// JevGate asks Jev whether a tool call is destructive, exfiltrates data
// or goes beyond what was asked (2.0 W3): "shadow" logs, "on" turns an
// allowed call into an Ask (never the reverse). Off by default.
JevGate string `json:"jev_gate,omitempty"`
// JevRoute picks /orchestrate's lane with a Jev choice question (2.0
// W3): "shadow" logs, "on" uses it. Off by default.
JevRoute string `json:"jev_route,omitempty"`
// Oracle picks the judge for steering questions (2.0 W3):
// "heuristic" (default), "llm" (the small model) or "jev". The
// watchdog ballot asks it.
Oracle string `json:"oracle,omitempty"`
// StreamRules: "shadow" (default) matches stream rules and logs, "on"
// acts, "off" skips them (2.0 W3).
StreamRules string `json:"stream_rules,omitempty"`
// Watchdog: the ballot every 3 turns (2.0 W3): "off" (default),
// "shadow" (asked and logged) or "on" (steers).
Watchdog string `json:"watchdog,omitempty"`
// CompletionGate (agent runs, 2.0 W3): "shadow" (default) keeps the
// substring TASK_COMPLETE check and logs where the gate differs; "on"
// lets the gate decide.
CompletionGate string `json:"completion_gate,omitempty"`
Timeout int `json:"timeout"` // seconds
ContextLimit int `json:"context_limit,omitempty"` // Optional: Override context window size
// Google Cloud authentication (for Gemini/Vertex AI)
GoogleCredentialsFile string `json:"google_credentials_file,omitempty"` // Path to service account JSON file
GoogleUseADC bool `json:"google_use_adc,omitempty"` // Use Application Default Credentials
// Runtime-detected provider (not persisted to config file)
Provider string `json:"-"` // Detected from BaseURL at runtime
// Default marks this named config as the one loaded when no -config flag
// is given. Exactly one file should set it; the first match wins.
Default bool `json:"default,omitempty"`
// Confirm mode: when true, Celeste proposes actions before executing
// write/generate operations. When false, she auto-executes.
ConfirmActions bool `json:"confirm_actions,omitempty"`
// ElevenLabs TTS settings
ElevenLabsAPIKey string `json:"elevenlabs_api_key,omitempty"`
ElevenLabsVoiceID string `json:"elevenlabs_voice_id,omitempty"`
// Streaming settings
SimulateTyping bool `json:"simulate_typing"`
TypingSpeed int `json:"typing_speed"` // chars per second
// MaxToolIterations caps the model turns in one chat turn's tool loop.
MaxToolIterations int `json:"max_tool_iterations,omitempty"`
// Venice.ai settings (for NSFW mode)
VeniceAPIKey string `json:"venice_api_key,omitempty"`
VeniceBaseURL string `json:"venice_base_url,omitempty"`
VeniceModel string `json:"venice_model,omitempty"` // Chat model (venice-uncensored)
VeniceImageModel string `json:"venice_image_model,omitempty"` // Image model (lustify-sdxl)
// Tarot settings
TarotFunctionURL string `json:"tarot_function_url,omitempty"`
TarotAuthToken string `json:"tarot_auth_token,omitempty"`
// Twitter settings
TwitterBearerToken string `json:"twitter_bearer_token,omitempty"`
TwitterAPIKey string `json:"twitter_api_key,omitempty"`
TwitterAPISecret string `json:"twitter_api_secret,omitempty"`
TwitterAccessToken string `json:"twitter_access_token,omitempty"`
TwitterAccessTokenSecret string `json:"twitter_access_token_secret,omitempty"`
// Weather settings
WeatherDefaultZipCode string `json:"weather_default_zip_code,omitempty"`
// Twitch settings
TwitchClientID string `json:"twitch_client_id,omitempty"`
TwitchClientSecret string `json:"twitch_client_secret,omitempty"`
TwitchDefaultStreamer string `json:"twitch_default_streamer,omitempty"`
// YouTube settings
YouTubeAPIKey string `json:"youtube_api_key,omitempty"`
YouTubeDefaultChannel string `json:"youtube_default_channel,omitempty"`
// IPFS settings
IPFSProvider string `json:"ipfs_provider,omitempty"` // "infura", "pinata", "custom"
IPFSAPIKey string `json:"ipfs_api_key,omitempty"`
IPFSAPISecret string `json:"ipfs_api_secret,omitempty"`
IPFSProjectID string `json:"ipfs_project_id,omitempty"` // Infura specific
IPFSGatewayURL string `json:"ipfs_gateway_url,omitempty"`
IPFSTimeoutSeconds int `json:"ipfs_timeout_seconds,omitempty"`
// Alchemy settings
AlchemyAPIKey string `json:"alchemy_api_key,omitempty"`
AlchemyDefaultNetwork string `json:"alchemy_default_network,omitempty"`
AlchemyTimeoutSeconds int `json:"alchemy_timeout_seconds,omitempty"`
// Blockchain monitoring settings
BlockmonAlchemyAPIKey string `json:"blockmon_alchemy_api_key,omitempty"`
BlockmonWebhookURL string `json:"blockmon_webhook_url,omitempty"`
BlockmonDefaultNetwork string `json:"blockmon_default_network,omitempty"`
BlockmonPollIntervalSeconds int `json:"blockmon_poll_interval_seconds,omitempty"`
// Wallet security settings
WalletSecurityEnabled bool `json:"wallet_security_enabled,omitempty"`
WalletSecurityPollInterval int `json:"wallet_security_poll_interval,omitempty"` // seconds
WalletSecurityAlertLevel string `json:"wallet_security_alert_level,omitempty"` // "low", "medium", "high", "critical"
// Collections configuration (xAI only)
XAIManagementAPIKey string `json:"xai_management_api_key,omitempty"`
Collections *CollectionsConfig `json:"collections,omitempty"`
XAIFeatures *XAIFeaturesConfig `json:"xai_features,omitempty"`
// Orchestrator settings
Orchestrator *OrchestratorConfig `json:"orchestrator,omitempty"`
// Sandbox is the OS sandbox for bash (2.0 W4); see Sandbox.
Sandbox *Sandbox `json:"sandbox,omitempty"`
// contains filtered or unexported fields
}
Config holds all configuration for Celeste CLI.
func DefaultConfig ¶
func DefaultConfig() *Config
DefaultConfig returns a config with default values. Provider-specific bits (BaseURL, model) resolve from the provider registry rather than being pinned here; only behavioural defaults live in this struct.
func LoadNamed ¶
LoadNamed loads configuration from a named config file. If name is empty, loads the default config.
func LoadNamedWithEnv ¶
LoadNamedWithEnv is LoadNamed plus the environment overrides, for the entry points that run a session.
func LoadSkillsConfig ¶
LoadSkillsConfig loads skill-specific configuration from skills.json.
func (*Config) CompletionGateMode ¶
CompletionGateMode is completion_gate: "shadow" (default) keeps the substring TASK_COMPLETE check and logs where the gate disagrees, "on" lets the gate decide.
func (*Config) GetFirstByteTimeout ¶
GetFirstByteTimeout returns how long a request may wait for the first byte of the reply. For a local endpoint it is LocalFirstByteSeconds, or GetTimeout when that is longer; once data flows, GetTimeout applies between chunks. Hosted providers use GetTimeout for both.
func (*Config) GetTimeout ¶
GetTimeout returns the request timeout. It is a stall timeout: a request fails when nothing arrives for this long, however long the reply takes in all (llm.MaxRequestDuration bounds that). A local endpoint whose timeout is unset or still the generic default gets LocalTimeoutSeconds; any other value is the user's and is kept.
func (*Config) JevGateMode ¶
JevGateMode is jev_gate: "off" (default), "shadow" or "on".
func (*Config) JevPruneMode ¶
JevPruneMode is jev_prune: "off" (default), "shadow" or "on".
func (*Config) JevRouteMode ¶
JevRouteMode is jev_route: "off" (default), "shadow" or "on".
func (*Config) ModelPinned ¶
ModelPinned reports whether model resolution is off for this config: "pin_model": true in the config, or CELESTE_PIN_MODEL=1 in the environment. A pinned model is sent as configured, served or not.
func (*Config) OracleMode ¶
OracleMode is oracle: "heuristic" (default), "llm" or "jev".
func (*Config) ResolveAgentModel ¶
ResolveAgentModel returns the model to use for agent / orchestrate / subagent work: AgentModel if set, otherwise the chat Model. This is the router seam — callers entering agent mode use this instead of Model.
func (*Config) ResolveServedModel ¶
func (c *Config) ResolveServedModel(ctx context.Context, baseURL, apiKey, model string) (resolved, note string)
ResolveServedModel resolves one model on its own endpoint (an orchestrator lane's), unless this config pins models. It may block on the network.
func (*Config) ResolveServedModels ¶
ResolveServedModels replaces Model, AgentModel and SmallModel with what the provider serves now, but only those celeste is sure are gone (providers.ResolveFromMemory). It loads the provider's catalog first (the cache, or one bounded fetch) and checks unlisted models where the provider can answer, so it may block on the network. It changes this in-memory config only; nothing is saved. The notes say what was replaced.
func (*Config) ResolveServedModelsCached ¶
ResolveServedModelsCached is ResolveServedModels from what this process already knows, with no I/O, for the TUI's Update. pending is true when a ResolveServedModels (in a tea.Cmd) would know more.
func (*Config) ResolveSmallModel ¶
ResolveSmallModel returns the model for housekeeping calls (compaction summaries): SmallModel if set, otherwise the chat Model.
func (*Config) StreamRulesMode ¶
StreamRulesMode is stream_rules: "shadow" (default) matches and logs, "on" acts, "off" skips matching.
func (*Config) WatchdogMode ¶
WatchdogMode is watchdog: "off" (default), "shadow" or "on".
type ConfigLoader ¶
type ConfigLoader struct {
// contains filtered or unexported fields
}
ConfigLoader provides configuration values to tools.
func NewConfigLoader ¶
func NewConfigLoader(config *Config) *ConfigLoader
NewConfigLoader creates a new config loader.
func (*ConfigLoader) GetAlchemyConfig ¶
func (l *ConfigLoader) GetAlchemyConfig() (AlchemyConfig, error)
GetAlchemyConfig returns Alchemy API configuration.
func (*ConfigLoader) GetBlockmonConfig ¶
func (l *ConfigLoader) GetBlockmonConfig() (BlockmonConfig, error)
GetBlockmonConfig returns blockchain monitoring configuration.
func (*ConfigLoader) GetIPFSConfig ¶
func (l *ConfigLoader) GetIPFSConfig() (IPFSConfig, error)
GetIPFSConfig returns IPFS configuration.
func (*ConfigLoader) GetTarotConfig ¶
func (l *ConfigLoader) GetTarotConfig() (TarotConfig, error)
GetTarotConfig returns tarot configuration.
func (*ConfigLoader) GetTwitchConfig ¶
func (l *ConfigLoader) GetTwitchConfig() (TwitchConfig, error)
GetTwitchConfig returns Twitch API configuration.
func (*ConfigLoader) GetVeniceConfig ¶
func (l *ConfigLoader) GetVeniceConfig() (VeniceConfig, error)
GetVeniceConfig returns Venice.ai configuration.
func (*ConfigLoader) GetWalletSecurityConfig ¶
func (l *ConfigLoader) GetWalletSecurityConfig() (WalletSecuritySettingsConfig, error)
GetWalletSecurityConfig returns wallet security monitoring configuration.
func (*ConfigLoader) GetWeatherConfig ¶
func (l *ConfigLoader) GetWeatherConfig() (WeatherConfig, error)
GetWeatherConfig returns weather skill configuration.
func (*ConfigLoader) GetYouTubeConfig ¶
func (l *ConfigLoader) GetYouTubeConfig() (YouTubeConfig, error)
GetYouTubeConfig returns YouTube API configuration.
type ContextTracker ¶
type ContextTracker struct {
Session *Session
Model string
MaxTokens int
CurrentTokens int
PromptTokens int
CompletionTokens int
// Thresholds (kept for backward compatibility)
WarnThreshold float64 // 0.75
CautionThreshold float64 // 0.85
CriticalThreshold float64 // 0.95
// Tracking
LastWarningLevel string
CompactionCount int
TruncationCount int
// Underlying budget (exported so callers can use it directly if needed)
Budget *ctxmgr.TokenBudget
}
ContextTracker monitors token usage and context window status for a session. It is a thin wrapper around ctxmgr.TokenBudget, keeping the same external API so that tui/app.go and commands/ callers do not need wholesale changes.
func NewContextTracker ¶
func NewContextTracker(session *Session, model string, contextLimitOverride ...int) *ContextTracker
NewContextTracker creates a new context tracker for a session. It initialises an internal ctxmgr.TokenBudget.
func (*ContextTracker) EstimateMessagesUntilLimit ¶
func (ct *ContextTracker) EstimateMessagesUntilLimit(avgTokensPerMsg int) int
EstimateMessagesUntilLimit estimates how many messages can be sent before hitting the warning threshold.
func (*ContextTracker) GetContextSummary ¶
func (ct *ContextTracker) GetContextSummary() string
GetContextSummary returns a formatted summary of context usage.
func (*ContextTracker) GetRemainingTokens ¶
func (ct *ContextTracker) GetRemainingTokens() int
GetRemainingTokens returns the number of tokens remaining before limit.
func (*ContextTracker) GetUsagePercentage ¶
func (ct *ContextTracker) GetUsagePercentage() float64
GetUsagePercentage returns the percentage of context window used (0.0 to 1.0).
func (*ContextTracker) GetWarningLevel ¶
func (ct *ContextTracker) GetWarningLevel() string
GetWarningLevel returns the current warning level based on usage percentage. Uses the tracker's own CurrentTokens/MaxTokens rather than delegating to the budget, because external code may set CurrentTokens directly.
func (*ContextTracker) ShouldCompact ¶
func (ct *ContextTracker) ShouldCompact() bool
ShouldCompact returns true if auto-compaction should be triggered.
func (*ContextTracker) UpdateTokens ¶
func (ct *ContextTracker) UpdateTokens(prompt, completion, total int)
UpdateTokens updates token counts from API response.
type DailyStats ¶
type DailyStats struct {
Date string `json:"date"`
SessionCount int `json:"session_count"`
MessageCount int `json:"message_count"`
TokenCount int `json:"token_count"`
Cost float64 `json:"cost"`
}
DailyStats tracks usage for a specific day
type Exporter ¶
type Exporter struct {
// contains filtered or unexported fields
}
Exporter handles session export to various formats
func NewExporter ¶
NewExporter creates a new exporter for a session
func (*Exporter) ExportToFile ¶
ExportToFile is a convenience method that exports and saves in one call
func (*Exporter) SaveToFile ¶
SaveToFile saves the exported content to a file
func (*Exporter) ToCSV ¶
ToCSV exports the session as CSV (one row per message) Format: timestamp,role,content,tokens,model,cost
func (*Exporter) ToMarkdown ¶
ToMarkdown exports the session as Markdown with frontmatter
type GlobalAnalytics ¶
type GlobalAnalytics struct {
TotalSessions int `json:"total_sessions"`
TotalMessages int `json:"total_messages"`
TotalTokens int `json:"total_tokens"`
TotalCost float64 `json:"total_cost"`
// Per-provider breakdown
ProviderUsage map[string]*ProviderStats `json:"provider_usage"`
// Per-model breakdown
ModelUsage map[string]*ModelStats `json:"model_usage"`
// Time-based tracking (YYYY-MM-DD -> stats)
DailyUsage map[string]*DailyStats `json:"daily_usage"`
LastUpdated time.Time `json:"last_updated"`
}
GlobalAnalytics tracks cumulative usage across all sessions
func LoadGlobalAnalytics ¶
func LoadGlobalAnalytics() (*GlobalAnalytics, error)
LoadGlobalAnalytics loads analytics from ~/.celeste/analytics.json
func NewGlobalAnalytics ¶
func NewGlobalAnalytics() *GlobalAnalytics
NewGlobalAnalytics creates a new empty analytics tracker
func (*GlobalAnalytics) GetTopModelNames ¶
func (ga *GlobalAnalytics) GetTopModelNames(n int) []struct { Name string Stats ModelStats }
GetTopModelNames returns the top N model names with their stats
func (*GlobalAnalytics) GetTopProviders ¶
func (ga *GlobalAnalytics) GetTopProviders() []struct { Name string Stats ProviderStats }
GetTopProviders returns providers sorted by usage
func (*GlobalAnalytics) GetWeeklyUsage ¶
func (ga *GlobalAnalytics) GetWeeklyUsage() []DailyStats
GetWeeklyUsage returns usage stats for the last 7 days
func (*GlobalAnalytics) Save ¶
func (ga *GlobalAnalytics) Save() error
Save persists analytics to ~/.celeste/analytics.json
func (*GlobalAnalytics) UpdateFromSession ¶
func (ga *GlobalAnalytics) UpdateFromSession(session *Session)
UpdateFromSession updates analytics with data from a session
type IPFSConfig ¶
type IPFSConfig struct {
Provider string
APIKey string
APISecret string
ProjectID string
GatewayURL string
TimeoutSeconds int
}
IPFSConfig holds IPFS configuration.
type LaneConfig ¶
type LaneConfig struct {
Primary string `json:"primary"`
PrimaryBaseURL string `json:"primary_base_url,omitempty"`
PrimaryAPIKey string `json:"primary_api_key,omitempty"`
Reviewer string `json:"reviewer,omitempty"`
ReviewerBaseURL string `json:"reviewer_base_url,omitempty"`
ReviewerAPIKey string `json:"reviewer_api_key,omitempty"`
}
LaneConfig holds the primary and optional reviewer model for one task lane. PrimaryBaseURL/PrimaryAPIKey and ReviewerBaseURL/ReviewerAPIKey allow cross-provider orchestration (e.g. xAI primary + OpenAI reviewer) without changing the main config.
type ModelStats ¶
type ModelStats struct {
SessionCount int `json:"session_count"`
MessageCount int `json:"message_count"`
InputTokens int `json:"input_tokens"`
OutputTokens int `json:"output_tokens"`
Cost float64 `json:"cost"`
}
ModelStats tracks usage for a specific model
type OrchestratorConfig ¶
type OrchestratorConfig struct {
Lanes map[string]LaneConfig `json:"lanes,omitempty"`
DefaultLane string `json:"default_lane,omitempty"`
DebateRounds int `json:"debate_rounds,omitempty"`
}
OrchestratorConfig controls multi-model orchestration behaviour.
type PricingTier ¶
PricingTier represents the cost per million tokens for input and output
func GetModelPricing ¶
func GetModelPricing(model string) (PricingTier, bool)
GetModelPricing returns the pricing tier for a model, if available
type ProviderBlocks ¶
type ProviderBlocks struct {
Provider string `json:"provider"`
Digest string `json:"digest,omitempty"`
Blocks []json.RawMessage `json:"blocks"`
}
ProviderBlocks is a message's content exactly as one provider returned it (2.0 F3): Anthropic thinking, redacted_thinking, text, tool_use and compaction blocks; OpenAI Responses output items. Provider is the key of the backend that produced them (llm.ProviderKey). Digest ties them to the message's provider-neutral Content and ToolCalls at the moment they were attached (tui.AttachProviderBlocks); tui.ReplayBlocks replays them only while both still match.
Blocks are canonical JSON: compact and HTML-escaped, the form encoding/json itself writes, so a save/load cycle returns the same bytes. A ProviderBlocks is never modified after it is attached; an edit replaces the message's pointer with nil.
func NewProviderBlocks ¶
func NewProviderBlocks(provider string, blocks []json.RawMessage) (*ProviderBlocks, error)
NewProviderBlocks canonicalizes a reply's blocks. It returns nil, nil for no blocks, and an error for an empty provider or a block that is not a JSON object.
func (*ProviderBlocks) UnmarshalJSON ¶
func (p *ProviderBlocks) UnmarshalJSON(data []byte) error
UnmarshalJSON re-canonicalizes each block, undoing the indentation that MarshalIndent (sessions, agent checkpoints) puts inside raw JSON. A value that does not decode becomes the zero ProviderBlocks, which is never replayed: damaged blocks must not fail a session or checkpoint load.
type ProviderStats ¶
type ProviderStats struct {
SessionCount int `json:"session_count"`
MessageCount int `json:"message_count"`
TokenCount int `json:"token_count"`
Cost float64 `json:"cost"`
}
ProviderStats tracks usage for a specific provider
type Sandbox ¶
type Sandbox struct {
Enabled *bool `json:"enabled,omitempty"` // run bash under the OS sandbox
Writable []string `json:"writable,omitempty"` // more writable directories (relative: to the workspace)
Network *bool `json:"network,omitempty"` // false cuts the network
}
Sandbox is the "sandbox" object in ~/.celeste/config.json (the user's, trusted) and in a workspace's .celeste/config.json (the repository's: its tightening applies always, its loosening only once trusted). A nil field keeps the default.
func LoadWorkspaceSandbox ¶
LoadWorkspaceSandbox reads the "sandbox" object of workspace's .celeste/config.json. s is nil when the file or the key is absent. body is s as canonical JSON (sorted keys, no unknown fields), what trust approvals hash. The file's other keys are ignored.
type Session ¶
type Session struct {
ID string `json:"id"`
Name string `json:"name,omitempty"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
Messages []SessionMessage `json:"messages"`
NSFWMode bool `json:"nsfw_mode,omitempty"`
Metadata map[string]any `json:"metadata,omitempty"`
TokenCount int `json:"token_count,omitempty"` // Estimated token count
Model string `json:"model,omitempty"` // Track model for limits
// NEW: Enhanced tracking
UsageMetrics *UsageMetrics `json:"usage_metrics,omitempty"` // Detailed usage tracking
Provider string `json:"provider,omitempty"` // Provider (openai, venice, etc)
MaxContext int `json:"max_context,omitempty"` // Model's max context window
// Workspace is the absolute directory the chat ran in (2.0 W4 ruling
// 1): `celeste resume` and /session list show this project's
// sessions first. Older sessions have none.
Workspace string `json:"workspace,omitempty"`
}
Session represents a saved conversation session.
func LoadSession ¶
LoadSession is a global helper to load a session by numeric ID
func SortForWorkspace ¶
SortForWorkspace splits sessions into ws's project's and the rest, each newest first (2.0 W4 ruling 2).
func (*Session) ClearMessages ¶
func (s *Session) ClearMessages()
ClearMessages clears all messages from the session.
func (*Session) GetCommandHistory ¶
GetCommandHistory retrieves the input command history from session metadata.
func (*Session) GetEndpoint ¶
GetEndpoint retrieves the endpoint from session metadata.
func (*Session) GetMessages ¶
func (s *Session) GetMessages() []SessionMessage
GetMessages returns all session messages.
func (*Session) GetMessagesRaw ¶
func (s *Session) GetMessagesRaw() interface{}
GetMessagesRaw returns messages as interface{} (for TUI interface compatibility).
func (*Session) GetModelPinned ¶
GetModelPinned reports a saved /set-model --force pin.
func (*Session) GetModelUnverified ¶
GetModelUnverified reports what SetModelUnverified stored.
func (*Session) GetNSFWMode ¶
GetNSFWMode retrieves the NSFW mode from session.
func (*Session) GetProvider ¶
GetProvider retrieves the provider name from the session.
func (*Session) GetWorkspace ¶
GetWorkspace is the directory the session ran in ("" for older sessions).
func (*Session) InitializeUsageMetrics ¶
func (s *Session) InitializeUsageMetrics()
InitializeUsageMetrics ensures the session has usage metrics initialized.
func (*Session) SetCommandHistory ¶
SetCommandHistory stores the input command history in session metadata, with set-key commands' keys redacted.
func (*Session) SetEndpoint ¶
SetEndpoint stores the current endpoint in session metadata.
func (*Session) SetMessagesRaw ¶
func (s *Session) SetMessagesRaw(msgs interface{})
SetMessagesRaw sets messages from interface{} (for TUI interface compatibility).
func (*Session) SetModelPinned ¶
SetModelPinned records a /set-model --force pin, so a resume keeps the model instead of resolving it.
func (*Session) SetModelUnverified ¶
SetModelUnverified records that the session's model is a /set-model --force name no catalog listed, so a resume does not show it as valid.
func (*Session) SetNSFWMode ¶
SetNSFWMode stores the NSFW mode in session.
func (*Session) SetWorkspace ¶
SetWorkspace records the directory the session runs in.
func (*Session) Summarize ¶
func (s *Session) Summarize() SessionSummary
Summarize returns a summary of the session.
func (*Session) SummarizeRaw ¶
func (s *Session) SummarizeRaw() interface{}
SummarizeRaw returns summary as interface{} (for TUI interface compatibility).
func (*Session) UpdateUsageMetrics ¶
UpdateUsageMetrics updates the session's usage metrics with new token data.
type SessionManager ¶
type SessionManager struct {
// contains filtered or unexported fields
}
SessionManager manages session persistence.
func NewSessionManager ¶
func NewSessionManager() *SessionManager
NewSessionManager creates a new session manager.
func (*SessionManager) AddMessage ¶
func (m *SessionManager) AddMessage(session *Session, role, content string)
AddMessage adds a message to the session and saves.
func (*SessionManager) AddMessageWithTokens ¶
func (m *SessionManager) AddMessageWithTokens(session *Session, role, content string, inputTokens, outputTokens int)
AddMessageWithTokens adds a message to the session with token tracking.
func (*SessionManager) Delete ¶
func (m *SessionManager) Delete(id string) error
Delete deletes a session by ID.
func (*SessionManager) GetCurrentID ¶
func (m *SessionManager) GetCurrentID() string
GetCurrentID returns the current session ID.
func (*SessionManager) List ¶
func (m *SessionManager) List() ([]Session, error)
List returns all saved sessions.
func (*SessionManager) Load ¶
func (m *SessionManager) Load(id string) (*Session, error)
Load loads a session by ID.
func (*SessionManager) LoadLatest ¶
func (m *SessionManager) LoadLatest() (*Session, error)
LoadLatest loads the most recent session.
func (*SessionManager) MergeSessions ¶
func (m *SessionManager) MergeSessions(session1, session2 *Session) *Session
MergeSessions combines messages from two sessions chronologically.
func (*SessionManager) NewSession ¶
func (m *SessionManager) NewSession() *Session
NewSession creates a new session with a unique ID.
func (*SessionManager) Save ¶
func (m *SessionManager) Save(session *Session) error
Save saves a session to disk.
type SessionMessage ¶
type SessionMessage struct {
Role string `json:"role"`
Content string `json:"content"`
Timestamp time.Time `json:"timestamp"`
// Tool traffic (#174): without it a resumed session replays only the
// prose, so the model loses what it read and did.
ToolCalls []SessionToolCall `json:"tool_calls,omitempty"` // assistant: calls made
ToolCallID string `json:"tool_call_id,omitempty"` // tool: call answered
Name string `json:"name,omitempty"` // tool: function name
// Hidden messages are sent to the model but not rendered (directives,
// compaction summaries). Compacted messages were replaced by a summary:
// rendered in the scrollback but no longer sent.
Hidden bool `json:"hidden,omitempty"`
Compacted bool `json:"compacted,omitempty"`
// ProviderBlocks is the message as the provider returned it (2.0 F3),
// saved only while it still matches Content and ToolCalls.
ProviderBlocks *ProviderBlocks `json:"provider_blocks,omitempty"`
}
SessionMessage represents a message in a session.
type SessionSummary ¶
type SessionSummary struct {
ID string `json:"id"`
Name string `json:"name,omitempty"`
MessageCount int `json:"message_count"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
FirstMessage string `json:"first_message,omitempty"`
Metadata map[string]any `json:"metadata,omitempty"`
Workspace string `json:"workspace,omitempty"`
}
SessionSummary provides a brief overview of a session.
type SessionToolCall ¶
type SessionToolCall struct {
ID string `json:"id"`
Name string `json:"name"`
Arguments string `json:"arguments"`
ThoughtSignature []byte `json:"thought_signature,omitempty"`
}
SessionToolCall is a tool call recorded on an assistant message.
type SliderConfig ¶
type SliderConfig struct {
// Flirt controls how forward / teasing she is.
// 0=professional, 3=playful, 7=flirty, 10=aggressive-flirt
Flirt int `json:"flirt"`
// Warmth controls affection level.
// 0=cold/distant, 3=polite, 7=warm, 10=openly-affectionate
Warmth int `json:"warmth"`
// Register controls speech style.
// 0=clipped-operator, 3=standard, 7=theatrical, 10=uwu/baby-talk
Register int `json:"register"`
// Lewdness controls content eligibility. Only has effect when
// R18Enabled is true — without R18, lewdness > 0 is a no-op.
// 0=SFW, 3=suggestive, 7=explicit-tease, 10=R18
Lewdness int `json:"lewdness"`
// R18Enabled is the independent toggle. Provider-agnostic — it
// controls what Celeste ATTEMPTS, not what the backend allows.
// Default false. Orthogonal to every slider.
R18Enabled bool `json:"r18_enabled"`
// Presets stores user-saved named slider combos.
Presets map[string]SliderPreset `json:"presets,omitempty"`
}
SliderConfig holds the user's personality slider state. Each slider is an int 0-10. Anchor points at 0/3/7/10 snap to authored prompt snippets; intermediate values snap to nearest anchor.
func DefaultSliderConfig ¶
func DefaultSliderConfig() *SliderConfig
DefaultSliderConfig returns the factory-default slider state. Moderate across the board, R18 off.
func LoadSliders ¶
func LoadSliders() *SliderConfig
LoadSliders loads the slider config from disk. Returns defaults if the file doesn't exist or is malformed.
func (*SliderConfig) LoadPreset ¶
func (s *SliderConfig) LoadPreset(name string) bool
LoadPreset restores slider values from a named preset.
func (*SliderConfig) Reset ¶
func (s *SliderConfig) Reset()
Reset restores factory defaults (preserves presets).
func (*SliderConfig) Save ¶
func (s *SliderConfig) Save() error
Save writes the slider config to disk.
type SliderPreset ¶
type SliderPreset struct {
Flirt int `json:"flirt"`
Warmth int `json:"warmth"`
Register int `json:"register"`
Lewdness int `json:"lewdness"`
R18Enabled bool `json:"r18_enabled"`
}
SliderPreset is a named snapshot of slider values.
type TarotConfig ¶
TarotConfig holds tarot function configuration.
type TwitchConfig ¶
TwitchConfig holds Twitch API configuration.
type UsageMetrics ¶
type UsageMetrics struct {
TotalInputTokens int `json:"total_input_tokens"`
TotalOutputTokens int `json:"total_output_tokens"`
TotalTokens int `json:"total_tokens"`
EstimatedCost float64 `json:"estimated_cost"`
CompactionCount int `json:"compaction_count"`
TruncationCount int `json:"truncation_count"`
MessageCount int `json:"message_count"`
ConversationStart time.Time `json:"conversation_start"`
ConversationEnd time.Time `json:"conversation_end"`
}
UsageMetrics tracks token usage and cost for a session
func NewUsageMetrics ¶
func NewUsageMetrics() *UsageMetrics
NewUsageMetrics creates a new usage metrics instance
func (*UsageMetrics) GetAverageTokensPerMessage ¶
func (um *UsageMetrics) GetAverageTokensPerMessage() float64
GetAverageTokensPerMessage returns the average tokens per message
func (*UsageMetrics) GetCostPerMessage ¶
func (um *UsageMetrics) GetCostPerMessage() float64
GetCostPerMessage returns the average cost per message
func (*UsageMetrics) GetDuration ¶
func (um *UsageMetrics) GetDuration() time.Duration
GetDuration returns the duration of the conversation
func (*UsageMetrics) IncrementMessageCount ¶
func (um *UsageMetrics) IncrementMessageCount()
IncrementMessageCount increments the message counter
func (*UsageMetrics) Update ¶
func (um *UsageMetrics) Update(inputTokens, outputTokens int, model string)
Update updates the usage metrics with new token counts
type UserIdentity ¶
type UserIdentity struct {
// Name is the user's display name. Empty means use the default title.
Name string `json:"name"`
// Title is the abyss-themed fallback when Name is empty.
// Default: "Summoner" — they invoked Celeste via the CLI.
Title string `json:"title,omitempty"`
}
UserIdentity holds the current user's identity for prompt calibration.
func DefaultUserIdentity ¶
func DefaultUserIdentity() *UserIdentity
DefaultUserIdentity returns the factory default — an unnamed summoner.
func LoadUser ¶
func LoadUser() *UserIdentity
LoadUser loads the user identity from disk. Returns default if the file doesn't exist or is malformed.
func (*UserIdentity) DisplayName ¶
func (u *UserIdentity) DisplayName() string
DisplayName returns the name to use when addressing the user. Returns Name if set, otherwise Title.
func (*UserIdentity) IsKusanagi ¶
func (u *UserIdentity) IsKusanagi() bool
IsKusanagi returns true if the user has identified as Kusanagi.
func (*UserIdentity) Save ¶
func (u *UserIdentity) Save() error
Save writes the user identity to disk.
type VeniceConfig ¶
type VeniceConfig struct {
APIKey string
BaseURL string
Model string // Chat model (venice-uncensored)
ImageModel string // Image generation model (lustify-sdxl, animewan, hidream, wai-Illustrious)
Upscaler string
}
VeniceConfig holds Venice.ai configuration.
type WalletSecuritySettingsConfig ¶
type WalletSecuritySettingsConfig struct {
Enabled bool
PollInterval int // seconds
AlertLevel string // minimum severity to alert on
}
WalletSecuritySettingsConfig holds wallet security settings.
type WeatherConfig ¶
type WeatherConfig struct {
DefaultZipCode string
}
WeatherConfig holds weather skill configuration.
type XAIFeaturesConfig ¶
type XAIFeaturesConfig struct {
EnableWebSearch bool `json:"enable_web_search"`
EnableXSearch bool `json:"enable_x_search"`
}
XAIFeaturesConfig holds xAI-specific feature flags
type YouTubeConfig ¶
YouTubeConfig holds YouTube API configuration.