@monotykamary/pi-supervisor 0.5.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +120 -0
- package/LICENSE +21 -0
- package/README.md +341 -0
- package/media/demo.mp4 +0 -0
- package/media/screenshot.png +0 -0
- package/package.json +87 -0
- package/src/compaction/brief.ts +841 -0
- package/src/compaction/build-sections.ts +340 -0
- package/src/compaction/causal-keys.ts +138 -0
- package/src/compaction/content.ts +68 -0
- package/src/compaction/extract/commits.ts +78 -0
- package/src/compaction/extract/goals.ts +79 -0
- package/src/compaction/extract/preferences.ts +52 -0
- package/src/compaction/extract/shared-symbols.ts +376 -0
- package/src/compaction/filter-noise.ts +47 -0
- package/src/compaction/format.ts +89 -0
- package/src/compaction/index.ts +38 -0
- package/src/compaction/normalize.ts +73 -0
- package/src/compaction/sanitize.ts +5 -0
- package/src/compaction/sections.ts +19 -0
- package/src/compaction/skill-collapse.ts +35 -0
- package/src/compaction/tool-args.ts +14 -0
- package/src/compaction/types.ts +26 -0
- package/src/core/analyzer.ts +58 -0
- package/src/core/index.ts +8 -0
- package/src/core/inference.ts +77 -0
- package/src/core/prompt-builder.ts +137 -0
- package/src/core/prompt-loader.ts +125 -0
- package/src/core/reframe.ts +27 -0
- package/src/fabric-provider.ts +115 -0
- package/src/global-config.ts +65 -0
- package/src/index.ts +514 -0
- package/src/session/client.ts +46 -0
- package/src/session/response-parser.ts +37 -0
- package/src/session/supervisor-session.ts +102 -0
- package/src/state/manager.ts +133 -0
- package/src/state/mid-run-signals.ts +103 -0
- package/src/state/patterns.ts +82 -0
- package/src/state/reframe.ts +27 -0
- package/src/subagent-detector.ts +94 -0
- package/src/types.ts +42 -0
- package/src/ui/animations.ts +95 -0
- package/src/ui/model-picker.ts +72 -0
- package/src/ui/model-settings-selector.ts +440 -0
- package/src/ui/model-sort.ts +101 -0
- package/src/ui/renderer.ts +314 -0
- package/src/ui/types.ts +48 -0
- package/tests/compaction.test.ts +507 -0
- package/tests/engine.test.ts +622 -0
- package/tests/ephemeral-supervision.test.ts +347 -0
- package/tests/fabric-provider.test.ts +55 -0
- package/tests/full-fidelity-snapshot.test.ts +250 -0
- package/tests/global-config.test.ts +74 -0
- package/tests/model-sort.test.ts +157 -0
- package/tests/parsing.test.ts +303 -0
- package/tests/state.test.ts +474 -0
- package/tests/status-widget.test.ts +539 -0
- package/tests/subagent-detector.test.ts +191 -0
- package/tests/supervise-command.test.ts +363 -0
- package/tests/supervise-model-command.test.ts +184 -0
- package/tsconfig.json +14 -0
- package/vitest.config.ts +15 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
|
4
|
+
|
|
5
|
+
### [0.5.5](https://github.com/monotykamary/pi-supervisor/compare/v0.5.4...v0.5.5) (2026-07-08)
|
|
6
|
+
|
|
7
|
+
### Features
|
|
8
|
+
|
|
9
|
+
- **model:** add /supervise model picker with pi-model-sort support ([21e7fa0](https://github.com/monotykamary/pi-supervisor/commit/21e7fa0783c1794ce4f8e49e273b68cde4176d77))
|
|
10
|
+
|
|
11
|
+
### [0.5.1](https://github.com/monotykamary/pi-supervisor/compare/v0.5.0...v0.5.1) (2026-03-12)
|
|
12
|
+
|
|
13
|
+
## [0.5.0] - 2026-03-12
|
|
14
|
+
|
|
15
|
+
### Changed (Breaking)
|
|
16
|
+
|
|
17
|
+
- **Simplified supervision — removed `sensitivity`** — the supervisor now automatically decides when to analyze:
|
|
18
|
+
- Always at `agent_end` (agent idle) — the critical decision point
|
|
19
|
+
- Mid-run only after steering (to verify it worked) or every 8th turn (safety valve)
|
|
20
|
+
- No more `low`/`medium`/`high` settings to configure
|
|
21
|
+
- **Token-optimal architecture** — ~85% fewer tokens than previous versions:
|
|
22
|
+
- **Session reuse**: Supervisor session maintained across analyses (automatic prompt caching)
|
|
23
|
+
- **Incremental snapshots**: Only new messages since last analysis are processed
|
|
24
|
+
- **Fixed 6-message context window**: Tight, consistent context size
|
|
25
|
+
- **Streaming only at `agent_end`**: No streaming overhead for mid-run checks
|
|
26
|
+
- **Removed `sensitivity` parameter from `start_supervision` tool** — supervision is now fully automatic
|
|
27
|
+
|
|
28
|
+
### Added
|
|
29
|
+
|
|
30
|
+
- **Test suite** — Vitest-based testing with 44 tests covering:
|
|
31
|
+
- `SupervisorStateManager` lifecycle, interventions, and trigger logic
|
|
32
|
+
- `parseDecision` JSON parsing with various edge cases
|
|
33
|
+
- `extractThinking` streaming reasoning extraction
|
|
34
|
+
- `loadSystemPrompt` discovery order
|
|
35
|
+
|
|
36
|
+
### Removed
|
|
37
|
+
|
|
38
|
+
- `/supervise sensitivity` subcommand — no longer needed
|
|
39
|
+
- Sensitivity selection from settings panel
|
|
40
|
+
- `Sensitivity` type and all sensitivity-related state
|
|
41
|
+
|
|
42
|
+
### Technical
|
|
43
|
+
|
|
44
|
+
- `SupervisorSession` class for reusable model sessions
|
|
45
|
+
- Incremental `snapshotBuffer` in `SupervisorState` for efficient context building
|
|
46
|
+
- `shouldAnalyzeMidRun()` method for smart trigger decisions
|
|
47
|
+
- Vitest test runner with `npm test` and `npm run test:watch`
|
|
48
|
+
|
|
49
|
+
## [0.4.2] - 2026-03-11
|
|
50
|
+
|
|
51
|
+
### Added
|
|
52
|
+
|
|
53
|
+
- **Interactive settings panel** — `/supervise` (no args) and `/supervise settings` now open a navigable settings UI built on pi-tui's `SettingsList` component instead of printing static text
|
|
54
|
+
- Arrow keys to navigate, Enter/Space to cycle values or open submenus, Escape to close
|
|
55
|
+
- **Model**: Enter opens the full interactive model picker as a submenu
|
|
56
|
+
- **Sensitivity**: cycles through `low`/`medium`/`high` with contextual descriptions
|
|
57
|
+
- **Widget**: toggles visibility inline
|
|
58
|
+
- **Outcome** (when active): displays current goal with steer/turn counts
|
|
59
|
+
- **Stop Supervision** (when active): confirm to stop directly from the panel
|
|
60
|
+
- `/supervise status` now also opens the interactive settings panel when supervision state exists
|
|
61
|
+
|
|
62
|
+
## [0.4.1] - 2026-02-22
|
|
63
|
+
|
|
64
|
+
### Changed
|
|
65
|
+
|
|
66
|
+
- Updated `@earendil-works/pi-ai`, `@earendil-works/pi-coding-agent`, and `@earendil-works/pi-tui` to 0.54.1
|
|
67
|
+
|
|
68
|
+
## [0.4.0] - 2026-02-22
|
|
69
|
+
|
|
70
|
+
### Added
|
|
71
|
+
|
|
72
|
+
- **`start_supervision` tool** — the agent can initiate supervision itself; once active it is locked and only the user can change or stop it via `/supervise`
|
|
73
|
+
- **`/supervise widget`** subcommand — toggle the status widget on/off
|
|
74
|
+
- **Workspace model persistence** — supervisor model saved to `.pi/supervisor-config.json` when `.pi/` exists; loaded automatically on next session
|
|
75
|
+
- **Streaming thinking** — supervisor reasoning streams live as a second line in the widget while analyzing
|
|
76
|
+
- **Stagnation detection** — after 5 consecutive steering messages with no `done`, switches to lenient evaluation (≥80% achieved → done) to avoid infinite loops
|
|
77
|
+
- **Mid-run steering for `medium` sensitivity** — checks every 3rd tool cycle (turns 2, 5, 8, …), confidence ≥ 0.90
|
|
78
|
+
- **Shortcut detection** — supervisor always steers when the agent takes shortcuts to satisfy the goal without properly achieving it
|
|
79
|
+
|
|
80
|
+
### Changed
|
|
81
|
+
|
|
82
|
+
- **Sensitivity reworked** — levels now control both _when_ to check and _how confidently_ to steer:
|
|
83
|
+
- `low`: end-of-run only, no mid-run checks
|
|
84
|
+
- `medium`: end-of-run + every 3rd tool cycle (confidence ≥ 0.90)
|
|
85
|
+
- `high`: end-of-run + every tool cycle (confidence ≥ 0.85)
|
|
86
|
+
- **`/supervise <outcome>` no longer auto-starts the agent** — supervision is set up first; the user starts the conversation separately, giving full control over the opening prompt
|
|
87
|
+
- **Supervisor is now a pure outside observer** — removed system prompt injection (`before_agent_start`); the agent runs completely unmodified and the supervisor steers only through user messages
|
|
88
|
+
- **Footer simplified** — `🎯` emoji replaces the `[SUPERVISING]` text label
|
|
89
|
+
- **Model fallback chain** — session state → `.pi/supervisor-config.json` → active chat model → built-in default
|
|
90
|
+
- **Dead `ANALYSIS_INTERVAL` code removed** — `agent_end` always fires once per user prompt with the agent idle; the interval throttle was never reachable
|
|
91
|
+
- Desired outcome repeated at the bottom of every supervisor analysis prompt to keep it prominent in long conversations
|
|
92
|
+
|
|
93
|
+
### Fixed
|
|
94
|
+
|
|
95
|
+
- Steering loop was broken: `deliverAs: "followUp"` does not trigger a new turn when the agent is already idle; removed to use plain `sendUserMessage`
|
|
96
|
+
|
|
97
|
+
## [0.3.0] - 2026-02-21
|
|
98
|
+
|
|
99
|
+
Initial release of `pi-supervisor`.
|
|
100
|
+
|
|
101
|
+
### Added
|
|
102
|
+
|
|
103
|
+
- **Supervisor engine** — observes every agent turn and calls a configurable LLM to evaluate progress toward a user-defined outcome
|
|
104
|
+
- **`/supervise <outcome>`** — activate supervision with a natural-language goal
|
|
105
|
+
- **`/supervise stop`** — deactivate supervision
|
|
106
|
+
- **`/supervise status`** — show outcome, model, sensitivity, and intervention history
|
|
107
|
+
- **`/supervise model`** — interactive model picker using pi's internal `ModelSelectorComponent` (same UI as Ctrl+P)
|
|
108
|
+
- **`/supervise model <provider/modelId>`** — set supervisor model directly for scripting
|
|
109
|
+
- **`/supervise sensitivity <low|medium|high>`** — control how aggressively the supervisor steers
|
|
110
|
+
- **Separate supervisor model** — runs in an isolated in-memory pi `AgentSession`, independent from the chat model; uses the same API credentials via `ctx.modelRegistry`
|
|
111
|
+
- **Steering** — injects follow-up user messages when the agent drifts; supervision stops automatically when the goal is achieved
|
|
112
|
+
- **`SUPERVISOR.md` support** — custom supervisor system prompt loaded from `.pi/SUPERVISOR.md` (project) or `~/.pi/agent/SUPERVISOR.md` (global), falling back to the built-in template; mirrors pi's `SYSTEM.md` discovery convention
|
|
113
|
+
- **Session persistence** — supervision state (outcome, model, sensitivity, interventions) stored in the session file and restored on restart, session switch, fork, and tree navigation
|
|
114
|
+
- **Footer status** — always-visible one-liner showing outcome, model, and steer count while supervising
|
|
115
|
+
- **Widget** — shows goal, model, and recent interventions above the editor
|
|
116
|
+
|
|
117
|
+
[0.4.2]: https://github.com/tintinweb/pi-supervisor/compare/v0.4.1...v0.4.2
|
|
118
|
+
[0.4.1]: https://github.com/tintinweb/pi-supervisor/compare/v0.4.0...v0.4.1
|
|
119
|
+
[0.4.0]: https://github.com/tintinweb/pi-supervisor/compare/v0.3.0...v0.4.0
|
|
120
|
+
[0.3.0]: https://github.com/tintinweb/pi-supervisor/releases/tag/v0.3.0
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 tintinweb
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,341 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
|
|
3
|
+
# 🧠 pi-supervisor
|
|
4
|
+
|
|
5
|
+
**Intelligent supervision for [pi](https://github.com/earendil-works/pi-coding-agent)**
|
|
6
|
+
|
|
7
|
+
_Observe every turn, steer when the agent drifts, signal when the goal is reached._
|
|
8
|
+
|
|
9
|
+
[](https://github.com/earendil-works/pi-coding-agent)
|
|
10
|
+
[](./LICENSE)
|
|
11
|
+
|
|
12
|
+
</div>
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
> A supervisor as the intelligent overseer keeping the agent on track.
|
|
17
|
+
|
|
18
|
+
> **Status:** Early release.
|
|
19
|
+
|
|
20
|
+
<img height="298" alt="image" src="https://github.com/monotykamary/pi-supervisor/raw/master/media/screenshot.png" />
|
|
21
|
+
|
|
22
|
+
https://github.com/user-attachments/assets/f3b23662-6473-4ac3-82f7-c7f9b34fa7c7
|
|
23
|
+
|
|
24
|
+
## How It Works
|
|
25
|
+
|
|
26
|
+
```
|
|
27
|
+
/supervise # Auto-infer goal from conversation
|
|
28
|
+
# or
|
|
29
|
+
/supervise Refactor auth to use dependency injection
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Then start the conversation normally — the supervisor watches from outside without modifying the agent's context.
|
|
33
|
+
|
|
34
|
+
1. **After each run** — the supervisor analyzes the conversation against the goal when the agent goes idle
|
|
35
|
+
2. **Mid-run, only when needed** — checks after steering (to verify it worked) or as a safety valve after prolonged activity
|
|
36
|
+
3. **On completion** — supervisor signals done and stops automatically
|
|
37
|
+
|
|
38
|
+
The supervisor is a pure outside observer. It runs in a separate in-memory pi session sharing only the API credentials and never touches the main agent's context window or system prompt.
|
|
39
|
+
|
|
40
|
+
**Context for the supervisor LLM is built algorithmically** — no rolling buffers, no state accumulation. At each analysis point, the full conversation is processed through an internal compaction pipeline (ported from [pi-vcc](https://github.com/monotykamary/pi-vcc)) that produces a structured summary: session goals, file activity, outstanding errors, current status, and a compressed brief transcript. The supervisor LLM receives this rich, information-dense context fresh every time, built in ~1ms with zero API cost.
|
|
41
|
+
|
|
42
|
+
## Install
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
pi install npm:pi-supervisor
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Or install from GitHub:
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
pi install https://github.com/monotykamary/pi-supervisor@master
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Or load directly for development:
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
pi -e ~/projects/pi-supervisor/src/index.ts
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Commands
|
|
61
|
+
|
|
62
|
+
| Command | Description |
|
|
63
|
+
| ---------------------- | -------------------------------------------------------- |
|
|
64
|
+
| `/supervise` | Auto-infer goal from conversation history |
|
|
65
|
+
| `/supervise <outcome>` | Start supervising with explicit goal |
|
|
66
|
+
| `/supervise model` | Pick the supervisor model (opens the model selector TUI) |
|
|
67
|
+
| `/supervise stop` | Stop active supervision |
|
|
68
|
+
| `/supervise widget` | Toggle the status widget on/off |
|
|
69
|
+
|
|
70
|
+
### Examples
|
|
71
|
+
|
|
72
|
+
```
|
|
73
|
+
/supervise
|
|
74
|
+
|
|
75
|
+
/supervise Refactor the auth module to use dependency injection and add 90% test coverage
|
|
76
|
+
|
|
77
|
+
/supervise stop
|
|
78
|
+
|
|
79
|
+
/supervise model
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
The agent can also initiate supervision itself by calling the `start_supervision` tool — useful when it recognises a task needs goal tracking. The tool uses the global config model or active chat model; the AI cannot specify a model. Once active, supervision is locked: only the user can change or stop it.
|
|
83
|
+
|
|
84
|
+
When [pi-fabric](https://github.com/monotykamary/pi-fabric) is installed, pi-supervisor also registers a versioned Fabric provider. Fabric programs can discover `supervisor.start` and `supervisor.status` through `tools.search()` and invoke them with `tools.call()`. Stop and goal mutation remain user-only.
|
|
85
|
+
|
|
86
|
+
## UI
|
|
87
|
+
|
|
88
|
+
### Live Widget
|
|
89
|
+
|
|
90
|
+
The widget displays supervision state in a compact one-line format (text truncates to fit window width):
|
|
91
|
+
|
|
92
|
+
```
|
|
93
|
+
◉ Supervising · Goal: "Refactor auth module…" · ↗ 2 · steering
|
|
94
|
+
The agent has added the DI container but hasn't updated the existing call sites yet…
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Header states:
|
|
98
|
+
|
|
99
|
+
- **Inferring** — analyzing conversation to suggest a goal (`◉ Inferring · scanning`)
|
|
100
|
+
- **Supervising** — active supervision in progress
|
|
101
|
+
- **Supervised** — goal achieved, widget clears after delay
|
|
102
|
+
|
|
103
|
+
When the supervisor detects an ineffective pattern, the reframe tier appears (e.g., `↻2`):
|
|
104
|
+
|
|
105
|
+
```
|
|
106
|
+
◉ Supervising · Goal: "Implement payment flow…" · ↗ 5 · ↻2 · analyzing
|
|
107
|
+
Breaking into smaller milestone: get the checkout form rendering first…
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
The thinking text streams naturally into multiple lines. When supervision ends or steers, thoughts animate away line-by-line from bottom to top (clearing newest first), then the widget clears. Toggle the widget with `/supervise widget`.
|
|
111
|
+
|
|
112
|
+
## How Supervision Works
|
|
113
|
+
|
|
114
|
+
**Analysis triggers:**
|
|
115
|
+
|
|
116
|
+
| When | Why |
|
|
117
|
+
| ----------------------------- | ------------------------------------------------ |
|
|
118
|
+
| Agent goes idle (`agent_end`) | Critical decision point — must choose done/steer |
|
|
119
|
+
| After we steered | Verify the steer worked |
|
|
120
|
+
| Mid-run safety valve | Catch runaway drift during long runs |
|
|
121
|
+
| Tool errors detected | If agent hits an error, we check |
|
|
122
|
+
|
|
123
|
+
The supervisor only intervenes when it has high confidence the agent is off track. It trusts the agent to make progress and only steps in when necessary.
|
|
124
|
+
|
|
125
|
+
### Algorithmic Context Building
|
|
126
|
+
|
|
127
|
+
At each analysis point, the conversation is processed through an internal compaction pipeline — the same algorithm used by [pi-vcc](https://github.com/monotykamary/pi-vcc), but used here as a read-only transformation, not as a session compactor.
|
|
128
|
+
|
|
129
|
+
**Pipeline:** `normalize → filter noise → build sections → format`
|
|
130
|
+
|
|
131
|
+
| Step | What it does |
|
|
132
|
+
| ------------------ | ------------------------------------------------------------------------------------------------------------- |
|
|
133
|
+
| **Normalize** | Raw Pi messages → uniform blocks (user, assistant, tool_call, tool_result, thinking, bash) |
|
|
134
|
+
| **Filter noise** | Strip system messages, thinking blocks, noise tools (TodoWrite), XML wrappers |
|
|
135
|
+
| **Build sections** | Extract session goals, file paths + symbols, type catalog, outstanding errors, current status, turn summaries |
|
|
136
|
+
| **Format** | Render as bracketed sections + brief transcript for the supervisor LLM |
|
|
137
|
+
|
|
138
|
+
**Properties:**
|
|
139
|
+
|
|
140
|
+
- **No LLM call** — purely algorithmic, zero extra API cost, ~1ms
|
|
141
|
+
- **Stateless** — built fresh from the full conversation each time, no rolling buffer or accumulated summary
|
|
142
|
+
- **Structured** — the supervisor LLM receives sections like `[Session Goal]`, `[Files And Changes]`, `[Outstanding Context]`, `[Current Status]` instead of a raw message dump
|
|
143
|
+
|
|
144
|
+
**Structured sections produced:**
|
|
145
|
+
|
|
146
|
+
| Section | Description |
|
|
147
|
+
| ----------------------- | -------------------------------------------------------------------------------------------------------------------- |
|
|
148
|
+
| `[Session Goal]` | Initial goal + scope changes (regex-based extraction) |
|
|
149
|
+
| `[Files And Changes]` | Modified/created/read files from tool calls, annotated with exported symbol names |
|
|
150
|
+
| `[Commits]` | Git commits made during the session (hash + first line) |
|
|
151
|
+
| `[Outstanding Context]` | Unresolved errors, test failures, tsc errors, empty search results — tagged `[ERROR]`/`[WARN]`/`[INFO]`/`[RESOLVED]` |
|
|
152
|
+
| `[Current Status]` | Current focus, last file-modifying action, and next steps |
|
|
153
|
+
| `[Earlier Turns]` | Per-turn one-liner summaries for every conversational turn |
|
|
154
|
+
| `[User Preferences]` | Regex-extracted from user messages (`always`, `never`, `prefer`...) |
|
|
155
|
+
| Brief transcript | Chronological conversation flow, tool calls collapsed to one-liners with `(#N)` refs |
|
|
156
|
+
|
|
157
|
+
## Reframe Escalation
|
|
158
|
+
|
|
159
|
+
When the supervisor detects that steering isn't working, it escalates through **4 tiers** of reframing strategies rather than giving up:
|
|
160
|
+
|
|
161
|
+
| Tier | Trigger | Strategy |
|
|
162
|
+
| ---- | ------------------------- | -------------------------------------------------------------------------- |
|
|
163
|
+
| 0 | (default) | Standard steering |
|
|
164
|
+
| 1 | Similar messages detected | **Directive** — be extremely specific about the next single action |
|
|
165
|
+
| 2 | Pattern continues | **Subgoal** — break the goal into a smaller, verifiable milestone |
|
|
166
|
+
| 3 | Still stuck | **Pivot** — suggest a completely different strategy or implementation path |
|
|
167
|
+
| 4 | Persistent stall | **Minimal slice** — strip to absolute essentials, demand tangible output |
|
|
168
|
+
|
|
169
|
+
**Pattern detection** tracks two indicators of ineffectiveness:
|
|
170
|
+
|
|
171
|
+
- **Message similarity** — when 2+ recent steering messages are similar (suggesting the agent isn't responding)
|
|
172
|
+
- **Stagnation** — when time passes without progress after a steer
|
|
173
|
+
|
|
174
|
+
When either pattern is detected, the supervisor escalates the reframe tier and injects tier-specific guidance into its prompt. The tier resets when the goal is achieved. This allows the supervisor to adapt to long-horizon projects that may take hours or days, rather than forcing early termination.
|
|
175
|
+
|
|
176
|
+
## Supervisor Model
|
|
177
|
+
|
|
178
|
+
The supervisor runs on a **separate model** — it can be a cheaper/faster model than the one doing the actual work.
|
|
179
|
+
|
|
180
|
+
**Resolution order:**
|
|
181
|
+
|
|
182
|
+
1. Previous session state (persists within a session)
|
|
183
|
+
2. `.pi/supervisor-config.json` in the project root (saved when you pick a model)
|
|
184
|
+
3. Active chat model (`ctx.model`) — so it works out of the box with no configuration
|
|
185
|
+
|
|
186
|
+
Change the supervisor model with `/supervise model` — it opens a copy of pi's own `/model` selector (DynamicBorder top/bottom, fuzzy search, all/scoped toggle) and saves the choice to `.pi/supervisor-config.json`. If supervision is already active, the live session model is updated too. Alternatively, start `/supervise <goal>` with a different chat model active, or delete `.pi/supervisor-config.json` to reset.
|
|
187
|
+
|
|
188
|
+
> **Works with [pi-model-sort](https://github.com/monotykamary/pi-model-sort):** the `/supervise model` picker reads pi-model-sort's last-used timestamps (`~/.pi/agent/extensions/pi-model-sort.json`) and lists models in the same recency order you see in pi's `/model` selector. With pi-model-sort absent or unused, it falls back to pi's default provider order. Selecting a model does **not** change your main chat model — the supervisor keeps its own.
|
|
189
|
+
|
|
190
|
+
## Focus and Goal Discipline
|
|
191
|
+
|
|
192
|
+
The supervisor is a pure outside observer — it does not modify the agent's system prompt. Goal discipline is enforced entirely through steering messages when the agent drifts. If the agent asks an out-of-scope clarifying question, the supervisor redirects it back to the goal rather than answering.
|
|
193
|
+
|
|
194
|
+
Unlike earlier versions, there are **no artificial limits** on steering attempts. The supervisor uses [reframe escalation](#reframe-escalation) to adapt its strategy when standard steering isn't working, allowing it to supervise long-horizon projects that may take hours or days to complete.
|
|
195
|
+
|
|
196
|
+
## Customizing the Supervisor: SUPERVISOR.md
|
|
197
|
+
|
|
198
|
+
The supervisor's reasoning is controlled by its **system prompt** — not the goal. The goal is always set at runtime via `/supervise`. `SUPERVISOR.md` defines _how_ the supervisor thinks: its rules, persona, and project-specific constraints.
|
|
199
|
+
|
|
200
|
+
**Discovery order** (mirrors pi's `SYSTEM.md` convention):
|
|
201
|
+
|
|
202
|
+
| Priority | Location | Use for |
|
|
203
|
+
| -------- | --------------------------- | ---------------------- |
|
|
204
|
+
| 1 | `.pi/SUPERVISOR.md` | Project-specific rules |
|
|
205
|
+
| 2 | `~/.pi/agent/SUPERVISOR.md` | Global personal rules |
|
|
206
|
+
| 3 | Built-in template | Fallback |
|
|
207
|
+
|
|
208
|
+
The active source is shown when you run `/supervise <goal>` or when the tool is invoked.
|
|
209
|
+
|
|
210
|
+
### Built-in system prompt
|
|
211
|
+
|
|
212
|
+
The default prompt the supervisor uses when no `SUPERVISOR.md` is found:
|
|
213
|
+
|
|
214
|
+
```
|
|
215
|
+
You are a supervisor monitoring a coding AI assistant conversation.
|
|
216
|
+
Your job: ensure the assistant fully achieves a specific outcome without needing the human to intervene.
|
|
217
|
+
|
|
218
|
+
═══ WHEN THE AGENT IS IDLE (finished its turn, waiting for user input) ═══
|
|
219
|
+
This is your most important moment. The agent has stopped and is waiting.
|
|
220
|
+
You MUST choose "done" or "steer". Never return "continue" when the agent is idle.
|
|
221
|
+
|
|
222
|
+
- "done" → only when the outcome is completely and verifiably achieved.
|
|
223
|
+
- "steer" → everything else: incomplete work, partial progress, open questions, waiting for confirmation.
|
|
224
|
+
|
|
225
|
+
If the agent asked a clarifying question or needs a decision:
|
|
226
|
+
FIRST check: is this question necessary to achieve the goal?
|
|
227
|
+
- YES (directly blocks goal progress): answer with a sensible default and tell agent to proceed.
|
|
228
|
+
- NO (out of scope, nice-to-have, unrelated feature): do NOT answer it. Redirect:
|
|
229
|
+
"That's outside the scope of the goal. Focus on: [restate the specific missing piece]."
|
|
230
|
+
DO NOT answer: passwords, credentials, secrets, anything requiring real user knowledge.
|
|
231
|
+
|
|
232
|
+
Your steer message speaks AS the user. Make it clear, direct, and actionable (1–3 sentences).
|
|
233
|
+
Do not ask the agent to verify its own work — tell it what to do next.
|
|
234
|
+
|
|
235
|
+
═══ WHEN THE AGENT IS ACTIVELY WORKING (mid-turn) ═══
|
|
236
|
+
Only intervene if it is clearly heading in the wrong direction.
|
|
237
|
+
Trust the agent to complete what it has started. Avoid interrupting productive work.
|
|
238
|
+
|
|
239
|
+
═══ STEERING RULES ═══
|
|
240
|
+
- Be specific: reference the outcome, missing pieces, or the question being answered.
|
|
241
|
+
- Never repeat a steering message that had no effect — escalate or change approach.
|
|
242
|
+
- A good steer answers the agent's question OR redirects to the missing piece of the outcome.
|
|
243
|
+
- If the agent is taking shortcuts to satisfy the goal without properly achieving it, always steer and remind it not to take shortcuts.
|
|
244
|
+
|
|
245
|
+
"done" CRITERIA: The core outcome is complete and functional. Minor polish, style tweaks, or
|
|
246
|
+
optional improvements do NOT block "done". Prefer stopping when the goal is substantially
|
|
247
|
+
achieved rather than looping forever chasing perfection.
|
|
248
|
+
|
|
249
|
+
Respond ONLY with valid JSON — no prose, no markdown fences.
|
|
250
|
+
Response schema (strict JSON):
|
|
251
|
+
{
|
|
252
|
+
"action": "continue" | "steer" | "done",
|
|
253
|
+
"message": "...", // Required when action === "steer"
|
|
254
|
+
"reasoning": "...", // Brief internal reasoning
|
|
255
|
+
"confidence": 0.85 // Float 0-1
|
|
256
|
+
}
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
**Dynamic reframe guidance:** When the supervisor detects an ineffective pattern, it injects tier-specific guidance into the prompt (see [Reframe Escalation](#reframe-escalation)).
|
|
260
|
+
|
|
261
|
+
### Writing a custom SUPERVISOR.md
|
|
262
|
+
|
|
263
|
+
You must preserve the JSON response schema. Everything else is up to you.
|
|
264
|
+
|
|
265
|
+
```markdown
|
|
266
|
+
You are a supervisor for a TypeScript project. Your priorities: type safety and test coverage.
|
|
267
|
+
|
|
268
|
+
Rules:
|
|
269
|
+
|
|
270
|
+
- Steer if the agent uses `any` types or skips tests for new code
|
|
271
|
+
- When steering, be direct: one sentence max, reference the specific file/function if possible
|
|
272
|
+
- "done" only when the new code has types and tests — not before
|
|
273
|
+
- Do not steer about code style, naming, or documentation
|
|
274
|
+
|
|
275
|
+
Response schema (strict JSON, required):
|
|
276
|
+
{
|
|
277
|
+
"action": "continue" | "steer" | "done",
|
|
278
|
+
"message": "...",
|
|
279
|
+
"reasoning": "...",
|
|
280
|
+
"confidence": 0.85
|
|
281
|
+
}
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
## Session Persistence
|
|
285
|
+
|
|
286
|
+
Supervision state (outcome, model, intervention history) is stored in the pi session file and restored automatically on restart, session switch, fork, and tree navigation.
|
|
287
|
+
|
|
288
|
+
## Testing
|
|
289
|
+
|
|
290
|
+
Run the test suite:
|
|
291
|
+
|
|
292
|
+
```bash
|
|
293
|
+
npm test # Run once
|
|
294
|
+
npm run test:watch # Watch mode
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
Coverage report generated in `coverage/`.
|
|
298
|
+
|
|
299
|
+
## Project Structure
|
|
300
|
+
|
|
301
|
+
```
|
|
302
|
+
src/
|
|
303
|
+
index.ts # Extension entry point, event wiring, /supervise command, start_supervision tool
|
|
304
|
+
types.ts # SupervisorState, SteeringDecision, ReframeTier
|
|
305
|
+
compaction/ # Algorithmic context building (ported from pi-vcc)
|
|
306
|
+
index.ts # Public API: extractMessages(), buildCompactionSummary(), formatForSupervisor()
|
|
307
|
+
normalize.ts # Message[] → NormalizedBlock[]
|
|
308
|
+
filter-noise.ts # Strip thinking, TodoWrite, XML wrappers
|
|
309
|
+
build-sections.ts # Build all structured sections
|
|
310
|
+
brief.ts # Compressed [user]/[assistant]/[tool_error] transcript
|
|
311
|
+
sanitize.ts # ANSI/control char stripping
|
|
312
|
+
content.ts # Text utilities: clip, firstLine, textOf
|
|
313
|
+
tool-args.ts # Path extraction from tool arguments
|
|
314
|
+
skill-collapse.ts # Collapse <skill> XML blocks
|
|
315
|
+
types.ts # NormalizedBlock, ToolResultIndex, SectionData, SymbolRef
|
|
316
|
+
extract/ # Section extractors
|
|
317
|
+
goals.ts # User goal + scope change extraction
|
|
318
|
+
commits.ts # Git commit extraction
|
|
319
|
+
preferences.ts # User preference extraction
|
|
320
|
+
shared-symbols.ts # Unified file/symbol/type extraction
|
|
321
|
+
state/ # State management
|
|
322
|
+
manager.ts # SupervisorStateManager — persistence, reframe tier, pattern detection
|
|
323
|
+
core/ # Core supervision logic
|
|
324
|
+
analyzer.ts # Main analysis engine (builds fresh compaction each call)
|
|
325
|
+
inference.ts # Goal inference from conversation
|
|
326
|
+
prompt-loader.ts # SUPERVISOR.md loading
|
|
327
|
+
session/ # Model session management
|
|
328
|
+
client.ts # callSupervisorModel — one-shot analysis via reusable session
|
|
329
|
+
ui/ # User interface
|
|
330
|
+
renderer.ts # Widget rendering and footer management
|
|
331
|
+
animations.ts # Thought clearing animations
|
|
332
|
+
types.ts # Widget state types
|
|
333
|
+
model-picker.ts # Interactive model picker (opens the selector)
|
|
334
|
+
model-settings-selector.ts # Copied pi-core ModelSelectorComponent for the supervisor
|
|
335
|
+
model-sort.ts # pi-model-sort last-used integration
|
|
336
|
+
global-config.ts # .pi/supervisor-config.json read/write
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
## License
|
|
340
|
+
|
|
341
|
+
MIT — [tintinweb](https://github.com/tintinweb) (forked by [monotykamary](https://github.com/monotykamary))
|
package/media/demo.mp4
ADDED
|
Binary file
|
|
Binary file
|
package/package.json
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@monotykamary/pi-supervisor",
|
|
3
|
+
"version": "0.5.9",
|
|
4
|
+
"description": "A pi extension that supervises the chat and steers it towards a defined outcome",
|
|
5
|
+
"author": "tintinweb (forked by monotykamary)",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/monotykamary/pi-supervisor.git"
|
|
10
|
+
},
|
|
11
|
+
"homepage": "https://github.com/monotykamary/pi-supervisor#readme",
|
|
12
|
+
"bugs": {
|
|
13
|
+
"url": "https://github.com/monotykamary/pi-supervisor/issues"
|
|
14
|
+
},
|
|
15
|
+
"keywords": [
|
|
16
|
+
"pi-package",
|
|
17
|
+
"pi",
|
|
18
|
+
"pi-extension",
|
|
19
|
+
"supervisor",
|
|
20
|
+
"steering",
|
|
21
|
+
"outcome",
|
|
22
|
+
"agent",
|
|
23
|
+
"productivity"
|
|
24
|
+
],
|
|
25
|
+
"files": [
|
|
26
|
+
"src/**/*.ts",
|
|
27
|
+
"tests/**/*.ts",
|
|
28
|
+
"vitest.config.ts",
|
|
29
|
+
"tsconfig.json",
|
|
30
|
+
"README.md",
|
|
31
|
+
"CHANGELOG.md",
|
|
32
|
+
"LICENSE",
|
|
33
|
+
"media/"
|
|
34
|
+
],
|
|
35
|
+
"peerDependencies": {
|
|
36
|
+
"@earendil-works/pi-ai": ">=0.80.8",
|
|
37
|
+
"@earendil-works/pi-coding-agent": ">=0.80.8",
|
|
38
|
+
"@sinclair/typebox": "0.34.49"
|
|
39
|
+
},
|
|
40
|
+
"devDependencies": {
|
|
41
|
+
"@commitlint/cli": "21.0.1",
|
|
42
|
+
"@commitlint/config-conventional": "21.0.1",
|
|
43
|
+
"@earendil-works/pi-tui": "0.80.8",
|
|
44
|
+
"@types/node": "25.9.1",
|
|
45
|
+
"knip": "6.14.1",
|
|
46
|
+
"lint-staged": "17.0.5",
|
|
47
|
+
"prettier": "3.8.3",
|
|
48
|
+
"simple-git-hooks": "2.13.1",
|
|
49
|
+
"standard-version": "9.5.0",
|
|
50
|
+
"typescript": "6.0.3",
|
|
51
|
+
"vitest": "4.1.7"
|
|
52
|
+
},
|
|
53
|
+
"simple-git-hooks": {
|
|
54
|
+
"pre-commit": "npx lint-staged",
|
|
55
|
+
"pre-push": "npm run typecheck && npm run test",
|
|
56
|
+
"commit-msg": "npx commitlint --edit ${1}"
|
|
57
|
+
},
|
|
58
|
+
"lint-staged": {
|
|
59
|
+
"*.{ts,js,json,md}": [
|
|
60
|
+
"prettier --write"
|
|
61
|
+
]
|
|
62
|
+
},
|
|
63
|
+
"pi": {
|
|
64
|
+
"extensions": [
|
|
65
|
+
"./src/index.ts"
|
|
66
|
+
],
|
|
67
|
+
"video": "https://github.com/monotykamary/pi-supervisor/raw/master/media/demo.mp4",
|
|
68
|
+
"image": "https://github.com/monotykamary/pi-supervisor/raw/master/media/screenshot.png"
|
|
69
|
+
},
|
|
70
|
+
"overrides": {
|
|
71
|
+
"brace-expansion": "5.0.6",
|
|
72
|
+
"fast-xml-builder": "1.2.0",
|
|
73
|
+
"protobufjs": "8.4.0",
|
|
74
|
+
"ws": "8.20.1"
|
|
75
|
+
},
|
|
76
|
+
"scripts": {
|
|
77
|
+
"test": "vitest run",
|
|
78
|
+
"test:watch": "vitest",
|
|
79
|
+
"typecheck": "tsc --noEmit",
|
|
80
|
+
"lint:dead": "knip --no-gitignore",
|
|
81
|
+
"format": "prettier --write .",
|
|
82
|
+
"format:check": "prettier --check .",
|
|
83
|
+
"release": "standard-version",
|
|
84
|
+
"release:dry-run": "standard-version --dry-run",
|
|
85
|
+
"postinstall": "simple-git-hooks 2>/dev/null || true"
|
|
86
|
+
}
|
|
87
|
+
}
|