Documentation
¶
Index ¶
- Variables
- func InitOnCallWorkflow(awsClient *ssmincidents.Client, redisClient *redis.Client)
- type AIAgent
- type AICallResult
- type AIFinding
- type AITask
- type AITaskKind
- type AgentResult
- type AgentVerdict
- type Alert
- type AlertProvider
- type AlertResult
- type AnalyzeIncidentSnapshot
- type AnalyzeTask
- type AnalyzeTool
- type DetectTask
- type Detector
- type EvidenceItem
- type OnCallProvider
- type OnCallWorkflow
- type QueueListener
- type RootCauseHypothesis
- type Signal
- type SignalSource
- type ToolCallTrace
- type ToolResult
Constants ¶
This section is empty.
Variables ¶
var CreateOnCallProvider func(cfg *config.Config, awsClient *ssmincidents.Client) (OnCallProvider, error)
Function that will be implemented in the common package to avoid circular imports
Functions ¶
func InitOnCallWorkflow ¶
func InitOnCallWorkflow(awsClient *ssmincidents.Client, redisClient *redis.Client)
InitOnCallWorkflow initializes the global singleton instance This is called once from main.go with the Redis client and AWS client
Types ¶
type AIAgent ¶ added in v1.4.3
type AIAgent interface {
Name() string
Kind() AITaskKind
Run(ctx context.Context, task AITask) (*AICallResult, error)
}
AIAgent is one concrete model + prompt + (optional) tool wiring, dedicated to a single AITaskKind. Implementations live under pkg/agent/ai (e.g. detect, analyze).
Run is expected to be self-contained: it owns the model call, but the router handles cache / rate-limit / persistence around it.
type AICallResult ¶ added in v1.4.0
type AICallResult struct {
Finding *AIFinding
UserPrompt string
RawResponse string
DurationMs int64
Model string
// ToolCalls is populated by tool-using agents (analyze). It is
// nil for tool-free agents (detect).
ToolCalls []ToolCallTrace
}
AICallResult bundles the parsed finding with the inputs and outputs of the underlying model call. The trace fields (UserPrompt, RawResponse, DurationMs, Model) are persisted into the detect log so operators can audit what was sent to the model and what came back.
SystemPrompt is intentionally omitted — it is a constant per build and would bloat every record. Operators can fetch the current assembled system prompt via the agent admin API.
type AIFinding ¶ added in v1.3.9
type AIFinding struct {
Title string
Summary string
Severity string // critical|high|medium|low
Category string // e.g. "database", "auth", "deploy"
Confidence float64 // 0..1
Suggestions []string
SampleIDs []string // signal IDs / pattern IDs for traceability
// Analyze-mode fields. All optional; omitempty so detect-mode
// payloads stay byte-compatible with the pre-E1 shape.
RootCauseHypotheses []RootCauseHypothesis `json:"root_cause_hypotheses,omitempty"`
Evidence []EvidenceItem `json:"evidence,omitempty"`
RelatedPatternIDs []string `json:"related_pattern_ids,omitempty"`
NextSteps []string `json:"next_steps,omitempty"`
}
AIFinding is the structured response returned by an AISRE for an unknown / spiking pattern. Used by detect mode.
Detect mode populates Title, Summary, Severity, Category, Confidence, Suggestions, SampleIDs. The lower block (RootCauseHypotheses, Evidence, RelatedPatternIDs, NextSteps) is populated by analyze mode only; detect leaves them empty and they marshal as omitempty.
type AITask ¶ added in v1.4.3
type AITask interface {
Kind() AITaskKind
CacheKey() string
}
AITask is the input to an AIAgent.Run call. Each concrete task type carries the inputs needed by its kind and exposes a CacheKey() the router uses for memoisation. An empty CacheKey disables caching for that call.
type AITaskKind ¶ added in v1.4.3
type AITaskKind string
AITaskKind identifies what an AIAgent is being asked to do.
The dispatcher uses the kind to pick the right agent, cache, and rate limiter. New kinds are added by extending this enum and the router's wiring.
const ( // AITaskDetect is a cheap, tool-free, single-call classification of // an unknown or spiking log pattern. The output is an AIFinding // emitted as an incident through services.CreateIncidentFromFinding. AITaskDetect AITaskKind = "detect" // AITaskAnalyze is an operator-triggered, tool-using investigation // of a single incident. The output is an AIFinding persisted to the // analyses storage blob. Analyze NEVER fans out to notification // channels. AITaskAnalyze AITaskKind = "analyze" )
type AgentResult ¶ added in v1.3.9
type AgentResult struct {
Verdict AgentVerdict
PatternID string // empty when VerdictUnknown and pattern not yet stored
Template string // human-readable pattern template ("Failed to ... at <*>:<*>")
SampleSignals []Signal // representative signals (capped, post-redaction)
Frequency int // matches in the current tick / window
Baseline float64 // EWMA baseline for the pattern (0 when unknown)
}
AgentResult is the output of a Detector for one batch of signals that share the same fingerprint.
type AgentVerdict ¶ added in v1.3.9
type AgentVerdict int
AgentVerdict is the classification a Detector pipeline assigns to a batch of signals that share a fingerprint.
const ( // VerdictKnownPattern means the pattern is in the catalog and current // frequency is within baseline — suppress (no AI, no incident). VerdictKnownPattern AgentVerdict = iota // VerdictUnknown means the pattern was never seen during training — // forward to AI for analysis. VerdictUnknown // VerdictSpike means the pattern is known but frequency exceeds the // baseline by more than the configured threshold — forward to AI. VerdictSpike )
func (AgentVerdict) String ¶ added in v1.3.9
func (v AgentVerdict) String() string
String renders an AgentVerdict for logging.
type Alert ¶
type Alert struct {
// contains filtered or unexported fields
}
func NewAlert ¶
func NewAlert(providers ...AlertProvider) *Alert
func (*Alert) SendAlert ¶
SendAlert is the legacy "first error wins" API. New code should use SendAllAlerts so a flaky Slack does not silently mute Telegram and Email. Kept here so external callers (and existing tests) compile without churn; internally we now delegate to SendAllAlerts and surface only the joined error.
func (*Alert) SendAllAlerts ¶ added in v1.4.0
func (a *Alert) SendAllAlerts(incident *m.Incident) AlertResult
SendAllAlerts tries every configured provider regardless of earlier failures. A single broken channel never prevents the others from firing — this is the multi-channel promise. The returned Err is non-nil iff at least one provider failed.
type AlertProvider ¶
AlertProvider is implemented by every notification channel (Slack, Telegram, MS Teams, Lark, Viber, Email, …). Name() identifies the channel in failure reports so operators can tell which one failed without parsing the wrapped error.
type AlertResult ¶ added in v1.4.0
type AlertResult struct {
Succeeded []string
Failed map[string]error
Err error // joined errors from Failed, nil when none
}
AlertResult captures the outcome of SendAllAlerts: which providers succeeded, which failed (with their error), and a joined error containing all failures (nil when every provider succeeded). The list of Succeeded channel names is what the incident persistence layer should store as ChannelsNotified — it is the truth about what actually reached its destination, not a list of what was enabled in config.
type AnalyzeIncidentSnapshot ¶ added in v1.4.3
type AnalyzeIncidentSnapshot struct {
IncidentID string `json:"incident_id"`
Title string `json:"title,omitempty"`
Service string `json:"service,omitempty"`
Source string `json:"source,omitempty"`
Severity string `json:"severity,omitempty"`
Resolved bool `json:"resolved,omitempty"`
CreatedAt time.Time `json:"created_at,omitempty"`
AckedAt *time.Time `json:"acked_at,omitempty"`
ResolvedAt *time.Time `json:"resolved_at,omitempty"`
// Content is the alert payload (the same map persisted on the
// incident record). Operators see this verbatim in the UI.
Content map[string]any `json:"content,omitempty"`
// RequestedBy identifies the operator that triggered the analysis
// (gateway-authenticated, so today this is just a free-form label
// like "admin"). Stored on the AnalysisRecord for audit.
RequestedBy string `json:"requested_by,omitempty"`
}
AnalyzeIncidentSnapshot is the input payload handed to the analyze-kind AIAgent. It captures the minimal incident metadata the agent needs to plan its tool calls; richer context (related logs, nearby incidents, pattern history) is fetched on demand via the agent's read-only tools, not pre-loaded into the snapshot.
The struct deliberately does not import pkg/storage — `pkg/core` must stay leaf-level. Callers (the admin controller, the worker) flatten storage records into this shape.
type AnalyzeTask ¶ added in v1.4.3
type AnalyzeTask struct {
Snapshot AnalyzeIncidentSnapshot
}
AnalyzeTask wraps an on-demand analysis request. The snapshot carries the incident payload the agent inspects; richer context (related logs, pattern history) is fetched via the agent's read-only tools at run time, not pre-loaded here.
func (AnalyzeTask) CacheKey ¶ added in v1.4.3
func (t AnalyzeTask) CacheKey() string
CacheKey implements AITask. Empty disables caching — operators expect a fresh tool walk on every analyze request.
func (AnalyzeTask) Kind ¶ added in v1.4.3
func (AnalyzeTask) Kind() AITaskKind
Kind implements AITask.
type AnalyzeTool ¶ added in v1.4.3
type AnalyzeTool interface {
// Name is the model-visible tool name. Must be a stable identifier
// (snake_case is the convention).
Name() string
// Description is the one-line model-visible doc. The model uses it
// to decide when to call the tool.
Description() string
// ArgsSchema returns a JSON schema (drafted as a generic map) for
// the tool's argument object. Eino converts this into the model's
// tool-call schema.
ArgsSchema() map[string]any
// Invoke runs the tool with the model-provided JSON args. The
// returned ToolResult is serialised to JSON and fed back to the
// model as the tool message. Errors are surfaced to the model as
// a tool error so it can adapt.
Invoke(ctx context.Context, args json.RawMessage) (*ToolResult, error)
}
AnalyzeTool is the contract every analyze-side read-only tool satisfies. Tools are registered with the analyze agent at construction time; the agent surfaces them to the model as Eino ToolInfo and dispatches model-requested calls back to this interface.
Implementations MUST be read-only. The compile-time guard in pkg/agent/ai/analyze rejects any import of services.CreateIncident transitively.
type DetectTask ¶ added in v1.4.3
type DetectTask struct {
Result AgentResult
}
DetectTask wraps an AgentResult for detect-mode classification.
func (DetectTask) CacheKey ¶ added in v1.4.3
func (t DetectTask) CacheKey() string
CacheKey implements AITask. Detect memoisation is keyed by pattern id; an empty pattern id (unknown pattern not yet stored) disables caching for that call.
func (DetectTask) Kind ¶ added in v1.4.3
func (DetectTask) Kind() AITaskKind
Kind implements AITask.
type Detector ¶ added in v1.3.9
type Detector interface {
Name() string
Process(ctx context.Context, batch []Signal) ([]AgentResult, error)
}
Detector consumes signals and emits AgentResults.
type EvidenceItem ¶ added in v1.4.3
type EvidenceItem struct {
Source string `json:"source"`
Summary string `json:"summary"`
Detail string `json:"detail,omitempty"`
}
EvidenceItem records one piece of supporting evidence the analyze agent gathered (typically from a tool call). Source identifies where it came from (e.g. "tool:get_related_logs"); Summary is a one-liner shown in the UI; Detail is the long form (capped on persist).
type OnCallProvider ¶ added in v1.3.0
type OnCallProvider interface {
TriggerOnCall(ctx context.Context, incidentID string, cfg *config.OnCallConfig) error
}
OnCallProvider defines the interface for on-call notification providers
type OnCallWorkflow ¶
type OnCallWorkflow struct {
// contains filtered or unexported fields
}
OnCallWorkflow coordinates on-call escalation with a single provider
func GetOnCallWorkflow ¶
func GetOnCallWorkflow() *OnCallWorkflow
GetOnCallWorkflow returns the global singleton instance This maintains compatibility with existing code
func NewOnCallWorkflow ¶ added in v1.3.0
func NewOnCallWorkflow(redisClient *redis.Client, provider OnCallProvider) *OnCallWorkflow
NewOnCallWorkflow creates a new on-call workflow with the given provider
func (*OnCallWorkflow) Ack ¶
func (w *OnCallWorkflow) Ack(incidentID string) error
Ack acknowledges an incident to prevent escalation
func (*OnCallWorkflow) Start ¶
func (w *OnCallWorkflow) Start(incidentID string, oc config.OnCallConfig) error
Start initiates the on-call workflow for an incident
type QueueListener ¶
type RootCauseHypothesis ¶ added in v1.4.3
type RootCauseHypothesis struct {
Hypothesis string `json:"hypothesis"`
Confidence float64 `json:"confidence"`
Rationale string `json:"rationale,omitempty"`
}
RootCauseHypothesis is one candidate explanation produced by an analyze-mode agent. Confidence is in [0, 1]; Rationale is a short human-readable justification.
type Signal ¶ added in v1.3.9
type Signal struct {
Source string // e.g. "elasticsearch:prod-app"
Timestamp time.Time
Severity string // raw severity from source, best-effort
Message string // primary text payload
Fields map[string]interface{} // structured fields
Raw map[string]interface{} // original document (capped size)
}
Signal is one normalized observation pulled from a SignalSource.
Fields holds best-effort structured fields; Raw is the original source document (capped to AgentConfig.SignalMaxBytes by the SignalSource so the pipeline cannot OOM on large documents).
type SignalSource ¶ added in v1.3.9
type SignalSource interface {
// Name uniquely identifies the configured source instance. It is used as
// part of Redis cursor keys, so it must be stable across restarts.
Name() string
// Pull returns all signals strictly newer than `since`, plus the new
// cursor (== max timestamp seen, or `since` if no signals were returned).
Pull(ctx context.Context, since time.Time) ([]Signal, time.Time, error)
}
SignalSource is a puller for one external observability backend (Elasticsearch, Loki, CloudWatch, ...).
type ToolCallTrace ¶ added in v1.4.3
ToolCallTrace is one model-issued tool round-trip captured for audit.
type ToolResult ¶ added in v1.4.3
type ToolResult struct {
Tool string `json:"tool"`
Found bool `json:"found"`
Data map[string]any `json:"data,omitempty"`
}
ToolResult is the uniform envelope every AnalyzeTool returns. The shape is stable so the model sees a predictable schema across tools; the per-tool payload lives in Data as JSON-encodable values.
Tool — the tool name (mirrors AnalyzeTool.Name) so a model parsing multiple tool responses can disambiguate without relying on call ordering.
Found — optional flag for lookup-style tools (pattern_history, describe_service) to signal "no such entity" without an error. Defaults to true; lookups that miss should set it to false and leave Data empty (or populated with just the query echo).
Data — the typed payload. Keys are tool-specific; values must be JSON-marshalable (no channels, funcs, or unexported structs).