@cr1ms0n/pi-subagent 0.8.9 → 0.9.0
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 +11 -1
- package/README.md +218 -115
- package/docs/ARCHITECTURE.md +56 -13
- package/docs/COST-ACCOUNTING.md +116 -66
- package/docs/RELEASING.md +32 -32
- package/docs/SECURITY.md +42 -5
- package/docs/UX.md +158 -141
- package/package.json +2 -2
- package/skills/subagent/SKILL.md +78 -49
- package/src/backends/pi.ts +164 -94
- package/src/child-preflight.ts +166 -0
- package/src/config.ts +254 -252
- package/src/dispatch-preflight.ts +87 -0
- package/src/dispatch-routing.ts +56 -0
- package/src/extension.ts +366 -158
- package/src/format.ts +436 -365
- package/src/jev-router.ts +1036 -0
- package/src/orchestrator.ts +75 -19
- package/src/persistence.ts +643 -335
- package/src/policy.ts +120 -89
- package/src/process-lock.ts +730 -687
- package/src/protocol.ts +320 -290
- package/src/registry.ts +730 -632
- package/src/routing-policy.ts +268 -0
- package/src/routing-types.ts +217 -0
- package/src/runner.ts +1299 -850
- package/src/schema.ts +10 -10
- package/src/startup-check.ts +481 -0
- package/src/types.ts +208 -198
- package/src/usage.ts +316 -274
- package/src/model-policy.ts +0 -169
package/docs/UX.md
CHANGED
|
@@ -1,141 +1,158 @@
|
|
|
1
|
-
# pi-subagent UX
|
|
2
|
-
|
|
3
|
-
## Overview
|
|
4
|
-
The standalone pi-subagent provides rich TUI support for monitoring, inspecting, and interacting with isolated subagent runs (single and parallel modes): inline streaming blocks, a terse footer, an ambient widget for background runs, batched completion notifications, mid-run steering, a worktree apply loop, and the `/subagents` inspector. UI logic is kept independent from `runner`/`registry` via small structural adapters (`SubagentAdapter`).
|
|
5
|
-
|
|
6
|
-
## Design principles
|
|
7
|
-
|
|
8
|
-
1. **Pi's tool shell owns state signaling.** The Box wrapper paints
|
|
9
|
-
`toolPendingBg` / `toolSuccessBg` / `toolErrorBg`, so inline blocks do not
|
|
10
|
-
repeat state words or draw their own success/error framing.
|
|
11
|
-
2. **Cost is a per-run attribute, not a competing ledger.** Dollar cost appears
|
|
12
|
-
inside the run's own result block; the parent/children/combined ledger is
|
|
13
|
-
available on demand via `/subagent-cost`, in `status` tool output, and in the
|
|
14
|
-
`/subagents` overlay header. The footer never shows cost.
|
|
15
|
-
3. **Fixed-height, mutate-in-place progress.** Streaming blocks keep a stable
|
|
16
|
-
shape (stats line + one `⎿ activity` line; parallel adds one line per task)
|
|
17
|
-
and the same component identity is reused across partial renders.
|
|
18
|
-
4. **Trailing-edge streaming flush.** Structural updates (state transition, new
|
|
19
|
-
session id, billed turn) emit immediately; live-text bursts coalesce with a
|
|
20
|
-
deferred flush so the last update of a burst always lands.
|
|
21
|
-
|
|
22
|
-
## Surfaces
|
|
23
|
-
|
|
24
|
-
### Inline tool block (foreground runs)
|
|
25
|
-
- `renderCall` is exactly one line: `subagent <task preview>` (or
|
|
26
|
-
`N parallel tasks — first task…`, `wait a1b2c3d4`, `… · background`).
|
|
27
|
-
- `renderResult` while streaming (fixed shape, spinner animates via wall-clock
|
|
28
|
-
frame; Pi's working indicator drives repaints):
|
|
29
|
-
```
|
|
30
|
-
⠹ ↻3 · 12.4k tok · 8s
|
|
31
|
-
⎿ reading src/auth/middleware.ts…
|
|
32
|
-
```
|
|
33
|
-
- Terminal single run:
|
|
34
|
-
```
|
|
35
|
-
↻8 · 33.8k tok · $0.012 · 12s
|
|
36
|
-
⎿ Found 5 middleware call sites…
|
|
37
|
-
→ /tmp/report.md
|
|
38
|
-
```
|
|
39
|
-
- Parallel: one line per task with a themed state glyph
|
|
40
|
-
(`◌ queued · ⠹ running · ✓ done · ✗ failed · ◐ partial · − cancelled · ◷ timeout`),
|
|
41
|
-
per-task stats, and a one-line tail (live activity or first output line).
|
|
42
|
-
- Expanded (Ctrl+O / `app.tools.expand`): full task output capped with a dim
|
|
43
|
-
`… +N lines` trailer pointing at the artifact/child session.
|
|
44
|
-
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
###
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
-
|
|
82
|
-
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
###
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
1
|
+
# pi-subagent UX
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
The standalone pi-subagent provides rich TUI support for monitoring, inspecting, and interacting with isolated subagent runs (single and parallel modes): inline streaming blocks, a terse footer, an ambient widget for background runs, batched completion notifications, mid-run steering, a worktree apply loop, and the `/subagents` inspector. UI logic is kept independent from `runner`/`registry` via small structural adapters (`SubagentAdapter`).
|
|
5
|
+
|
|
6
|
+
## Design principles
|
|
7
|
+
|
|
8
|
+
1. **Pi's tool shell owns state signaling.** The Box wrapper paints
|
|
9
|
+
`toolPendingBg` / `toolSuccessBg` / `toolErrorBg`, so inline blocks do not
|
|
10
|
+
repeat state words or draw their own success/error framing.
|
|
11
|
+
2. **Cost is a per-run attribute, not a competing ledger.** Dollar cost appears
|
|
12
|
+
inside the run's own result block; the parent/children/combined ledger is
|
|
13
|
+
available on demand via `/subagent-cost`, in `status` tool output, and in the
|
|
14
|
+
`/subagents` overlay header. The footer never shows cost.
|
|
15
|
+
3. **Fixed-height, mutate-in-place progress.** Streaming blocks keep a stable
|
|
16
|
+
shape (stats line + one `⎿ activity` line; parallel adds one line per task)
|
|
17
|
+
and the same component identity is reused across partial renders.
|
|
18
|
+
4. **Trailing-edge streaming flush.** Structural updates (state transition, new
|
|
19
|
+
session id, billed turn) emit immediately; live-text bursts coalesce with a
|
|
20
|
+
deferred flush so the last update of a burst always lands.
|
|
21
|
+
|
|
22
|
+
## Surfaces
|
|
23
|
+
|
|
24
|
+
### Inline tool block (foreground runs)
|
|
25
|
+
- `renderCall` is exactly one line: `subagent <task preview>` (or
|
|
26
|
+
`N parallel tasks — first task…`, `wait a1b2c3d4`, `… · background`).
|
|
27
|
+
- `renderResult` while streaming (fixed shape, spinner animates via wall-clock
|
|
28
|
+
frame; Pi's working indicator drives repaints):
|
|
29
|
+
```
|
|
30
|
+
⠹ ↻3 · 12.4k tok · 8s
|
|
31
|
+
⎿ reading src/auth/middleware.ts…
|
|
32
|
+
```
|
|
33
|
+
- Terminal single run:
|
|
34
|
+
```
|
|
35
|
+
↻8 · 33.8k tok · $0.012 · 12s
|
|
36
|
+
⎿ Found 5 middleware call sites…
|
|
37
|
+
→ /tmp/report.md
|
|
38
|
+
```
|
|
39
|
+
- Parallel: one line per task with a themed state glyph
|
|
40
|
+
(`◌ queued · ⠹ running · ✓ done · ✗ failed · ◐ partial · − cancelled · ◷ timeout`),
|
|
41
|
+
per-task stats, and a one-line tail (live activity or first output line).
|
|
42
|
+
- Expanded (Ctrl+O / `app.tools.expand`): full task output capped with a dim
|
|
43
|
+
`… +N lines` trailer pointing at the artifact/child session.
|
|
44
|
+
- Expanded detail adds one bounded route line for Jev-routed runs: selected
|
|
45
|
+
execution model, selected tools (plus locally added control-plane tools),
|
|
46
|
+
selector version, confidence, outcome and selection latency. Legacy runs
|
|
47
|
+
simply have no route line.
|
|
48
|
+
- Durations freeze at `endedAt`; running durations tick at render time.
|
|
49
|
+
- Reliability annotations render inline: `[attempt 2]` during a same-model
|
|
50
|
+
retry, `[stalled 2m]` while the stall watchdog is flagging silence, and
|
|
51
|
+
`◐ wrapped up` on budget-stopped runs that concluded gracefully.
|
|
52
|
+
|
|
53
|
+
### Footer status
|
|
54
|
+
Terse and actionable only: `⚙ 2 running · 1 ready · /subagents`. Cleared when
|
|
55
|
+
nothing is running or ready. No cost — Pi's footer already shows session cost.
|
|
56
|
+
|
|
57
|
+
### Ambient widget (background runs only)
|
|
58
|
+
An above-editor widget renders while `async: true` runs are live — foreground
|
|
59
|
+
runs already render inline as the tool result, so they never appear here
|
|
60
|
+
(avoids double-render):
|
|
61
|
+
|
|
62
|
+
```
|
|
63
|
+
● Subagents
|
|
64
|
+
├─ ⠼ Audit deps · ↻4 · 18k tok · 41s
|
|
65
|
+
│ ⎿ checking license headers…
|
|
66
|
+
└─ ◌ License scan · 12s
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Cleared when the last background run settles. Spinner and elapsed animate on
|
|
70
|
+
a 250ms interval that exists only while background runs are live.
|
|
71
|
+
|
|
72
|
+
### Completion notifications (background runs only)
|
|
73
|
+
When an async run reaches a terminal state, a `steer` message (custom type
|
|
74
|
+
`subagent-completion`) is queued for the parent LLM before its next LLM call,
|
|
75
|
+
so it can react without polling. The human sees a themed compact box (state
|
|
76
|
+
glyph, label, stats, one-line preview, artifact pointers); the LLM sees plain
|
|
77
|
+
text with run ids and a `wait { id }` pointer.
|
|
78
|
+
|
|
79
|
+
- Successes within a short window batch into one message (no fanout spam);
|
|
80
|
+
failures bypass batching and flush immediately, carrying held successes.
|
|
81
|
+
- A `wait` that already delivered the run suppresses the redundant
|
|
82
|
+
notification (delivered-state is re-checked at flush time).
|
|
83
|
+
|
|
84
|
+
### `/subagents` overlay
|
|
85
|
+
- Header: title + running/ready counters + full usage ledger + rule.
|
|
86
|
+
- List: two lines per run — glyph/id/state/stats, then the task preview.
|
|
87
|
+
Selection cursor `▶`, animated spinner for live runs.
|
|
88
|
+
- Detail: run stats, summary, then per-task sections (glyph, label,
|
|
89
|
+
model/selector route/profile/thinking, usage, pointers, transcript/final
|
|
90
|
+
output/errors), scrollable with ↑↓/j/k and PageUp/PageDown.
|
|
91
|
+
- Actions: `c` cancel, `s` steer (prompts for a message, injects it into the
|
|
92
|
+
running child), `d` dismiss, `r` resume, `o` output pointers, `a` apply a
|
|
93
|
+
finished run's changed worktree into the main checkout (confirm dialog),
|
|
94
|
+
`x` discard worktree + branch (confirm dialog), Enter drill-down,
|
|
95
|
+
Esc/b back, Esc/q close.
|
|
96
|
+
- Live transcript (`t` on a **running** run's detail): tails the child's
|
|
97
|
+
session file (`sessionDir/<…sessionId…>.jsonl`) on a 500ms poll while the
|
|
98
|
+
pane is visible — compact role/tool lines, auto-follow unless you scroll
|
|
99
|
+
up (which pauses follow). No RPC reads; hidden/finished runs never poll.
|
|
100
|
+
Missing file shows “waiting for child session…”. `s` steering still works
|
|
101
|
+
from the same pane so observe → steer stays on one surface.
|
|
102
|
+
|
|
103
|
+
### `/subagent-cost`
|
|
104
|
+
Prints the root/subagents/routing/combined ledger once, on demand. Routing
|
|
105
|
+
tokens appear as their own category and their currency as unreported; the known
|
|
106
|
+
dollar totals exclude that unreported selector spend.
|
|
107
|
+
|
|
108
|
+
### Mid-run steering
|
|
109
|
+
Children run in Pi RPC mode, so their stdin stays open as a command channel.
|
|
110
|
+
`action: "steer"` (or `s` in the overlay) queues a message that is delivered
|
|
111
|
+
after the child's current assistant turn, before its next LLM call — course
|
|
112
|
+
correction without cancel + retry. Parallel runs steer one task via `index`.
|
|
113
|
+
|
|
114
|
+
### Worktree loop
|
|
115
|
+
Finished runs with changed worktrees support `diff` / `apply` / `discard`
|
|
116
|
+
actions (tool) and `a` / `x` keys (overlay). `apply` lands the worktree's
|
|
117
|
+
combined patch (committed + uncommitted + untracked vs base) onto the main
|
|
118
|
+
checkout as **uncommitted working-tree changes** via `git apply --3way`; it
|
|
119
|
+
never commits and never deletes the worktree. `discard` is the explicit
|
|
120
|
+
cleanup step and always confirms first.
|
|
121
|
+
|
|
122
|
+
### Parallel fan-in
|
|
123
|
+
`synthesis: "<instruction>"` on a parallel run asks for one read-only child
|
|
124
|
+
after all tasks settle that folds their outputs into a single brief, delivered
|
|
125
|
+
first in the result. It is best effort and deferred: its route is selected only
|
|
126
|
+
when aggregation is actually needed after the workers finish, so it never blocks
|
|
127
|
+
worker launch. A selector or child failure keeps the raw worker outputs, their
|
|
128
|
+
usage and a bounded `Optional synthesis blocked: …` diagnostic instead of
|
|
129
|
+
discarding or re-routing them.
|
|
130
|
+
|
|
131
|
+
### Plan results (tool output, not TUI)
|
|
132
|
+
`action:"plan"` returns the resolved model/tools and the selector usage it
|
|
133
|
+
incurred, and states that a later dispatch selects again. It starts no child and
|
|
134
|
+
creates no run entry, so plan never adds an overlay row or ambient widget. A
|
|
135
|
+
plan whose optional synthesis selection fails still returns the valid worker plan
|
|
136
|
+
and labels only that synthetic stage blocked with its diagnostic.
|
|
137
|
+
|
|
138
|
+
## States
|
|
139
|
+
- **Queued/Running**: spinner + live stats + activity tail from live text.
|
|
140
|
+
- **Completed/Partial/Failed/Cancelled/Timeout/Lost**: state glyph, frozen
|
|
141
|
+
duration, usage summary, output pointers; failures show the error message.
|
|
142
|
+
- **Delivered vs Undelivered**: footer/overlay track pending delivery.
|
|
143
|
+
- **Notification**: one per terminal transition to avoid spam.
|
|
144
|
+
|
|
145
|
+
## Integration Notes
|
|
146
|
+
- Extension wires via `ctx.ui.custom((tui, theme, kb, done) => createSubagentsOverlay(tui, theme, adapter, done), {overlay: true})`.
|
|
147
|
+
- Adapter provides getActiveRuns/getCompletedRuns/cancelRun etc. without tight coupling.
|
|
148
|
+
- Inline renderers reuse `context.lastComponent` (a `LineBlock`) so the row keeps
|
|
149
|
+
a stable component identity across partial renders.
|
|
150
|
+
- Streamed tool updates separate LLM-facing `content` (compact status string)
|
|
151
|
+
from render-facing `details` (state, usage, live-text tail, run timing).
|
|
152
|
+
- Tests combine pure UI models with a headless Pi extension harness: format
|
|
153
|
+
helpers, block layouts (collapsed/streaming/terminal/parallel), navigation,
|
|
154
|
+
truncation (ANSI-safe via `visibleWidth`), ready state, lifecycle/disposal.
|
|
155
|
+
- Follows Pi TUI guidelines (render(width), handleInput, invalidate,
|
|
156
|
+
requestRender, dispose). The overlay owns a single animation interval.
|
|
157
|
+
|
|
158
|
+
See ARCHITECTURE.md for ownership boundaries. All rendering respects terminal width and ANSI safety.
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cr1ms0n/pi-subagent",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Community fork of Luke Parke's pi-subagent with
|
|
3
|
+
"version": "0.9.0",
|
|
4
|
+
"description": "Community fork of Luke Parke's pi-subagent with Jev model/tool routing and verified Pi child capabilities",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"author": "Luke Parke",
|
package/skills/subagent/SKILL.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: subagent
|
|
3
|
-
description: Delegate work to isolated child agents with the subagent tool
|
|
3
|
+
description: Delegate work to isolated child agents with the subagent tool. Jev routes each new dispatch to an execution model and individual tools from the user's configured candidate list; covers explore/review/general profiles, parallel fanout with best-effort synthesis, worktree isolation and the diff/apply/discard loop, background runs, steering, output_schema, context fork, and the Pi-only new-dispatch rule. Use when delegating exploration or implementation, running tasks in parallel, or when a subagent run needs inspecting, steering, or landing.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Subagent
|
|
@@ -20,24 +20,24 @@ from isolation, parallelism, or a fresh context.
|
|
|
20
20
|
## Core calls
|
|
21
21
|
|
|
22
22
|
```ts
|
|
23
|
-
//
|
|
24
|
-
//
|
|
25
|
-
|
|
23
|
+
// Omit model and fallback_models. Jev selects the execution model from the
|
|
24
|
+
// user's configured candidate list and the individual tools from the locally
|
|
25
|
+
// permitted catalog. An explicit model/fallback is rejected on new work.
|
|
26
26
|
|
|
27
27
|
// Single foreground task (default profile: general)
|
|
28
|
-
{ task: "Find call sites of parseConfig", description: "Map parseConfig"
|
|
28
|
+
{ task: "Find call sites of parseConfig", description: "Map parseConfig" }
|
|
29
29
|
|
|
30
30
|
// Parallel read-only explorers (default profile for tasks[]: explore)
|
|
31
31
|
{
|
|
32
32
|
tasks: [
|
|
33
|
-
{ task: "Map auth middleware", description: "Auth flow"
|
|
34
|
-
{ task: "List env vars in server/", description: "Env inventory"
|
|
33
|
+
{ task: "Map auth middleware", description: "Auth flow" },
|
|
34
|
+
{ task: "List env vars in server/", description: "Env inventory" }
|
|
35
35
|
],
|
|
36
36
|
synthesis: "Merge into one prioritized brief"
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
-
// Background
|
|
40
|
-
{ task: "Audit dependency licenses",
|
|
39
|
+
// Background: notified on completion; wait/status still work
|
|
40
|
+
{ task: "Audit dependency licenses", async: true }
|
|
41
41
|
{ action: "status", id: "abc123" }
|
|
42
42
|
{ action: "wait", id: "abc123" } // interruptible; does not cancel
|
|
43
43
|
{ action: "cancel", id: "abc123" }
|
|
@@ -45,69 +45,98 @@ const routeModel = "<exact model from current modelPolicy route>";
|
|
|
45
45
|
// subagent_wait { id: "abc123", timeout_ms?: number }
|
|
46
46
|
|
|
47
47
|
// Worktree loop
|
|
48
|
-
{ task: "Implement feature A",
|
|
48
|
+
{ task: "Implement feature A", profile: "general", isolation: "worktree" }
|
|
49
49
|
{ action: "diff", id: "abc123", index: 1 }
|
|
50
50
|
{ action: "apply", id: "abc123", index: 1 }
|
|
51
51
|
{ action: "discard", id: "abc123", index: 1 }
|
|
52
52
|
|
|
53
|
-
// Dry-run validation + resolved plan (no spawn)
|
|
54
|
-
// plan
|
|
55
|
-
{ action: "plan", tasks: [{ task: "…",
|
|
53
|
+
// Dry-run validation + resolved plan (no spawn).
|
|
54
|
+
// plan calls Jev and incurs selector fees, then a later dispatch selects again.
|
|
55
|
+
{ action: "plan", tasks: [{ task: "…", isolation: "worktree" }] }
|
|
56
56
|
```
|
|
57
57
|
|
|
58
58
|
## Profiles
|
|
59
59
|
|
|
60
60
|
| Profile | Tools | Writes |
|
|
61
61
|
| --------- | --------------------------------------------------------- | ------------------------------------------- |
|
|
62
|
-
| `explore` | read
|
|
62
|
+
| `explore` | locally permitted read-only tools + Pi context tools | no project-file writes |
|
|
63
63
|
| `review` | same as explore | no project-file writes |
|
|
64
|
-
| `general` |
|
|
64
|
+
| `general` | Jev chooses from the full available locally permitted catalog + Pi context tools | yes if the selected tools include bash/edit/write |
|
|
65
|
+
|
|
66
|
+
Jev picks individual tool names, not a capability bundle. Candidates come from
|
|
67
|
+
the full available locally permitted catalog, not from agent `tools` defaults and
|
|
68
|
+
not from only the parent's active tools. An explicit `tools` list is a ceiling,
|
|
69
|
+
explore/review stay read-only regardless of the answer, and an empty selection
|
|
70
|
+
never means "all tools".
|
|
65
71
|
|
|
66
72
|
For Pi children, `new_context`, `get_context_remaining`, `history`, and
|
|
67
|
-
`notes` are
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
73
|
+
`notes` are added locally when the parent exposes them, so the selector never
|
|
74
|
+
asks about them. They are control-plane tools: they may update context
|
|
75
|
+
notes/window state, but never grant `bash`, `edit`, or `write` access. Route
|
|
76
|
+
metadata reports them as local additions.
|
|
77
|
+
|
|
78
|
+
The finalized tool subset is passed to the child as Pi's `--tools` allowlist
|
|
79
|
+
(`--no-tools` for a true empty set). Pi 0.86.0 is the verified baseline for
|
|
80
|
+
built-in, extension and late-registered tool enforcement; an unsupported host is
|
|
81
|
+
refused rather than silently weakened.
|
|
71
82
|
|
|
72
83
|
Parallel write-capable tasks sharing one checkout are rejected unless each uses
|
|
73
84
|
`isolation: "worktree"`, a distinct `cwd`, or `allow_shared_writes: true`.
|
|
74
85
|
|
|
75
86
|
## Backends
|
|
76
87
|
|
|
77
|
-
`backend: "
|
|
78
|
-
**refused
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
|
88
|
+
New dispatch is Pi-only. `backend: "codex"` or `backend: "claude"` on new work
|
|
89
|
+
is **refused** before any selector or provider work, including a backend
|
|
90
|
+
inherited from agent frontmatter, and is never silently switched to Pi. Existing
|
|
91
|
+
Codex/Claude runs remain manageable through `status`/`wait`/`cancel`/`steer`/
|
|
92
|
+
`diff`/`apply`/`discard`.
|
|
93
|
+
|
|
94
|
+
Another provider's execution model is still eligible through Pi when the user
|
|
95
|
+
lists it in their candidate configuration. Unsupported combinations inside the
|
|
96
|
+
Pi path are **refused**, not silently degraded:
|
|
97
|
+
|
|
98
|
+
| | pi |
|
|
99
|
+
| ------------------------ | -------------- |
|
|
100
|
+
| `max_cost` | yes (provider-reported execution only; not selector currency) |
|
|
101
|
+
| read-only profile | tool allowlist |
|
|
102
|
+
| steering / grace wrap-up | yes |
|
|
103
|
+
| `context: "fork"` | yes |
|
|
104
|
+
| `thinking` | yes |
|
|
105
|
+
| `output_schema` | yes |
|
|
88
106
|
|
|
89
107
|
## Budgets and safety
|
|
90
108
|
|
|
91
109
|
- Prefer `max_turns`, `max_cost`, and/or `timeout_ms` on long or write-capable runs.
|
|
110
|
+
`timeout_ms` is absolute: local preflight, Jev selection, setup, queue and
|
|
111
|
+
runtime all count against it.
|
|
92
112
|
- `output_schema` asks the child for a fenced `json:result` block (one repair round).
|
|
93
|
-
- `context: "fork"` continues from a fork of the parent session
|
|
94
|
-
- Do not poll `status` in a tight loop
|
|
113
|
+
- `context: "fork"` continues from a fork of the parent session.
|
|
114
|
+
- Do not poll `status` in a tight loop. Use `wait` / `subagent_wait`, or let the
|
|
95
115
|
completion notification arrive for `async: true` runs.
|
|
96
116
|
- Point the user at `/subagents` for the live inspector and `/subagent-cost` for
|
|
97
|
-
the root / subagent / combined ledger.
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
`
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
117
|
+
the root / subagent / routing / combined ledger. Routing cost is reported as
|
|
118
|
+
unreported (tokens only, no currency).
|
|
119
|
+
|
|
120
|
+
## Routing
|
|
121
|
+
|
|
122
|
+
Omit `model` and `fallback_models` on every new call: both are legacy fields,
|
|
123
|
+
and an explicit value is rejected rather than bypassing selection. Jev chooses
|
|
124
|
+
one execution model from the user's dedicated candidate list plus an individual
|
|
125
|
+
include/exclude decision per eligible tool. The local policy then re-validates
|
|
126
|
+
the answer: unknown or unsafe tools cannot launch, explore/review stay read-only,
|
|
127
|
+
and management actions need no routing config or credential.
|
|
128
|
+
|
|
129
|
+
There are no emergency or fallback models, and low confidence is accepted rather
|
|
130
|
+
than treated as a threshold. A Jev timeout or API failure stops the affected new
|
|
131
|
+
dispatch with an actionable error; existing runs stay queryable and cancellable.
|
|
132
|
+
Transient child failures retry the already selected model and tool set within the
|
|
133
|
+
original deadline, up to `max_retries`; a quality failure never reselects.
|
|
134
|
+
|
|
135
|
+
An optional candidate `thinking` value is an opaque Pi thinking-level string;
|
|
136
|
+
common values include `off`, `minimal`, `low`, `medium`, `high`, `xhigh`, and
|
|
137
|
+
`max`, but model-specific values are passed through unchanged. It is a default:
|
|
138
|
+
explicit task, agent, and profile `taskDefaults.thinking` values override it.
|
|
139
|
+
The extension re-reads `jevRouting` on each dispatch and injects the current
|
|
140
|
+
routing guidance into the parent prompt. If `jevRouting` is missing or invalid,
|
|
141
|
+
or the credential environment variable is unset, management remains available but
|
|
142
|
+
new spawns, `/btw`, plan, resume, fork and synthesis are rejected.
|