MainSDK
Search⌘K
How-to

Propose playbooks with the advisor

Let a model read signals and propose one of your declared playbooks, with a person approving every proposal.

Building for 0.6

Status Status is where the work is: Planned (in a milestone, not started), Building (tickets in progress), Preview (usable, may change), then the stability it ships at.

Stability The promise an interface ships with.

  • Stable Follows semantic versioning; breaking changes need a new major, 12 months of overlap and a codemod.
  • Beta Usable in production; may change before it becomes stable.
  • Experimental May change or go away; needs an explicit opt-in in main.yaml.
Stability levels
Updated 2026-10-28

You will turn on the advisor so that, when signals suggest trouble, a model proposes one of the playbooks you already declared and a person approves it. It takes about 10 minutes.

You need

  • At least one playbook rule declared, or a preset turned on, such as attack.contain.
  • The ai interface configured with a model (or driver: local in tests).

1. Declare it

main.yaml
agents:
  advisor: { budget: { spend: $2/day, calls: 50/day } }
advisor:
  on: [attack.suspected, anomaly.detected]
  may: [attack.contain, pressure.slim]
  run: approve

mainsdk check fails with MAIN-ADVISOR-0001 when may is empty, names a rule that is not declared, or when run: auto would apply a rule whose steps are not notice or instance class.

2. Read a proposal

A wake at medium severity or above makes the advisor ask the model. You can also ask now:

ops/ask.ts
import { advisor } from "mainsdk/experimental/advisor";

const p = await advisor.propose();
console.log(p.choice, p.reason, p.evidence);   // choice is one of may, or none

A proposal with a choice starts a playbook run with source advisor, held for a person to approve. The advisor never approves anything itself.

Test it offline

test/advisor.test.ts
import { createTestApp } from "@mainsdk/testing";

const app = await createTestApp({
  ai: { replies: [JSON.stringify({ choice: "attack.contain", reason: "Many failed sign-ins", evidence: ["s1"], confidence: 0.8 })] },
});

Check it worked

A model answer that names a playbook outside may is refused and logged as MAIN-ADVISOR-0002, and no run starts. When the budget or the hourly limit is reached the advisor stops with MAIN-ADVISOR-0003 and your playbooks carry on without it. Secrets and personal data never reach the model: a field that matches a detector is dropped and logged as MAIN-ADVISOR-0004.

Next

Was this page helpful?

↑↓ moveEnter openEsc close

Not decided yet