Swirls

SWIRLS_

  • How it works
  • Pricing

56 matches

OverviewDeliver client operations10Win and grow accounts8Resolve customer issues6Create and distribute content9Run people and operations5Review money and agreements3Monitor systems and data9Compose dependable work6

56 matches

OverviewDeliver client operations10Win and grow accounts8Resolve customer issues6Create and distribute content9Run people and operations5Review money and agreements3Monitor systems and data9Compose dependable work6
← Customer SupportFormView on GitHub

Bug Report Triage

Classifies bug severity, assigns priority, notifies the right Slack channel, and emails the reporter.

aiswitchhttpemail

Source

/**
 * Triages incoming bug reports. Classifies severity, assigns priority,
 * and sends to the right team channel.
 */

form bug_report {
  label: "Bug Report"
  schema: @json {
    {
      "type": "object",
      "required": ["title", "description", "reporter_email"],
      "properties": {
        "title": { "type": "string", "title": "Bug Title" },
        "description": { "type": "string", "title": "Description" },
        "steps_to_reproduce": { "type": "string", "title": "Steps to Reproduce" },
        "reporter_email": { "type": "string", "format": "email", "title": "Reporter Email" },
        "component": {
          "type": "string",
          "title": "Component",
          "enum": ["frontend", "backend", "api", "database", "infrastructure"]
        }
      }
    }
  }
}

secret triage_slack {
  vars: [SLACK_WEBHOOK_URL]
}

workflow triage_bug {
  label: "Triage Bug Report"

  root {
    type: code
    label: "Extract bug report"
    code: @ts { return context.nodes.root.input }
    outputSchema: @json {
      {
        "type": "object",
        "properties": {
          "title": { "type": "string" },
          "description": { "type": "string" },
          "steps_to_reproduce": { "type": "string" },
          "reporter_email": { "type": "string" },
          "component": { "type": "string" }
        }
      }
    }
  }

  node classify {
    type: ai
    label: "Classify bug"
    kind: object
    model: "google/gemini-2.5-flash"
    prompt: @ts {
      const bug = context.nodes.root.output
      return "Classify this bug report.\n\nTitle: " + bug.title + "\nComponent: " + (bug.component || "unknown") + "\nDescription: " + bug.description + "\nSteps: " + (bug.steps_to_reproduce || "not provided")
    }
    schema: @json {
      {
        "type": "object",
        "required": ["severity", "priority", "category"],
        "properties": {
          "severity": { "type": "string", "enum": ["critical", "major", "minor", "trivial"] },
          "priority": { "type": "string", "enum": ["p0", "p1", "p2", "p3"] },
          "category": { "type": "string", "enum": ["crash", "data_loss", "performance", "ui", "functionality", "security"] },
          "suggested_assignee_team": { "type": "string" }
        }
      }
    }
  }

  node route_severity {
    type: switch
    label: "Route by severity"
    cases: ["critical", "standard"]
    router: @ts {
      if (context.nodes.classify.output.severity === "critical") return "critical"
      return "standard"
    }
  }

  node page_oncall {
    type: http
    label: "Page on-call"
    method: "POST"
    url: @ts { return context.secrets.triage_slack.SLACK_WEBHOOK_URL }
    headers: @ts { return { "Content-Type": "application/json" } }
    body: @ts {
      const bug = context.nodes.root.output
      const cls = context.nodes.classify.output
      return JSON.stringify({
        text: "CRITICAL BUG: " + bug.title + "\nCategory: " + cls.category + "\nPriority: " + cls.priority + "\n" + bug.description
      })
    }
    secrets: {
      triage_slack: [SLACK_WEBHOOK_URL]
    }
  }

  node log_bug {
    type: code
    label: "Log triaged bug"
    code: @ts {
      const bug = context.nodes.root.output
      const cls = context.nodes.classify.output
      return {
        title: bug.title,
        severity: cls.severity,
        priority: cls.priority,
        category: cls.category,
        component: bug.component || "unknown",
        team: cls.suggested_assignee_team || "unassigned"
      }
    }
  }

  node ack_reporter {
    type: email
    label: "Acknowledge reporter"
    from: @ts { return "[email protected]" }
    to: @ts { return context.nodes.root.output.reporter_email }
    subject: @ts { return "Bug received: " + context.nodes.root.output.title }
    text: @ts {
      return "Thanks for reporting this bug. It has been triaged as " + context.nodes.classify.output.priority + " (" + context.nodes.classify.output.severity + "). Our team is on it."
    }
  }

  flow {
    root -> classify
    classify -> route_severity
    route_severity -["critical"]-> page_oncall
    route_severity -["standard"]-> log_bug
    classify -> ack_reporter
  }
}

trigger on_bug {
  form:bug_report -> triage_bug
  enabled: true
}

Flow

Trigger to workflow

bug_reportform
triage_bug
Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.

Workflow nodes

CODE
Code Node
Extract bug report
AI
AI Node
Classify bug
SWITCH
Switch Node
Route by severity
HTTP
HTTP Node
Page on-call
CODE
Code Node
Log triaged bug
EMAIL
Email Node
Acknowledge reporter
Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.