pi-task-dispatcher 1.0.0 → 3.0.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/README.md CHANGED
@@ -1,133 +1,192 @@
1
1
  # pi-task-dispatcher
2
2
 
3
- Delegate bounded mechanical and engineering subtasks to configurable Pi worker models without replacing the model selected for the main Pi session.
3
+ Supervised mechanical and engineering delegations for Pi.
4
4
 
5
- ## How it works
5
+ Each delegation runs in an isolated, in-memory Pi RPC session. After every cohesive tool batch, a worker-side gate stops execution at a safe boundary and returns a bounded state report. The manager can then inspect the result and explicitly continue, revise, compact, checkpoint, cancel, or take over.
6
6
 
7
- Your selected Pi model remains the **orchestrator**: it decides whether to delegate, supplies a self-contained task, evaluates the worker report, reviews material changes, and owns the final answer. This package adds two model-only tools:
7
+ ## Features
8
8
 
9
- | Tool | Use it when |
10
- | --- | --- |
11
- | `delegate_mechanical` | The outcome and constraints are precise and the work is bounded, multi-step, and primarily inspection, exact edits, repetitive transformation, commands, retrieval, or verification. Use a direct tool for a single trivial operation. |
12
- | `delegate_engineering` | A self-contained engineering subtask needs investigation, implementation, debugging, refactoring, testing, review, research, or analysis. Include the outcome, constraints, and acceptance conditions. |
13
-
14
- Both workers operate in the current workspace and can modify files when their configured tools permit it.
15
-
16
- After the orchestrator selects a delegation tool, its role is routed deterministically to that role's configured `provider/model`. That routing does **not** make a worker's output, changes, or correctness deterministic; treat every worker report as input to review and verification.
9
+ - **Two worker roles:** mechanical execution and broader engineering work.
10
+ - **Enforced supervision:** a private parent-child IPC gate calls `ctx.abort()` after persisted tool results; pausing does not depend on the worker following a prompt.
11
+ - **Explicit control:** continue, revise, recalculate, compact, checkpoint, cancel, or take over.
12
+ - **Resumable context:** continuation uses the same in-memory worker session and completed tool results.
13
+ - **Least privilege:** every start selects an exact Pi built-in worker-tool allowlist; delegation tools and unrelated discovered extensions are unavailable to the worker.
14
+ - **Model agnostic:** both roles inherit Pi's active model and thinking level unless an explicit role override is configured.
15
+ - **Formula-owned budgets:** the manager supplies semantic workload units, while the dispatcher calculates turn and time ceilings from workload, role, and delegated-model limits.
16
+ - **Context insight:** boundary reports include worker context usage, compactions, turns, elapsed time, action counts, and recommendations.
17
+ - **Recoverable reports:** the complete action ledger and worker text remain in structured tool details; bounded model-facing text retains recent actions plus both the beginning and ending of long reports.
18
+ - **Deterministic UI:** tool renderers display task, current activity, elapsed time, context pressure, and terminal success/failure colors. A compact paused-state line appears in Pi's footer.
17
19
 
18
20
  ## Requirements
19
21
 
20
- - Pi 1.0.0 or later
22
+ - Pi 1.0.3 or later
21
23
  - Node.js 22.19.0 or later
22
- - A configured, authenticated Pi model for each worker role you invoke
24
+ - One active, authenticated Pi model; optional role-specific models must also be available and authenticated
23
25
 
24
- ## Install
26
+ The supervision gate requires the parent Pi process and child Pi CLI to run under Node.js with an inherited IPC channel. The dispatcher fails closed when that boundary cannot be established; it does not fall back to prompt-only supervision. Worker processes disable ordinary extension discovery and load only the generated supervision gate.
25
27
 
26
- Install the published package for your Pi user configuration:
28
+ ## Installation
29
+
30
+ Install the published package for the current Pi user:
27
31
 
28
32
  ```sh
29
- pi install npm:pi-task-dispatcher@1.0.0
33
+ pi install npm:pi-task-dispatcher
30
34
  ```
31
35
 
32
- For a local checkout, run this from its parent directory:
36
+ ## Tools
33
37
 
34
- ```sh
35
- pi install ./pi-task-dispatcher
36
- ```
38
+ | Tool | Responsibility |
39
+ | --- | --- |
40
+ | `delegate_mechanical` | Start a supervised mechanic delegation. |
41
+ | `delegate_engineering` | Start a supervised engineer delegation. |
42
+ | `delegate_control` | Apply one explicit manager decision to a paused delegation. |
43
+ | `delegate_status` | Recover the current or most recent state without changing it. |
37
44
 
38
- To register either source in the current project's `.pi/settings.json` instead, add `--local`:
45
+ Only one live delegation is currently permitted. A terminal delegation may be inspected until a new one replaces it.
39
46
 
40
- ```sh
41
- pi install npm:pi-task-dispatcher@1.0.0 --local
42
- ```
47
+ ## Starting a delegation
48
+
49
+ Both role tools require:
43
50
 
44
- Project packages load only after that project is trusted. In an already running Pi session, run:
51
+ - `task`: a self-contained objective, scope, constraints, and acceptance checks;
52
+ - `tools`: the smallest exact allowlist selected from Pi's built-in tools and active for the main agent;
53
+ - `workload`: semantic estimates used by the deterministic budget formula.
45
54
 
46
- ```text
47
- /reload
55
+ ```json
56
+ {
57
+ "task": "Inspect the parser cache, correct its invalidation, and run the focused tests.",
58
+ "tools": ["read", "edit", "bash"],
59
+ "workload": {
60
+ "investigationUnits": 3,
61
+ "changeUnits": 2,
62
+ "verificationUnits": 2,
63
+ "expectedLongRunningSeconds": 60
64
+ }
65
+ }
48
66
  ```
49
67
 
50
- `/reload` reloads extensions and other discovered resources. The worker configuration below is read again for every delegation.
68
+ A workload unit is intentionally semantic:
51
69
 
52
- ## Default workers
70
+ - `investigationUnits`: cohesive components or evidence groups to inspect;
71
+ - `changeUnits`: related edit groups;
72
+ - `verificationUnits`: focused check or test groups;
73
+ - `expectedLongRunningSeconds`: additional expected command time.
53
74
 
54
- | Role | Model | Thinking | Timeout | Turn limit |
55
- | --- | --- | --- | ---: | ---: |
56
- | Mechanic | `openai-codex/gpt-5.6-luna` | `max` | 300 seconds | 20 |
57
- | Engineer | `openai-codex/gpt-5.6-terra` | `max` | 900 seconds | 30 |
75
+ At least one investigation, change, or verification unit is required.
58
76
 
59
- By default, both workers receive this explicit tool allowlist:
77
+ Isolated workers accept `read`, `bash`, `powershell`, `edit`, `write`, `grep`, `find`, and `ls` when the selected tools are also active in the main Pi session. Extension tools are not supported because the child disables extension discovery.
60
78
 
61
- ```text
62
- read,bash,edit,write
63
- ```
79
+ The current formula derives planned work turns from those units, applies a role factor and a bounded scale based on the selected delegated model's own context window, reserves two additional turns for synthesis or recovery, then derives active execution time from calculated turns plus expected long-running time. Administrative ceilings always win. Formula inputs and results are returned in every state report so they can be reviewed and recalculated. Time spent paused for manager deliberation does not consume the active execution budget.
80
+
81
+ ## Safe action boundaries
82
+
83
+ A worker run proceeds as follows:
84
+
85
+ 1. Pi produces one assistant response.
86
+ 2. Its complete tool-call batch runs and tool results are persisted.
87
+ 3. The worker-only gate reports the boundary through private IPC.
88
+ 4. The gate aborts the automatic next worker turn.
89
+ 5. The RPC run settles while the child process and in-memory context remain alive.
90
+ 6. The delegation tool returns the new state to the manager.
91
+
92
+ An action batch can contain parallel tool calls from one worker response. Already-running tools are allowed to finish. The boundary prevents another productive model turn from starting without a manager decision.
93
+
94
+ ## Controlling a paused delegation
64
95
 
65
- `pi-task-dispatcher` provides only these four native Pi tools by default; it does not provide `web_search`, `fetch_content`, `get_search_content`, or `source_check`. If you have the separate `pi-web-access` package installed, you may explicitly add those tools to a role's `tools` array:
96
+ `delegate_control` accepts these actions:
97
+
98
+ | Action | Effect |
99
+ | --- | --- |
100
+ | `continue` | Resume from completed results. `actionBatches` may lease 1–10 batches before returning. |
101
+ | `revise` | Add controlling instructions, then resume. |
102
+ | `recalculate` | Supply remaining semantic workload and extend the current ceilings from observed turns and active execution time without running the worker. |
103
+ | `compact` | Compact the idle worker's own context and return refreshed state. |
104
+ | `take_over` | Stop the delegation externally and transfer remaining work to the manager. |
105
+ | `checkpoint` | Stop externally and preserve a synthetic checkpoint from observed state. |
106
+ | `cancel` | Stop externally and close the job. |
107
+
108
+ Example:
66
109
 
67
110
  ```json
68
111
  {
69
- "mechanic": {
70
- "tools": ["read", "bash", "edit", "write", "web_search", "fetch_content", "get_search_content", "source_check"]
71
- }
112
+ "jobId": "engineer-2",
113
+ "action": "continue",
114
+ "actionBatches": 2
72
115
  }
73
116
  ```
74
117
 
75
- ## Configure workers
118
+ The dispatcher enforces takeover, cancellation, budget exhaustion, no-progress policy, and process cleanup. These actions do not depend on worker cooperation.
119
+
120
+ ## State reports and screen output
121
+
122
+ A paused result contains:
123
+
124
+ - a session-local sequential identity such as `engineer-2`, plus role, model, and status;
125
+ - the delegated task and live command or tool activity while execution is running;
126
+ - boundary sequence and current phase;
127
+ - completed, failed, and potentially mutating action counts;
128
+ - recent bounded activity labels;
129
+ - active elapsed time and turns against calculated budgets;
130
+ - context tokens, context window, percentage, and compaction counts;
131
+ - a recommended next decision;
132
+ - bounded worker text, if any.
133
+
134
+ The TUI renders the same structured state as a compact block. Expanding the tool result reveals bounded worker text. The complete action ledger and worker text remain in result details for state reconstruction rather than being discarded by display truncation.
135
+
136
+ When paused, one unindented footer status appears below Pi's primary report. It shows the identity, active elapsed time, last activity, and context as percentage/window—for example, `10.3%/32k context`. The percentage and window both come from that delegation's selected model and live worker-session statistics, not from the main model.
137
+
138
+ ## Worker compaction
76
139
 
77
- Optionally create `~/.pi/agent/task-dispatcher.json`. If Pi's agent directory is overridden, use `<agent-dir>/task-dispatcher.json` instead. Missing role objects and fields inherit the defaults.
140
+ The dispatcher explicitly enables automatic compaction in every worker session. Pi's automatic compaction remains the overflow safety mechanism.
78
141
 
79
- This is a complete valid configuration using the defaults:
142
+ The dispatcher also:
143
+
144
+ - observes compaction lifecycle events;
145
+ - accounts for reported compaction usage;
146
+ - queries `get_session_stats` at safe boundaries;
147
+ - recommends proactive compaction when context usage reaches the current policy threshold;
148
+ - permits explicit worker compaction only while paused.
149
+
150
+ Worker compaction is independent from compaction of the main Pi conversation.
151
+
152
+ ## Configuration
153
+
154
+ The optional configuration file is `task-dispatcher.json` in Pi's agent directory.
80
155
 
81
156
  ```json
82
157
  {
83
- "version": 1,
84
- "mechanic": {
85
- "model": "openai-codex/gpt-5.6-luna",
86
- "thinking": "max",
87
- "tools": [
88
- "read",
89
- "bash",
90
- "edit",
91
- "write"
92
- ],
93
- "timeoutSeconds": 300,
94
- "maxTurns": 20
95
- },
96
- "engineer": {
97
- "model": "openai-codex/gpt-5.6-terra",
98
- "thinking": "max",
99
- "tools": [
100
- "read",
101
- "bash",
102
- "edit",
103
- "write"
104
- ],
105
- "timeoutSeconds": 900,
106
- "maxTurns": 30
158
+ "policy": {
159
+ "absoluteMaxTurns": 96,
160
+ "absoluteMaxSeconds": 7200,
161
+ "pausedLeaseSeconds": 1800,
162
+ "noProgressSeconds": 600
107
163
  }
108
164
  }
109
165
  ```
110
166
 
111
- | Field | Meaning |
112
- | --- | --- |
113
- | `version` | Optional. When present, it must be `1`. |
114
- | `mechanic`, `engineer` | Optional per-role objects. Each supplied field overrides that role's default. |
115
- | `model` | A `provider/model` string. Pi verifies that the exact model exists in its registry and has usable authentication before starting the worker. |
116
- | `thinking` | One of `off`, `minimal`, `low`, `medium`, `high`, `xhigh`, or `max`. |
117
- | `tools` | A non-empty array of tool names. It replaces, rather than extends, the default allowlist; duplicate names are removed. |
118
- | `timeoutSeconds` | Positive integer wall-clock limit for the worker process. |
119
- | `maxTurns` | Positive integer limit for a continuing tool-using worker loop. |
167
+ Configuration is read for every new delegation. By default, both roles inherit the manager's active model and thinking level, so installation assumes no particular provider or model access. A role may optionally override `model` with `"provider/model"`, `thinking`, or both. Policy values are administrative failsafes, not ordinary task budgets.
120
168
 
121
- ## Isolation, limits, and safety
169
+ Version 3 intentionally ignores the version 2 fields `maxTurns`, `timeoutSeconds`, and `checkpointGraceSeconds`. Remove them from local configuration after migration.
122
170
 
123
- Each delegation starts a separate, no-session Pi child process in the current workspace. The worker receives its role prompt, selected model, thinking level, and only the configured `tools` allowlist. The dispatcher does not register either delegation tool inside worker processes, so workers cannot recursively delegate through this package.
171
+ ## Lifecycle and cleanup
124
172
 
125
- The parent cancellation signal is propagated to the child. Workers are stopped on timeout, and an ongoing tool-using loop is stopped at its configured turn limit. While a worker runs, its tool activity can be reported as progress. Its final tool result includes the role, model, thinking level, configured tool names, status, turns, duration, exit information, activity, and aggregated usage; non-completed runs are returned as errors with a diagnostic and any available partial report. Reported failure states include configuration, model, and process errors, cancellation, timeout, turn-limit, and incomplete outcomes.
173
+ - A parent-operation abort stops the active worker stage.
174
+ - A paused lease eventually closes an abandoned worker.
175
+ - Session shutdown or extension reload disposes the child and runtime-controlled temporary files.
176
+ - Worker process failures reject pending RPC operations and produce a failed state.
177
+ - Worker role instructions and the supervision gate exist only in a runtime-controlled temporary directory.
178
+ - The worker uses `--no-session`; no worker session file is persisted.
179
+
180
+ Process separation is not a security sandbox. Worker tools execute with the Pi host's operating-system permissions. Tool availability does not establish task scope or authorization.
181
+
182
+ ## Development checks
183
+
184
+ ```sh
185
+ npm run check
186
+ npm run test:gate
187
+ ```
126
188
 
127
- > **Security warning:** Worker process isolation is not a security sandbox. A worker can use every tool in its configured allowlist with the Pi host's permissions in the current environment. Use the smallest practical allowlist and delegate only work you are prepared to authorize.
189
+ `check` runs static release invariants and deterministic fake-RPC lifecycle and renderer scenarios. The fake child verifies pause/resume, usage deltas, full action-ledger retention, intercepted prompts, missing-boundary failure, fail-closed timeouts, pre-aborted operations, partial argument rendering, stable repeated rendering, and manager-state transitions without a model request.
128
190
 
129
- ## Short workflow
191
+ `test:gate` performs a small live model integration check with the active parent model exported by Pi through `PI_PROVIDER`, `PI_MODEL`, and `PI_REASONING_LEVEL`, falling back to Pi's configured default when those values are unavailable; it contains no provider or model assumption. Optional `PI_TASK_DISPATCHER_GATE_MODEL` and `PI_TASK_DISPATCHER_GATE_THINKING` overrides are available for explicit test matrices. The probe verifies that the private gate pauses after a read batch and that the same in-memory child can subsequently complete. It requires configured credentials and therefore is not a hermetic unit test.
130
192
 
131
- 1. Select the normal Pi model that should orchestrate the task.
132
- 2. Give it a bounded request, for example: “Use `delegate_engineering` to diagnose the failing parser test. Do not change public APIs; run the focused test; return the cause, files changed, and test result.”
133
- 3. The orchestrator calls the selected worker tool, receives its report, inspects relevant changes and verification, then produces the final response.