← All ivy-agents
IVYXSTUDIO · IVY AGENT
I

Incident Escalation

ivy.agent.incident-escalation · v1.0.0

ivyx

Takes a monitoring alert, has Jev rate its severity, and for a high one opens a GitHub issue, posts to Slack and mails on-call; otherwise logs it through your API.

Steps

In the order the agent's file lists them, each with where its inputs come from and the values the file fixes. A branch or a loop is a step too.

  1. 01
    Rate the severity
    ivy.node.jev-score

    Asks TypeSafe Jev where a text or JSON state sits on an ordered scale of 2 to 10 described levels and returns a score from 0 to the top level with the nearest level, its description and the confidence.

    takes
    state from the agent's input, payload
    set
    instructions Rate the severity of this incident on these levels: low, medium, high. Customers unable to use a service is high; a r...
    levels ["low","medium","high"]
    secret
    jev_api_key the stored secret jev-api-key
    returns
    severity
    Ivy Node
  2. 02
    Write the title
    ivy.node.template-render

    Fills {{ name }} placeholders in a text template from a mapping, and reports which names were missing.

    takes
    values from the agent's input, payload
    set
    template Incident on {{ service }}: {{ message }}
    on_missing empty
    returns
    title
    Ivy Node
  3. 03
    Only a high severity

    Lets what follows run only when is.high of step 1 is true.

    Branch
  4. 04
    Open the issue
    ivy.node.http-request

    Sends one HTTP request to a URL and returns the status, headers and body, parsed as JSON when the response is JSON.

    Runs only on the then branch of step 3.

    takes
    url from the agent's input, issues_url
    json.title from step 2, text
    json.body from the agent's input, payload.message
    set
    method POST
    secret
    token the stored secret github-token
    returns
    escalated, issue_url
    Ivy Node
  5. 05
    Alert the channel
    ivy.node.http-request

    Sends one HTTP request to a URL and returns the status, headers and body, parsed as JSON when the response is JSON.

    Runs only on the then branch of step 3.

    takes
    json.text from step 2, text
    set
    method POST
    secret
    url the stored secret slack-webhook-url
    Ivy Node
  6. 06
    Page on-call
    ivy.node.email-send

    Sends a plain-text or HTML email through an SMTP server in one step and returns the recipients it went to.

    Runs only on the then branch of step 3.

    takes
    subject from step 2, text
    body from the agent's input, payload.message
    from_addr from the agent's input, username
    username from the agent's input
    to from the agent's input
    smtp_host from the agent's input
    smtp_port from the agent's input
    use_tls from the agent's input, smtp_tls
    set
    smtp_host smtp.gmail.com
    smtp_port 587
    use_tls true
    secret
    password the stored secret mail-password
    returns
    sent
    Ivy Node
  7. 07
    Log the alert
    ivy.node.http-request

    Sends one HTTP request to a URL and returns the status, headers and body, parsed as JSON when the response is JSON.

    Runs only on the else branch of step 3.

    takes
    url from the agent's input, log_url
    json.service from the agent's input, payload.service
    json.level from step 1, level_text
    json.message from the agent's input, payload.message
    set
    method POST
    secret
    token the stored secret saas-api-key
    returns
    logged
    Ivy Node

Nodes it brings

Adding this agent in IVYX Studio adds these nodes with it. A node your workspace already has is kept as it is, even at another version.

What it touches

Collected from what each of its nodes declares, plus the model call when a step is a model turn. A declaration is the author's statement, and it is what policy rules select on.

message-sendNetwork

What it needs

  • A stored secret named github-token. The agent's file carries the name, never the value.
  • A stored secret named jev-api-key. The agent's file carries the name, never the value.
  • A stored secret named mail-password. The agent's file carries the name, never the value.
  • A stored secret named saas-api-key. The agent's file carries the name, never the value.
  • A stored secret named slack-webhook-url. The agent's file carries the name, never the value.

Inputs

FieldTypeDescription
payloadrequiredobjectThe event your service posted: service, message and metrics of the alert.
issues_urlrequiredstringThe repository's issues endpoint, such as https://api.github.com/repos/<owner>/<repo>/issues. The stand-in's address is used in the cases.
log_urlrequiredstringYour API's log endpoint; a POST records an alert that was not escalated. The stand-in's address is used in the cases.
usernamerequiredstringThe sending address, which is the login name; its password is the stored secret mail-password.
torequiredstringThe on-call address.
smtp_hoststringThe SMTP server; smtp.gmail.com when left out.
smtp_portintegerThe SMTP port; 587 when left out.
smtp_tlsbooleanUpgrade SMTP with STARTTLS; on when left out.

Outputs

FieldTypeDescription
severitystringlow, medium or high.
escalatedbooleanTrue once GitHub accepted the issue; absent when not escalated.
issue_urlstringThe issue's page; absent when not escalated.
sentbooleanTrue once the server accepted the mail to on-call; absent when not escalated.
loggedbooleanTrue once your API recorded the alert; absent when escalated.
titlestringThe one-line title of the alert.

Tests

2 of 2 test cases passed on Oct 7, 2026, in the publisher's own environment, before this version was published. The registry keeps that record; it does not run the cases again.

Requires: python:3.9, the stored secret jev-api-key, a GitHub token stored as the secret github-token, a Slack incoming webhook URL stored as the secret slack-webhook-url, your own API's key stored as the secret saas-api-key, an SMTP server (Gmail unless smtp_host says otherwise) with the sending account's password stored as the secret mail-password, for the cases, GreenMail on 127.0.0.1:3025 (mkdata-mail.py), for the cases, the stand-in API on 127.0.0.1:18910 (api-standin.py), which the secrets crm-1, gh-1, saas-1 and the stand-in's /slack/hook address satisfy

  • payments-down

    Every payment request failing is high: an issue, a Slack alert and a page to on-call.

    given
    smtp_host 127.0.0.1
    smtp_port 3025
    smtp_tls false
    payload {"service":"payments-api","message":"100% of requests failing with 503 since 09:12 UTC; customers cannot pay","metric...
    issues_url http://127.0.0.1:18910/repos/acme/app/issues
    log_url http://127.0.0.1:18910/log
    username agent@ivyx.test
    to agent@ivyx.test
    expects
    severity equals high
    escalated equals true
    issue_url matches issues/\d+$
    sent equals true
    title matches ^Incident on payments-api
  • disk-warning

    A disk at 70% with no customer impact is low or medium: only the log hears.

    given
    smtp_host 127.0.0.1
    smtp_port 3025
    smtp_tls false
    payload {"service":"reports-worker","message":"Disk usage at 70% on worker-3; no customer impact, cleanup scheduled","metrics...
    issues_url http://127.0.0.1:18910/repos/acme/app/issues
    log_url http://127.0.0.1:18910/log
    username agent@ivyx.test
    to agent@ivyx.test
    expects
    severity matches ^(low|medium)$
    logged equals true