Documentation
¶
Index ¶
- Constants
- func LoadConfig(path string) error
- func SetAlertConfigResolver(r AlertConfigResolver)
- type AgentAIAnalyzeConfig
- type AgentAIConfig
- type AgentAITaskConfig
- type AgentCatalogConfig
- type AgentCloudWatchLogsSourceConfig
- type AgentConfig
- type AgentElasticsearchSourceConfig
- type AgentFileSourceConfig
- type AgentGraylogSourceConfig
- type AgentLokiSourceConfig
- type AgentMinerConfig
- type AgentRedactionConfig
- type AgentRegexConfig
- type AgentRegexRule
- type AgentSourceConfig
- type AgentSplunkSourceConfig
- type AlertConfig
- type AlertConfigResolver
- type AwsIncidentManagerConfig
- type AzBusConfig
- type Config
- type DescribeDependenciesToolConfig
- type EmailConfig
- type FindRunbookToolConfig
- type GitAuthConfig
- type IncidentioConfig
- type LarkConfig
- type MSTeamsConfig
- type OnCallConfig
- type PagerDutyConfig
- type ProxyConfig
- type PubSubConfig
- type QueryMetricsPrometheusConfig
- type QueryMetricsToolConfig
- type QueryTracesTempoConfig
- type QueryTracesToolConfig
- type QueueConfig
- type RecentChangesGitConfig
- type RecentChangesGitRepo
- type RecentChangesToolConfig
- type RedisConfig
- type SNSConfig
- type SQSConfig
- type ServiceDependency
- type ServiceNowConfig
- type SlackConfig
- type SlackMessageProperties
- type StorageConfig
- type StorageDatabaseConfig
- type StorageFileConfig
- type StoragePostgresConfig
- type StorageRedisConfig
- type TelegramConfig
- type ToolsConfig
- type ViberConfig
Constants ¶
const ( DefaultSpikeZ = 3.0 DefaultSpikeMinFrequency = 5 DefaultSpikeMinBaselineCount = 20 DefaultSpikeSustainTicks = 1 )
Spike-detection defaults, applied when the corresponding config key is unset (zero). They mirror the founder-approved locked defaults.
const AICacheBlobName = "ai_cache"
AICacheBlobName is the storage blob key used by the AI SRE result cache (per-pattern findings, ttl-bounded).
const CatalogBlobName = "patterns"
CatalogBlobName is the storage blob key used by the agent catalog. Backends translate this into a path / redis key / row.
const DefaultAutoPromoteAfter = 100
DefaultAutoPromoteAfter is the sighting count at which a learned pattern is auto-promoted to "known" when the operator omits, blanks, or sets a non-positive auto_promote_after. It is the single source of truth for that default: the config loader normalizes any value <= 0 up to this, and the learning engine and readiness view fall back to it as well, so there is no "disabled / manual-only" promotion state.
const ShadowBlobName = "shadow"
ShadowBlobName is the storage blob key used by the shadow log.
Variables ¶
This section is empty.
Functions ¶
func LoadConfig ¶
func SetAlertConfigResolver ¶ added in v1.4.8
func SetAlertConfigResolver(r AlertConfigResolver)
SetAlertConfigResolver registers the resolver used to override the effective notification-channel config at runtime. Last-wins: a second call replaces the first. Passing nil clears the slot (back to the YAML floor). OSS ships none, so the emission path uses the static `alert.*` config unchanged. This is the entry point the enterprise hooks.Register attaches to (mirror of SetAISettingsResolver). Call at boot.
Types ¶
type AgentAIAnalyzeConfig ¶ added in v1.4.3
type AgentAIAnalyzeConfig struct {
// Model overrides the shared ai.model for analyze deep dives.
// Empty inherits ai.model.
Model string `mapstructure:"model"`
}
AgentAIAnalyzeConfig is the analyze-agent override block. The model knob lets analyze deep dives point at a stronger model than the shared ai.model. All other LLM settings (temperature, max_tokens, rate limit, cache) are inherited from the top-level ai block, and the tool-loop knobs (tool_timeout, parallel_tools) live on the shared tools block (tools.yaml). The analyze agent is constructed whenever AI.Enable is true — there is no separate opt-in gate.
The Model knob is read directly from cfg.AI.Analyze (NOT via Resolve, which zeroes the Analyze overlay), so it must be deep-cloned in clone_config.go.
type AgentAIConfig ¶ added in v1.3.9
type AgentAIConfig struct {
// Enable gates whether the AI SRE is called at all. When false
// (the default) detect mode still classifies patterns but never calls
// the LLM — it only logs what it would have sent. This allows operators
// to run detect mode in a "dry-run" fashion without an API key.
Enable bool `mapstructure:"enable"`
// Provider selects the model backend the eino layer constructs
// (e.g. "openai", "deepseek", "qwen", "ollama", "claude"). Empty
// defaults to "openai". The single APIKey below is the credential for
// the SELECTED provider — operators change the key to match when they
// switch provider. An unsupported value fails fast at model construction.
Provider string `mapstructure:"provider"`
// APIKey is the bearer token sent in the Authorization header.
APIKey string `mapstructure:"api_key"`
// Model is the model identifier, e.g. "gpt-4o-mini".
Model string `mapstructure:"model"`
// Temperature controls randomness (0.0–2.0). Default 0.2.
Temperature float64 `mapstructure:"temperature"`
// MaxTokens caps the response length. Default 512.
MaxTokens int `mapstructure:"max_tokens"`
// MaxCallsPerHour is a sliding-window rate limit. 0 = unlimited.
MaxCallsPerHour int `mapstructure:"max_calls_per_hour"`
// CacheTTL is how long an AI result for a pattern_id is cached to
// avoid re-asking about the same pattern. Default "1h".
CacheTTL string `mapstructure:"cache_ttl"`
// Detect and Analyze are per-task overrides. Empty fields fall back
// to the top-level defaults above, so a single shared block keeps
// working unchanged. Detect is used by the worker for unknown /
// spiking pattern classification; Analyze is used by the on-demand
// analyzer.
//
// There is no `framework` knob: Eino is the only LLM path.
Detect AgentAITaskConfig `mapstructure:"detect"`
Analyze AgentAIAnalyzeConfig `mapstructure:"analyze"`
}
The struct and env overrides are wired today; the concrete HTTP client and prompt builder land alongside detect-mode emission.
func (AgentAIConfig) Resolve ¶ added in v1.4.3
func (c AgentAIConfig) Resolve(task AgentAITaskConfig) AgentAIConfig
Resolve returns a fully-defaulted AgentAIConfig for the given task by overlaying the task's sub-config onto the top-level defaults. Empty sub-config fields preserve the top-level value (and Temperature == 0 is treated as "inherit" — operators wanting deterministic detect must set it on the top-level block).
type AgentAITaskConfig ¶ added in v1.4.3
type AgentAITaskConfig struct {
Model string `mapstructure:"model"`
Temperature float64 `mapstructure:"temperature"`
MaxTokens int `mapstructure:"max_tokens"`
MaxCallsPerHour int `mapstructure:"max_calls_per_hour"`
CacheTTL string `mapstructure:"cache_ttl"`
}
AgentAITaskConfig is the per-task override block. Zero values mean "inherit the top-level AgentAIConfig field".
type AgentCatalogConfig ¶ added in v1.3.9
type AgentCatalogConfig struct {
PersistInterval string `mapstructure:"persist_interval"` // e.g. "30s"
AutoPromoteAfter int `mapstructure:"auto_promote_after"` // sightings to "known"; <=0 is normalized to DefaultAutoPromoteAfter
// SpikeZ is the z-score threshold: a known pattern is re-flagged as a spike
// when its per-second rate sits this many standard deviations above the
// learned baseline (self-scaling, so a burst on a high-volume pattern trips
// even though its mean is large). Default 3.0.
SpikeZ float64 `mapstructure:"spike_z"`
// SpikeAbsCeiling is a deterministic safety net: a tick with at least this
// many matches always surfaces, regardless of the z-score or warmup. 0
// disables it (opt-in). Default 0.
SpikeAbsCeiling int `mapstructure:"spike_abs_ceiling"`
// SpikeSustainTicks is how many CONSECUTIVE spiking ticks are required
// before firing — a debounce against single noisy ticks. 1 (the default)
// fires on the first tick (no debounce).
SpikeSustainTicks int `mapstructure:"spike_sustain_ticks"`
// SpikeMinFrequency is the minimum tick count required before a spike can
// fire — an absolute noise floor so a low-count pattern can't page on a
// couple of matches. Default 5.
SpikeMinFrequency int `mapstructure:"spike_min_frequency"`
// SpikeMinBaselineCount is the warmup/confidence gate: the pattern must
// have been seen this many times overall before the z-score is trusted
// (until then only the absolute ceiling can fire). Default 20.
SpikeMinBaselineCount int `mapstructure:"spike_min_baseline_count"`
// SpikeMultiplier is DEPRECATED and no longer drives detection (the
// threshold moved from a volume-blind ratio to the z-score above). It is
// still parsed so an existing config loads without error; a one-time
// deprecation notice is logged when it is set. Remove it from your config.
SpikeMultiplier float64 `mapstructure:"spike_multiplier"`
}
type AgentCloudWatchLogsSourceConfig ¶ added in v1.4.0
type AgentCloudWatchLogsSourceConfig struct {
// Region, e.g. "us-east-1". Required.
Region string `mapstructure:"region"`
// LogGroupName is the CloudWatch log group, e.g. "/aws/lambda/my-fn".
// Required.
LogGroupName string `mapstructure:"log_group_name"`
// LogStreamPrefix optionally restricts events to streams whose name
// starts with this prefix (cheaper than scanning the whole group).
LogStreamPrefix string `mapstructure:"log_stream_prefix"`
// FilterPattern is a CloudWatch Logs filter pattern (NOT a regex).
// See AWS docs. Empty matches every event.
FilterPattern string `mapstructure:"filter_pattern"`
// PageSize is the per-call limit (max 10000). Default 500.
PageSize int `mapstructure:"page_size"`
}
AgentCloudWatchLogsSourceConfig drives the AWS CloudWatch Logs SignalSource.
The source uses the `FilterLogEvents` API (cheap, real-time, no async query lifecycle). Authentication is the standard AWS SDK chain (env vars, shared credentials file, IAM role).
type AgentConfig ¶ added in v1.3.9
type AgentConfig struct {
Enable bool `mapstructure:"enable"`
Mode string `mapstructure:"mode"` // training | shadow | detect
PollInterval string `mapstructure:"poll_interval"` // e.g. "30s"
Lookback string `mapstructure:"lookback"` // e.g. "5m"
BatchMax int `mapstructure:"batch_max"`
SignalMaxBytes int `mapstructure:"signal_max_bytes"`
// NewServiceGrace is the duration a newly discovered service stays in
// implicit training mode before detect-mode AI analysis begins. Signals
// from a service still in its grace period flow through the full pipeline
// (redact → regex → miner → catalog) but are not forwarded to the AI
// analyzer. Set to "0" to disable (all services analysed immediately).
NewServiceGrace string `mapstructure:"new_service_grace"` // e.g. "30m"
// ServicePatterns is an ordered list of regexes applied to each
// (post-redaction) log message to discover the service name.
ServicePatterns []string `mapstructure:"service_patterns"`
Redaction AgentRedactionConfig `mapstructure:"redaction"`
Catalog AgentCatalogConfig `mapstructure:"catalog"`
Miner AgentMinerConfig `mapstructure:"miner"`
Regex AgentRegexConfig `mapstructure:"regex"`
AI AgentAIConfig `mapstructure:"ai"`
// Sources is the list of enabled signal sources. Versus loads it from
// the file `agent_sources.yaml` sitting next to the main config file
// (path is hardcoded; missing file is OK — the agent simply has no
// sources). The file's top-level key is `sources`. ${VAR} references
// in the file are expanded against the process environment.
Sources []AgentSourceConfig `mapstructure:"sources"`
// Tools holds per-tool configuration for analyze-mode tools that need
// external data (e.g. the `recent_changes` tool's git repository and
// the `describe_dependencies` tool's service-dependency graph).
// Versus loads it from the file `tools.yaml` sitting next to the main
// config file (path is hardcoded; missing file is OK — tools needing
// config then simply degrade to a clean "nothing found"). The file's
// top-level key is `tools`. This is per-tool DATA config, not a
// registration allow-list: tools are still registered in code via
// `analyzetools.Default`.
Tools ToolsConfig `mapstructure:"tools"`
}
type AgentElasticsearchSourceConfig ¶ added in v1.3.9
type AgentElasticsearchSourceConfig struct {
Addresses []string `mapstructure:"addresses"`
Username string `mapstructure:"username"`
Password string `mapstructure:"password"`
APIKey string `mapstructure:"api_key"`
InsecureSkipVerify bool `mapstructure:"insecure_skip_verify"`
Index string `mapstructure:"index"`
TimeField string `mapstructure:"time_field"`
Query string `mapstructure:"query"` // Lucene-style query string
MessageField string `mapstructure:"message_field"`
SeverityField string `mapstructure:"severity_field"`
ExtraFields []string `mapstructure:"extra_fields"`
PageSize int `mapstructure:"page_size"`
// ReorderWindow is how far back (a Go duration, e.g. "1m") each tick
// re-scans below the cursor to catch documents that were indexed with a
// timestamp behind the newest one already seen — refresh lag, clock skew,
// or bursty/late ingestion. Docs indexed more than ReorderWindow behind the
// cursor are NOT recovered; this is the bounded trade-off that keeps the
// per-tick dedup set memory-bounded. Empty/invalid → 1m default.
ReorderWindow string `mapstructure:"reorder_window"`
}
type AgentFileSourceConfig ¶ added in v1.3.9
type AgentFileSourceConfig struct {
// Path to the log file. Globs are NOT supported (one source = one file).
Path string `mapstructure:"path"`
// Format: "text" (default) or "json" (one JSON object per line).
Format string `mapstructure:"format"`
// CursorPath overrides the default sidecar cursor file location
// (default: a ".versus-cursor-<source_name>" file next to the watched log file).
CursorPath string `mapstructure:"cursor_path"`
// FromBeginning controls behavior when there is no cursor yet.
// false (default) starts at the current end of the file (tail-like).
// true reads the whole file from the start (replay-like — useful for tests).
FromBeginning bool `mapstructure:"from_beginning"`
// MaxLineBytes caps a single line's length to protect memory; longer
// lines are truncated. Default 64 KiB.
MaxLineBytes int `mapstructure:"max_line_bytes"`
// MaxLinesPerPull caps the number of lines returned by a single Pull.
// When the file has a large backlog (e.g. from_beginning=true on a 100k-
// line file), this paginates the backfill across ticks so the worker's
// batch_max truncation never silently drops unread tail content. The
// byte offset only advances over what was actually consumed in this
// Pull, so the next tick resumes exactly where this one stopped.
// Default 1000.
MaxLinesPerPull int `mapstructure:"max_lines_per_pull"`
// TimestampLayout is a Go time layout (e.g. "2006-01-02T15:04:05Z07:00")
// used to parse a leading timestamp from each line. When empty the
// source uses time.Now() at read time. Default tries RFC3339Nano then
// RFC3339, then "2006-01-02 15:04:05".
TimestampLayout string `mapstructure:"timestamp_layout"`
MessageField string `mapstructure:"message_field"` // default: "message"
TimestampField string `mapstructure:"timestamp_field"` // default: "@timestamp"
SeverityField string `mapstructure:"severity_field"` // default: "level"
}
AgentFileSourceConfig drives the file-tailing SignalSource.
The file source is the cheapest way to exercise the agent end-to-end: drop a log file on disk, point the agent at it, restart, and watch the catalog fill up. It tracks its position in a sidecar cursor file so it survives restarts and handles log rotation (file shrinks → start over from offset 0).
type AgentGraylogSourceConfig ¶ added in v1.4.3
type AgentGraylogSourceConfig struct {
// Address is the Graylog base URL, e.g. "https://graylog:9000".
Address string `mapstructure:"address"`
// Username + Password for HTTP Basic auth. Standard Graylog login.
Username string `mapstructure:"username"`
Password string `mapstructure:"password"`
// APIToken is an alternative to Username/Password. When set the
// source sends Basic auth with the token as the username and the
// literal string "token" as the password (Graylog convention).
APIToken string `mapstructure:"api_token"`
InsecureSkipVerify bool `mapstructure:"insecure_skip_verify"`
// Query is a Graylog search string, e.g. `level:ERROR AND service:api`.
// Defaults to "*" (match all) when empty.
Query string `mapstructure:"query"`
// StreamID optionally restricts the search to a single stream
// (Graylog stream ids look like "000000000000000000000001").
StreamID string `mapstructure:"stream_id"`
// MessageField is the field copied into Signal.Message.
// Default "message".
MessageField string `mapstructure:"message_field"`
// SeverityField is the field copied into Signal.Severity.
// Default "level".
SeverityField string `mapstructure:"severity_field"`
// Fields, when non-empty, restricts the server-side projection to
// these fields (faster + smaller responses).
Fields []string `mapstructure:"fields"`
// ExtraFields are additional fields copied into Signal.Fields. They
// must also appear in Fields (or Fields must be empty so the server
// returns the whole document).
ExtraFields []string `mapstructure:"extra_fields"`
// PageSize caps results per tick (Graylog default cap is 150).
// Default 500.
PageSize int `mapstructure:"page_size"`
}
AgentGraylogSourceConfig drives the Graylog SignalSource.
The source uses Graylog's `search/universal/absolute` REST endpoint — synchronous, sorted by timestamp ascending, and cursor-friendly.
type AgentLokiSourceConfig ¶ added in v1.4.0
type AgentLokiSourceConfig struct {
// Address is the Loki base URL, e.g. "http://loki:3100".
Address string `mapstructure:"address"`
// TenantID, when set, is sent as the `X-Scope-OrgID` header (multi-tenant
// Loki / Grafana Cloud).
TenantID string `mapstructure:"tenant_id"`
// Username/Password enable HTTP Basic auth (Grafana Cloud uses
// instance ID / API token).
Username string `mapstructure:"username"`
Password string `mapstructure:"password"`
// BearerToken is sent as `Authorization: Bearer <token>` when set.
// Mutually exclusive with Username/Password (Bearer wins).
BearerToken string `mapstructure:"bearer_token"`
InsecureSkipVerify bool `mapstructure:"insecure_skip_verify"`
// Query is a LogQL selector, e.g. `{app="api",env="prod"} |= "error"`.
// Required.
Query string `mapstructure:"query"`
// SeverityField, when set, is read from each entry's stream labels
// (e.g. "level") to populate Signal.Severity.
SeverityField string `mapstructure:"severity_field"`
// ExtraLabels are additional stream labels copied into Signal.Fields.
ExtraLabels []string `mapstructure:"extra_labels"`
// PageSize is the per-query limit (Loki caps this around 5000 by
// default). Default 500.
PageSize int `mapstructure:"page_size"`
}
AgentLokiSourceConfig drives the Grafana Loki SignalSource.
The source uses Loki's HTTP `query_range` endpoint with `direction=forward` so the stream is read oldest-first and pagination is cursor-friendly. The cursor is the maximum log timestamp seen on the previous tick.
type AgentMinerConfig ¶ added in v1.3.9
type AgentRedactionConfig ¶ added in v1.3.9
type AgentRegexConfig ¶ added in v1.3.9
type AgentRegexConfig struct {
DefaultPattern string `mapstructure:"default_pattern"`
Rules []AgentRegexRule `mapstructure:"rules"`
// Metrics and Traces are OPTIONAL top-level per-KIND regex overrides,
// siblings of DefaultPattern (which is the logs default). They apply to
// every source of that kind. Both default to empty, which means "learn
// all" — metrics/traces are not text-filtered by default. They are not
// shipped in the sample config.yaml; an operator opts in only to narrow a
// kind. Logs are unaffected (they always use DefaultPattern + Rules).
Metrics string `mapstructure:"metrics"`
Traces string `mapstructure:"traces"`
}
type AgentRegexRule ¶ added in v1.3.9
type AgentSourceConfig ¶ added in v1.3.9
type AgentSourceConfig struct {
Name string `mapstructure:"name"`
Type string `mapstructure:"type"` // "elasticsearch" | "file" | "loki" | "cloudwatchlogs" | "graylog" | "splunk" | <registered type, e.g. "prometheus"/"traces" via Versus Enterprise>
Enable bool `mapstructure:"enable"`
Elasticsearch AgentElasticsearchSourceConfig `mapstructure:"elasticsearch"`
File AgentFileSourceConfig `mapstructure:"file"`
Loki AgentLokiSourceConfig `mapstructure:"loki"`
CloudWatchLogs AgentCloudWatchLogsSourceConfig `mapstructure:"cloudwatchlogs"`
Graylog AgentGraylogSourceConfig `mapstructure:"graylog"`
Splunk AgentSplunkSourceConfig `mapstructure:"splunk"`
// Options is a generic per-source settings block consumed by source
// types resolved through the runtime registration hook
// (signalsources.Register) rather than built into OSS — e.g. the
// enterprise metric (`prometheus`) and trace (`traces`) data sources.
// Built-in OSS log sources use their dedicated typed blocks above and
// ignore this field. The registered Factory decodes this map into its
// own concrete config struct.
Options map[string]interface{} `mapstructure:"options"`
}
type AgentSplunkSourceConfig ¶ added in v1.4.3
type AgentSplunkSourceConfig struct {
// Address is the Splunk REST base URL, e.g. "https://splunk:8089".
Address string `mapstructure:"address"`
// Token is sent as `Authorization: Bearer <token>` and takes
// priority over Username/Password when set.
Token string `mapstructure:"token"`
// Username + Password fall back to HTTP Basic auth.
Username string `mapstructure:"username"`
Password string `mapstructure:"password"`
InsecureSkipVerify bool `mapstructure:"insecure_skip_verify"`
// Search is the SPL query. May start with the `search` command
// (added automatically when missing). Example:
// `index=main sourcetype=api level=error`.
Search string `mapstructure:"search"`
// TimeField is the timestamp field on each result. Default "_time".
TimeField string `mapstructure:"time_field"`
// MessageField is the field copied into Signal.Message.
// Default "_raw".
MessageField string `mapstructure:"message_field"`
// SeverityField is the field copied into Signal.Severity. Empty by
// default — Splunk events do not have a canonical severity field.
SeverityField string `mapstructure:"severity_field"`
// ExtraFields are copied into Signal.Fields.
ExtraFields []string `mapstructure:"extra_fields"`
// PageSize caps results per tick. Default 500.
PageSize int `mapstructure:"page_size"`
}
AgentSplunkSourceConfig drives the Splunk SignalSource.
The source uses Splunk's `search/v2/jobs/export` REST endpoint for streaming JSON results. Auth uses a bearer token by default (HEC / auth tokens); HTTP Basic is the fallback for username/password setups.
type AlertConfig ¶
type AlertConfig struct {
DebugBody bool `mapstructure:"debug_body"`
Slack SlackConfig
Telegram TelegramConfig
Viber ViberConfig
Email EmailConfig
MSTeams MSTeamsConfig
Lark LarkConfig
}
type AlertConfigResolver ¶ added in v1.4.8
type AlertConfigResolver interface {
ResolveAlert(ctx context.Context, base *AlertConfig) (applied bool)
}
AlertConfigResolver resolves the effective notification-channel config at runtime. Implementations overlay this org's runtime channel overrides onto base — a per-request CLONE the caller owns — IN PLACE, per channel, and report whether any override was applied.
Contract:
- Only channels the resolver holds an override for are overlaid; every other channel is left exactly as base (the YAML floor) — partial override.
- It MUST NOT mutate global config; base is always a caller-owned clone.
- It MUST be fail-closed per channel: if a persisted override for a channel fails to decrypt or is malformed, the resolver leaves THAT channel at its base (YAML) value rather than breaking it. A corrupt override reverts to YAML, it never silently mutes a channel.
- ctx carries the effective org for a future multi-tenant build; the single-org resolver uses its boot-pinned org and may ignore ctx.
- It returns applied=true if it changed base at all, false if it had no opinion for any channel (base untouched).
type AzBusConfig ¶
type AzBusConfig struct {
Enable bool `mapstructure:"enable"`
}
type Config ¶
type Config struct {
Name string
Host string
Port int
PublicHost string `mapstructure:"public_host"`
// GatewaySecret is the shared secret required by every admin endpoint
// (`/api/admin/*` and `/api/agent/*`). Clients send the same value in
// the `X-Gateway-Secret` header. When empty, admin endpoints are NOT
// registered and the agent refuses to start.
GatewaySecret string `mapstructure:"gateway_secret"`
Alert AlertConfig
Queue QueueConfig
OnCall OnCallConfig
Proxy ProxyConfig
Redis RedisConfig `mapstructure:"redis"`
Storage StorageConfig `mapstructure:"storage"`
Agent AgentConfig `mapstructure:"agent"`
}
func GetConfigForAlert ¶ added in v1.4.8
GetConfigForAlert resolves the effective config for a single incident emission, applying the runtime-override → YAML → default precedence on a per-request CLONE (golden rule #4: global config is NEVER mutated).
Precedence, highest wins, all on the clone:
- clone the global cfg (cloneConfig — never touch the global pointer)
- runtime channel override (creds + enable) (applyAlertResolver — the runtime seam)
- per-incident routing params on top (applyParamsOverwrite — slack_channel_id, …)
Step 2 supplies a channel's CREDENTIALS + ENABLE from the runtime override (nil-inert in OSS). Step 3 is the EXISTING per-incident routing overlay (slack_channel_id, telegram_chat_id, email_to, msteams_other_power_url, …) and still applies ON TOP of the resolved credentials — an operator who rotated a token at runtime AND set a per-incident channel id both take effect. Routing is a distinct axis from credential config, so layering them keeps the two from fighting.
OSS fast path: when no resolver is registered AND there are no params, this returns the global cfg with NO clone — community behaviour is byte-for-byte unchanged (one nil-check, zero allocation).
ctx carries the effective org for a future multi-tenant build; the single-org resolver uses its boot-pinned org (CreateIncident may pass context.Background).
func GetConfigOrNil ¶ added in v1.4.8
func GetConfigOrNil() *Config
GetConfigOrNil returns the global config, or nil when it has not been loaded yet. Unlike GetConfig it NEVER panics, so callers that only read optional config can run on paths that may execute before Load (or in tests that don't load config) and degrade safely by treating a nil return as "unconfigured". Handlers must never mutate the returned pointer (golden rule #4).
type DescribeDependenciesToolConfig ¶ added in v1.4.3
type DescribeDependenciesToolConfig struct {
// Services is the operator-authored service-dependency graph. Each
// entry has a `name` and a `depends_on` list of upstream services;
// the reverse (downstream) edges are derived automatically at build
// time. Empty leaves the `describe_dependencies` tool unregistered.
Services []ServiceDependency `mapstructure:"services"`
}
DescribeDependenciesToolConfig configures the `describe_dependencies` tool. It carries the optional service-dependency graph; an empty `Services` list leaves the tool unregistered.
type EmailConfig ¶
type FindRunbookToolConfig ¶ added in v1.4.4
type FindRunbookToolConfig struct {
// EmbeddingModel is the embedding model id, e.g.
// "text-embedding-3-small". Required to register the tool; empty
// leaves find_runbook unregistered.
EmbeddingModel string `mapstructure:"embedding_model"`
}
FindRunbookToolConfig configures the read-only `find_runbook` runbook-RAG tool. The tool is opt-in: it is registered only when an embedding model is configured (and a runbook corpus exists). An empty `EmbeddingModel` leaves the tool unregistered, so a community install behaves exactly as before.
The runbook corpus directory lives in the data folder under `runbooks/` (`./data/runbooks`; `/app/data/runbooks` in the container image); place your `*.md` runbooks there. The server auto-ingests them at boot (incrementally — only new or edited runbooks are embedded), so no separate step is needed.
Example (tools.yaml):
tools:
find_runbook:
embedding_model: text-embedding-3-small
The embeddings endpoint reuses the shared AI credential (`agent.ai.api_key`): there is no separate embedding key to manage. A local OpenAI-compatible server that does not authenticate ignores the bearer token.
type GitAuthConfig ¶ added in v1.4.3
type GitAuthConfig struct {
// Token is an HTTPS access token / personal access token used for
// https:// remotes (sent via an Authorization header, never persisted
// to the local mirror's config).
Token string `mapstructure:"token"`
// SSHKeyPath is the path to a private SSH key used for ssh:// or
// scp-like (git@host:org/repo) remotes.
SSHKeyPath string `mapstructure:"ssh_key_path"`
}
GitAuthConfig holds the credentials used to authenticate to a remote git repository. Both fields are optional; an empty config relies on the ambient git credentials (credential helper / default SSH keys).
type IncidentioConfig ¶ added in v1.4.4
type LarkConfig ¶ added in v1.3.1
type MSTeamsConfig ¶
type MSTeamsConfig struct {
Enable bool
TemplatePath string `mapstructure:"template_path"`
OtherPowerURLs map[string]string `mapstructure:"other_power_urls"` // Optional alternative Power Automate URLs
// Power Automate Workflow URL for Teams integration
PowerAutomateURL string `mapstructure:"power_automate_url"`
}
type OnCallConfig ¶
type OnCallConfig struct {
Enable bool
InitializedOnly bool `mapstructure:"initialized_only"` // Initialize infrastructure but don't enable by default
WaitMinutes int `mapstructure:"wait_minutes"`
Provider string `mapstructure:"provider"` // "aws_incident_manager", "pagerduty", "servicenow" or "incident_io"
AwsIncidentManager AwsIncidentManagerConfig `mapstructure:"aws_incident_manager"`
PagerDuty PagerDutyConfig `mapstructure:"pagerduty"`
ServiceNow ServiceNowConfig `mapstructure:"servicenow"`
Incidentio IncidentioConfig `mapstructure:"incident_io"`
}
type PagerDutyConfig ¶ added in v1.3.0
type ProxyConfig ¶ added in v1.3.7
type PubSubConfig ¶
type PubSubConfig struct {
Enable bool `mapstructure:"enable"`
}
type QueryMetricsPrometheusConfig ¶ added in v1.4.4
type QueryMetricsPrometheusConfig struct {
// Address is the Prometheus base URL, e.g. "http://prometheus:9090".
// Empty leaves the `query_metrics` tool unregistered.
Address string `mapstructure:"address"`
// BearerToken is sent as `Authorization: Bearer <token>` when set.
BearerToken string `mapstructure:"bearer_token"`
// Username/Password enable HTTP Basic auth (used when BearerToken is
// empty).
Username string `mapstructure:"username"`
Password string `mapstructure:"password"`
// InsecureSkipVerify disables TLS verification (dev only).
InsecureSkipVerify bool `mapstructure:"insecure_skip_verify"`
}
QueryMetricsPrometheusConfig points the `query_metrics` tool at a Prometheus HTTP query endpoint. Auth mirrors the prometheus SignalSource: bearer token takes priority over HTTP Basic.
type QueryMetricsToolConfig ¶ added in v1.4.4
type QueryMetricsToolConfig struct {
Prometheus QueryMetricsPrometheusConfig `mapstructure:"prometheus"`
}
QueryMetricsToolConfig configures the read-only `query_metrics` tool. The tool runs on-demand PromQL range queries against a Prometheus endpoint, independent of the detect-path prometheus SignalSource, so an analysis can pull arbitrary metric series. With an empty `Prometheus.Address` the tool is not registered (a community install without a metric backend behaves exactly as before).
type QueryTracesTempoConfig ¶ added in v1.4.4
type QueryTracesTempoConfig struct {
// Address is the Tempo base URL, e.g. "http://tempo:3200". Empty
// leaves the `query_traces` tool unregistered.
Address string `mapstructure:"address"`
// BearerToken is sent as `Authorization: Bearer <token>` when set.
BearerToken string `mapstructure:"bearer_token"`
// Username/Password enable HTTP Basic auth (used when BearerToken is
// empty).
Username string `mapstructure:"username"`
Password string `mapstructure:"password"`
// InsecureSkipVerify disables TLS verification (dev only).
InsecureSkipVerify bool `mapstructure:"insecure_skip_verify"`
}
QueryTracesTempoConfig points the `query_traces` tool at a Tempo HTTP search endpoint. Auth mirrors the traces SignalSource.
type QueryTracesToolConfig ¶ added in v1.4.4
type QueryTracesToolConfig struct {
Tempo QueryTracesTempoConfig `mapstructure:"tempo"`
}
QueryTracesToolConfig configures the read-only `query_traces` tool. The tool runs on-demand trace searches against a Tempo-compatible backend. With an empty `Tempo.Address` the tool is not registered.
type QueueConfig ¶
type QueueConfig struct {
Enable bool `mapstructure:"enable"`
DebugBody bool `mapstructure:"debug_body"`
SNS SNSConfig `mapstructure:"sns"`
SQS SQSConfig `mapstructure:"sqs"`
PubSub PubSubConfig `mapstructure:"pubsub"`
AzBus AzBusConfig `mapstructure:"azbus"`
}
type RecentChangesGitConfig ¶ added in v1.4.3
type RecentChangesGitConfig struct {
// Auth is the global default authentication applied to every repo that
// does not define its own. Empty means rely on the ambient git
// credentials (credential helper / default SSH keys).
Auth GitAuthConfig `mapstructure:"auth"`
// Repos is the set of remote git repositories to read commits from.
// Empty leaves the `recent_changes` tool unregistered.
Repos []RecentChangesGitRepo `mapstructure:"repos"`
}
RecentChangesGitConfig points the `recent_changes` tool at one or more remote git repositories. The tool shells out to the `git` binary (which must be on PATH), so no Go git dependency is pulled in and no separate event pipeline is required: the deploy/change record is the commit log the team already keeps. Each repository is mirror-cloned into a local cache on first use and fetched on subsequent lookups.
Example (tools.yaml):
tools:
recent_changes:
git:
auth: # global default auth
token: ${GIT_TOKEN} # HTTPS token / PAT
ssh_key_path: /home/versus/.ssh/id_ed25519
repos:
- url: https://github.com/acme/api.git # remote clone URL
branch: main # optional; empty = default HEAD
service: api # optional; empty = derived from URL
- url: git@github.com:acme/web.git # service auto-detected as "web"
auth: # optional; overrides the global auth
ssh_key_path: /home/versus/.ssh/web_deploy
An empty Repos list leaves the `recent_changes` tool unregistered.
type RecentChangesGitRepo ¶ added in v1.4.3
type RecentChangesGitRepo struct {
// URL is the remote clone URL (https or scp-like git@host:org/repo).
// Empty entries are ignored.
URL string `mapstructure:"url"`
// Branch optionally pins which branch to read. Empty reads the
// repository's default HEAD.
Branch string `mapstructure:"branch"`
// Service maps every commit in this repository to a service name. When
// empty the service is auto-detected from the repository name in the
// URL (e.g. git@github.com:acme/web.git → "web").
Service string `mapstructure:"service"`
// Auth optionally overrides the global git auth for this repo. Empty
// fields fall back to the global default in RecentChangesGitConfig.
Auth GitAuthConfig `mapstructure:"auth"`
}
RecentChangesGitRepo is one remote git repository the change feed reads.
type RecentChangesToolConfig ¶ added in v1.4.3
type RecentChangesToolConfig struct {
// Git points the tool at a set of remote git repositories' commit
// histories. An empty Repos list leaves the tool unregistered.
Git RecentChangesGitConfig `mapstructure:"git"`
}
RecentChangesToolConfig configures the `recent_changes` tool. Today the only supported change source is one or more remote git repositories.
type RedisConfig ¶
type RedisConfig struct {
Host string `mapstructure:"host"`
Port int `mapstructure:"port"`
Password string `mapstructure:"password"`
DB int `mapstructure:"db"`
TLS *bool `mapstructure:"tls"`
InsecureSkipVerify bool `mapstructure:"insecure_skip_verify"`
Cluster *bool `mapstructure:"cluster"`
}
func (RedisConfig) ClusterEnabled ¶ added in v1.4.10
func (r RedisConfig) ClusterEnabled() bool
ClusterEnabled reports whether the Redis client should be built in cluster mode (redis.NewClusterClient) so it follows MOVED/ASK redirects across shards — required for AWS ElastiCache Valkey/Redis in cluster mode. Single-node is the default: a nil flag (key omitted) preserves today's behaviour. Set redis.cluster: true (or REDIS_CLUSTER=true) to opt in.
func (RedisConfig) TLSEnabled ¶ added in v1.4.4
func (r RedisConfig) TLSEnabled() bool
TLSEnabled reports whether the Redis client should dial over TLS. TLS is the default: a nil flag (key omitted from config) preserves the historical always-TLS behaviour. Set redis.tls: false (or REDIS_TLS=false) to dial a plaintext Redis such as a local/dev redis:7-alpine.
type ServiceDependency ¶ added in v1.4.3
type ServiceDependency struct {
Name string `mapstructure:"name"`
DependsOn []string `mapstructure:"depends_on"`
}
ServiceDependency is one node in the optional service-dependency graph. `DependsOn` lists the upstream services this service relies on; the reverse (downstream) edges are derived automatically.
type ServiceNowConfig ¶ added in v1.4.4
type ServiceNowConfig struct {
InstanceURL string `mapstructure:"instance_url"`
Username string `mapstructure:"username"`
Password string `mapstructure:"password"`
Table string `mapstructure:"table"` // ServiceNow table to create records in; defaults to "incident"
OtherInstanceURLs map[string]string `mapstructure:"other_instance_urls"`
}
type SlackConfig ¶
type SlackConfig struct {
Enable bool
Token string
ChannelID string `mapstructure:"channel_id"`
TemplatePath string `mapstructure:"template_path"`
MessageProperties SlackMessageProperties `mapstructure:"message_properties"`
}
type SlackMessageProperties ¶ added in v1.3.3
type StorageConfig ¶ added in v1.3.9
type StorageConfig struct {
Type string `mapstructure:"type"` // file | redis | database | postgres (default: file)
File StorageFileConfig `mapstructure:"file"`
Redis StorageRedisConfig `mapstructure:"redis"`
Database StorageDatabaseConfig `mapstructure:"database"`
Postgres StoragePostgresConfig `mapstructure:"postgres"`
}
StorageConfig is the durable-storage block. It is the single source of truth for where the agent persists its catalog/shadow log AND where the incident service writes incident history. Type-specific sub-blocks are only consulted when `type` matches.
type StorageDatabaseConfig ¶ added in v1.3.9
type StorageDatabaseConfig struct {
Driver string `mapstructure:"driver"` // postgres | mysql | sqlite
DSN string `mapstructure:"dsn"`
}
StorageDatabaseConfig is the database backend's options. Stub today.
type StorageFileConfig ¶ added in v1.3.9
type StorageFileConfig struct {
MaxIncidents int `mapstructure:"max_incidents"` // rolling cap; default 1000
}
StorageFileConfig is the file backend's options. Only consulted when storage.type == "file".
type StoragePostgresConfig ¶ added in v1.4.4
type StoragePostgresConfig struct {
DSN string `mapstructure:"dsn"` // env: POSTGRES_DSN
}
StoragePostgresConfig is the Postgres backend options. Activated when storage.type == "postgres". A single Postgres backend stores incidents, analyses, and blobs — no separate object store needed.
type StorageRedisConfig ¶ added in v1.3.9
type StorageRedisConfig struct {
Host string `mapstructure:"host"`
Port int `mapstructure:"port"`
Password string `mapstructure:"password"`
DB int `mapstructure:"db"`
InsecureSkipVerify bool `mapstructure:"insecure_skip_verify"`
KeyPrefix string `mapstructure:"key_prefix"`
MaxIncidents int `mapstructure:"max_incidents"`
}
StorageRedisConfig is the redis backend's options. Stub today.
type TelegramConfig ¶
type ToolsConfig ¶ added in v1.4.3
type ToolsConfig struct {
// ToolTimeout caps how long a single tool dispatch may run before it
// is abandoned, e.g. "20s". A timeout surfaces as a tool error in the
// audit trace (not a hard failure) so one slow tool cannot consume
// the whole analysis budget. Empty, "0", or an unparseable value
// inherits the built-in default (20s).
ToolTimeout string `mapstructure:"tool_timeout"`
// ParallelTools controls whether multiple tool calls emitted in one
// model turn run concurrently. Off by default: tool dispatch is
// sequential, which keeps load on downstream sources predictable. The
// per-call audit trace is ordered deterministically regardless.
ParallelTools bool `mapstructure:"parallel_tools"`
// RecentChanges configures the `recent_changes` tool.
RecentChanges RecentChangesToolConfig `mapstructure:"recent_changes"`
// DescribeDependencies configures the `describe_dependencies` tool.
DescribeDependencies DescribeDependenciesToolConfig `mapstructure:"describe_dependencies"`
// FindRunbook configures the `find_runbook` runbook-RAG tool.
FindRunbook FindRunbookToolConfig `mapstructure:"find_runbook"`
// QueryMetrics configures the `query_metrics` tool's Prometheus reader.
QueryMetrics QueryMetricsToolConfig `mapstructure:"query_metrics"`
// QueryTraces configures the `query_traces` tool's trace-backend reader.
QueryTraces QueryTracesToolConfig `mapstructure:"query_traces"`
}
ToolsConfig groups the configurable analyze-mode tools by tool name. It also carries the shared tool-loop knobs (tool_timeout, parallel_tools) that apply to every analyze tool dispatch.
type ViberConfig ¶ added in v1.3.7
type ViberConfig struct {
Enable bool
APIType string `mapstructure:"api_type"` // "bot" or "channel" - defaults to "channel"
// Bot API configuration
BotToken string `mapstructure:"bot_token"`
UserID string `mapstructure:"user_id"`
TemplatePath string `mapstructure:"template_path"`
// Channel configuration for Channels Post API
ChannelID string `mapstructure:"channel_id"`
UseProxy bool `mapstructure:"use_proxy"`
}