Documentation
¶
Overview ¶
Package alert implements the native `alert` built-in tool: a config-driven, distroless-safe way for a headless core-agent daemon to fire escalations to pre-registered webhook targets (Slack, Discord, PagerDuty, generic JSON) without shelling out or running a separate MCP server. The design lives in docs/alert-tool-design.md.
SSRF is impossible by construction: the tool exposes no arbitrary-URL parameter — the model picks a target by NAME from the operator's registry, and an unknown name is rejected rather than dialed.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func HasLiveTarget ¶
HasLiveTarget reports whether any configured target can be delivered to. pkg/tools.Build uses it as the second half of `alert`'s registration gate, so a build whose every target is unresolvable registers no alert tool at all rather than one that cannot fire.
Types ¶
type Args ¶
type Args struct {
Target string `` /* 150-byte string literal not displayed */
Level string `json:"level" jsonschema:"required; severity of the alert: one of info, warning, critical, resolved"`
Summary string `json:"summary" jsonschema:"required; a one-line human-readable summary of what happened"`
Details map[string]any `` /* 158-byte string literal not displayed */
}
Args is the tool's input. Auth material is deliberately absent — it is resolved from env at call time and never appears in the schema or the audited args (design §Security).
type DeadTarget ¶
DeadTarget is a configured target this process cannot deliver to, paired with the operator-facing reason.
func PartitionTargets ¶
func PartitionTargets(cfg *config.Config) (live []config.AlertTarget, dead []DeadTarget)
PartitionTargets splits cfg's registry into the targets this process can actually fire and those it cannot.
A target whose url_env (or auth env) is unset can never deliver: a process's environment is fixed at exec time, so "unset now" means "unset for this process's whole life" — a Secret edit needs a pod restart either way. Registering it anyway hands the model an escalation path that fails at the one moment it is needed. A live 2026-08-14 run called `alert` at the end of an incident it could not resolve and learned only then that nobody had been paged; the target had been advertised in the tool description all along.
Same rule as the built-in descriptions (#759), one layer down: never name a capability the deployment doesn't have.
type Result ¶
type Result struct {
Target string `json:"target"`
StatusCode int `json:"status_code"`
DurationMs int64 `json:"duration_ms"`
}
Result is the tool's output. Response BODY is intentionally excluded — it may carry PII from the destination and could be a smuggle channel back to the model; only the status code and duration are returned.