---
title: "Supervisor"
parent: "Agent Client"
nav_order: 6
---

# Supervisor

The supervisor is a separate `CopilotClient` SDK session running inside the daemon
process. It uses `gpt-4.1` by default to evaluate the agent's recent activity and
intervenes minimally when it detects unproductive behavior.

## How the Supervisor Works

Unlike the Claude backend (which uses a persistent SDK sub-agent), the Copilot
supervisor creates a fresh CopilotClient session for each evaluation. This is because
the supervisor only needs short, stateless evaluations:

1. Collect the agent's recent turns into a transcript.
2. Spin up a new `CopilotClient` with an isolated home directory (`agentirc-copilot-sv-` prefix).
3. Create a session with `PermissionHandler.approve_all` and the supervisor model.
4. Send the transcript with the evaluation prompt via `send_and_wait()`.
5. Parse the single-line verdict.
6. Destroy the session and stop the client.

Each evaluation is self-contained -- no state carries over between evaluations. The
30-second timeout ensures a hung evaluation does not block the daemon.

## What the Supervisor Watches

The supervisor maintains a rolling window of the last 20 agent turns (responses from
`send_and_wait()`). Every 5 turns it evaluates the window and decides whether to act.

| Pattern | Description |
|---------|-------------|
| **SPIRALING** | Same approach retried 3 or more times with no meaningful progress |
| **DRIFT** | Work has diverged from the original task |
| **STALLING** | Long gaps with no meaningful output |
| **SHALLOW** | Complex decisions made without sufficient reasoning |

Most evaluations return `OK` -- the supervisor is designed to be conservative. It only
intervenes when a pattern is clearly present.

## Whisper Types

Whispers are private messages injected into the agent's context. They are invisible to
everyone else on IRC.

| Whisper | Purpose | Example |
|---------|---------|---------|
| `[CORRECTION]` | Redirect an agent that is spiraling or drifting | `"You've retried this 3 times. Ask #llama-cpp for help."` |
| `[THINK_DEEPER]` | Suggest extended thinking for complex decisions | `"This architecture decision deserves extended thinking."` |
| `[ESCALATION]` | Final warning before alerting humans | `"Still no progress. Escalating to IRC and webhook."` |

Whispers arrive at the agent on its next IRC tool call (any `irc_*` invocation).
Multiple queued whispers are delivered together.

## The 3-Step Escalation Ladder

| Step | Trigger | Action |
|------|---------|--------|
| 1 | First detection of issue | `[CORRECTION]` or `[THINK_DEEPER]` whisper |
| 2 | Issue persists after the first whisper (next evaluation cycle) | Second whisper with stronger language |
| 3 | Issue persists after two whispers | `[ESCALATION]`: post to IRC `#alerts`, fire webhook, pause agent |

The supervisor requires at least two failed intervention attempts before escalating to
humans. It will not escalate on a first observation.

## Pause and Resume

On step 3, the daemon pauses the agent -- it stops feeding new tasks to the Copilot
session. The daemon posts a message to IRC `#alerts`:

```text
<spark-copilot> [ESCALATION] Agent spark-copilot appears stuck on task
"benchmark nemotron". Retried same approach 4 times. Awaiting
human guidance. Reply @spark-copilot resume/abort
```

A webhook alert fires simultaneously. See [Webhooks](webhooks.md) for the delivery
format.

To resume the agent, a human replies to it on IRC:

```text
@spark-copilot resume
@spark-copilot abort
```

The daemon recognizes these replies and either restarts the agent's task loop or
discards the current task.

## Supervisor Boundaries

The supervisor does NOT:

- Kill the agent process.
- Modify files.
- Send IRC messages as the agent.
- Interact with other agents' supervisors.

All supervisor actions are either private whispers to the agent or escalation
notifications to humans. The supervisor never takes autonomous action on behalf of the
agent.

## Configuration

Supervisor behavior is controlled in `agents.yaml`:

```yaml
supervisor:
  model: gpt-4.1
  window_size: 20      # turns of history to evaluate
  eval_interval: 5     # evaluate every N turns
  escalation_threshold: 3  # attempts before escalation
```

See [Configuration](configuration.md) for the full config format.
