Skip to content
← Back to all pipelines

Bug Triage

Parse raw error logs → classify each (severity P0-P3 + category + suggested owner) → rank by impact → emit Markdown triage report.

v1.0.0CompositionVerified
githubtriagestructured-output
Setup — API key

Set one of these env vars before running locally. The CLI resolves $VAR via env-var substitution.

shell · bash
# Choose ONE provider
export MINIMAX_API_KEY="sk-..."      # default provider for these pipelines
# OR
export OPENROUTER_API_KEY="sk-..."  # OpenRouter (multi-model gateway)

Pipeline YAMLs use ${VAR:-default} syntax; runtime reads fromprocess.env at parse time. agentsmarket pipeline call returns a clear error if no key is found.

Install

Downloads Pipeline.yaml. R16 stub — server route pending.

CLI · bash
agentsmarket pipeline install bug-triage
Run locally

Executes the pipeline via the local CLI runtime. Use --mock for a dry-run (no API key needed).

CLI · bash
# Dry-run (no API key needed)
agentsmarket pipeline call bug-triage --local --mock

# Real run (uses one of MINIMAX_API_KEY / OPENROUTER_API_KEY)
agentsmarket pipeline call bug-triage --local

Inputs are passed via --inputs '<JSON>' or read from~/.config/agentsmarket/pipelines/bug-triage/inputs.json. See the pipeline YAML below for the input schema.

Pipeline YAML

Verbatim copy of packages/pipeline-runtime/pipelines/bug-triage.yaml. Verified end-to-end against mock LLM provider.

pipeline.yaml · yaml
# bug-triage — parses error logs → classifies severity + category → ranked report.
#
# Demonstrates: structured_json output_format with dotted-path fields,
# multi-stage DAG with depends_on, recovery plan generation as final step.
# Useful for SRE/on-call workflows.
#
# Run locally:  agentsmarket run pipelines/bug-triage.yaml --mock
name: bug-triage
version: 1.0.0
description: Parse raw error logs → classify each (severity P0-P3 + category + suggested owner) → rank by impact → emit Markdown triage report.
author_id: 0xYourAddress
license: MIT

inputs:
  logs:
    type: string
    required: true
    description: "Raw log dump from a service (stderr, log file, journalctl, etc.)"
  service_name:
    type: string
    required: false
    default: unknown-service

outputs:
  report:
    format: text
    description: "Markdown bug triage report with prioritized fix list"

defaults:
  model: MiniMax-M3

stages:
  - id: parse_logs
    provider: minimax
    system: ${BUG_TRIAGE_TONE:-You are an SRE on-call engineer. Triage with speed and precision.}
    retry:
      attempts: 3
      backoff: exponential
      retryable_status: [429, 503]
    prompt: |
      Parse the following error logs from service `{{service_name}}`.

      Output a JSON object with shape: `{"errors": [<each error as object>]}`
      Each error object must have exactly these fields:
        - `timestamp` (ISO 8601 if present, else `unknown`)
        - `level` (ERROR / WARN / FATAL / PANIC)
        - `category` (network / disk / auth / memory / cpu / config / dependency / client / unknown)
        - `message` (one-line summary)
        - `stack_top` (first 3 frames of stack, or null)
        - `recurrence_count` (how many times this same fingerprint appeared)

      Reply with valid JSON only. No prose, no markdown fences.

      Logs:
      ```
      $input.logs
      ```
    output_format: structured_json
    fields:
      - "errors[*].timestamp"
      - "errors[*].level"
      - "errors[*].category"
      - "errors[*].message"
      - "errors[*].stack_top"
      - "errors[*].recurrence_count"

  - id: classify
    provider: minimax
    depends_on: [parse_logs]
    prompt: |
      Assign priority + suggested owner team per error.

      Output a JSON object with shape: `{"items": [<each classified error>]}`
      Each item must have exactly these fields:
        - `id` (1-based index matching parse_logs order)
        - `severity` (P0 / P1 / P2 / P3 — P0 = page-now, P1 = critical, P2 = degraded, P3 = minor)
        - `summary` (≤80 chars, action-oriented)
        - `suggested_owner` (e.g., `infra`, `api`, `auth-team`, `db-team`, `frontend`, `oncall`)
        - `fix_complexity` (trivial / small / medium / large)

      Reply with valid JSON only. No prose, no markdown fences.

      Errors: $stages.parse_logs.output
    output_format: structured_json
    fields:
      - "items[*].severity"
      - "items[*].summary"
      - "items[*].suggested_owner"
      - "items[*].fix_complexity"

  - id: rank
    provider: minimax
    depends_on: [classify]
    prompt: |
      Rank items in P0 → P1 → P2 → P3 order. Within same severity, sort by
      `recurrence_count` descending (more-frequent first).
      Preserve each item's original `id`.

      Output a JSON object with shape: `{"ranked": [<ordered list of items>]}`.
      Each entry in `ranked` should include the full item object so downstream
      stages can reference `id`, `severity`, `summary`, etc.

      Reply with valid JSON only. No prose, no markdown fences.

      Classified items: $stages.classify.output
    output_format: structured_json
    fields:
      - "ranked[*].id"
      - "ranked[*].severity"
      - "ranked[*].summary"

  - id: report
    provider: minimax
    depends_on: [rank]
    prompt: |
      Write a Markdown triage report for service `{{service_name}}`.

      Structure:
        # {{service_name}} Bug Triage — {{date}}
        ## P0 (page now)
        ## P1 (critical)
        ## P2 (degraded)
        ## P3 (minor)

      Under each section list:
        - **<summary>** — _suggested owner: <team>, complexity: <X>, est. fix time: <Y>_

      Ranked list: $stages.rank.output
    output_format: text
Verification evidence

How do we know this pipeline actually runs?

Each pipeline in this catalog is gated by packages/pipeline-runtime/tests/examples-execution.test.ts— a mock-provider end-to-end test that runs the actual YAML through the real runPipelineV2 executor and asserts every stage produces output. The CI test suite reports results on every push.

What the test verifies:

  • YAML parses + has valid name/version/stages array
  • Every stage declares a non-empty id
  • All stage IDs are unique
  • runPipelineV2 executes without throwing
  • Every stage produces an output
  • Mock provider is called at least once per model stage
  • structured_json stages declare a non-empty fields array
  • Pipeline version pin enforcement (uses: foo@1.0.0 returns matching version)
Run it yourself

From the repo root:

shell · bash
pnpm --filter @agentsmarket/pipeline-runtime test examples-execution

# Expected: 16 tests pass (1 file × 16 it() blocks)
Author

by agents-market-demo