pi-delegation-policy 0.3.0 → 0.3.2
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 +12 -0
- package/README.md +30 -109
- package/SECURITY.md +1 -1
- package/package.json +1 -1
- package/src/delegate-panel.ts +23 -14
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,18 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
## 0.3.2 - 2026-08-26
|
|
6
|
+
|
|
7
|
+
### Documentation
|
|
8
|
+
|
|
9
|
+
- Refreshed the README and wiki with the current package status, safe first-use path, panel behavior, configuration hierarchy, and privacy boundaries.
|
|
10
|
+
|
|
11
|
+
## 0.3.1 - 2026-08-26
|
|
12
|
+
|
|
13
|
+
### Fixed
|
|
14
|
+
|
|
15
|
+
- Matched model results to Pi's `/model` presentation: model ID first, `[provider]` last, with no more than ten visible model rows.
|
|
16
|
+
|
|
5
17
|
## 0.3.0 - 2026-08-26
|
|
6
18
|
|
|
7
19
|
### Added
|
package/README.md
CHANGED
|
@@ -1,130 +1,55 @@
|
|
|
1
1
|
# pi-delegation-policy
|
|
2
2
|
|
|
3
|
-
A local Pi extension that
|
|
3
|
+
A local Pi extension that helps the main agent decide **when delegation is worth it** and which exact models to use for the Small, Medium, Large, and optional UI Design roles. It provides guidance; it is not a subagent runner.
|
|
4
4
|
|
|
5
|
-
> **Status:** Version 0.3.0 is
|
|
5
|
+
> **Status:** Version **0.3.2** is the latest published package. The package accepts Pi `>=0.84.1`; Pi `0.84.1` is the explicitly validated baseline (newer versions are not claimed as tested).
|
|
6
6
|
>
|
|
7
|
-
> **
|
|
7
|
+
> **Docs:** [Read the documentation site](https://yivas.github.io/pi-delegation-policy/).
|
|
8
8
|
|
|
9
|
-
##
|
|
9
|
+
## Value and boundary
|
|
10
10
|
|
|
11
|
-
-
|
|
12
|
-
-
|
|
13
|
-
-
|
|
14
|
-
-
|
|
15
|
-
- Injects one policy block through Pi's public `before_agent_start` event when the active configuration is valid.
|
|
11
|
+
- Choose `off`, `normal`, or `aggressive` delegation intensity globally or for the current session branch.
|
|
12
|
+
- Configure exact provider/model references for Small, Medium, Large, and optionally UI Design.
|
|
13
|
+
- Keep global defaults and session-branch overrides across reload, resume, and tree navigation.
|
|
14
|
+
- Validate active configurations before injecting one policy block through Pi's public `before_agent_start` event.
|
|
16
15
|
|
|
17
|
-
|
|
16
|
+
The extension guides the main agent. It never creates, launches, routes, supervises, or blocks subagents; changes Pi's main model or thinking; stores credentials; intercepts tools; or makes its own network requests. It has no model fallback, telemetry, project configuration, presets, or external skill loading.
|
|
18
17
|
|
|
19
|
-
|
|
18
|
+
## Install and start
|
|
20
19
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
Install the package in your Pi user settings:
|
|
20
|
+
Install the published package in Pi's user settings, then reload Pi:
|
|
24
21
|
|
|
25
22
|
```bash
|
|
26
23
|
pi install npm:pi-delegation-policy
|
|
24
|
+
# restart Pi, or run /reload
|
|
27
25
|
```
|
|
28
26
|
|
|
29
|
-
|
|
27
|
+
1. Open `/delegate` (or press `Alt+G` in Pi's TUI).
|
|
28
|
+
2. Configure exact, authenticated Small, Medium, and Large provider/model references. UI Design is optional.
|
|
29
|
+
3. Select `normal` or `aggressive`, then choose **Apply changes**.
|
|
30
|
+
4. Run `/delegate status` and inspect the footer for `D:NORM` or `D:AGG`. `D:ERR` means an active required role is invalid; no policy is injected.
|
|
31
|
+
5. The applied state affects the **next** agent run. An agent already running is not rewritten.
|
|
32
|
+
|
|
33
|
+
See the [end-to-end getting-started guide](https://yivas.github.io/pi-delegation-policy/getting-started/) and [configuration reference](https://yivas.github.io/pi-delegation-policy/configuration/) for details.
|
|
30
34
|
|
|
31
|
-
##
|
|
35
|
+
## Essential commands
|
|
32
36
|
|
|
33
37
|
```text
|
|
34
|
-
/delegate Open the
|
|
35
|
-
/delegate off Disable policy
|
|
38
|
+
/delegate Open the editor
|
|
39
|
+
/delegate off Disable policy for this session branch
|
|
36
40
|
/delegate normal Enable balanced delegation guidance
|
|
37
41
|
/delegate aggressive Enable delegation-first guidance
|
|
38
|
-
/delegate status Show
|
|
39
|
-
/delegate reset Reset this
|
|
42
|
+
/delegate status Show effective session state
|
|
43
|
+
/delegate reset Reset this branch to off and other fields to global defaults
|
|
40
44
|
```
|
|
41
45
|
|
|
42
|
-
`
|
|
43
|
-
|
|
44
|
-
The interactive editor requires Pi's TUI mode; quick `/delegate` arguments remain available in other modes. The editor is one bounded, keyboard-first panel. It shows the effective value and the built-in, global, and session value for each setting. Model fields open a live fuzzy search over provider, model ID, and display name; long catalogs scroll within the terminal instead of extending past the screen. **Use global default** remains available while searching, and UI Design also offers **Disable for this session**.
|
|
45
|
-
|
|
46
|
-
Edits stay in a draft until **Apply changes** is selected or `A` is pressed. **Save effective configuration as defaults** updates the global file without applying the session draft. **Reset draft to off** remains local until Apply. Escape returns from a field editor; closing a modified draft requires explicit discard confirmation.
|
|
47
|
-
|
|
48
|
-
The footer shows `D:OFF`, `D:NORM`, `D:AGG`, or `D:ERR` without replacing Pi's own status.
|
|
49
|
-
|
|
50
|
-
## Configuration
|
|
51
|
-
|
|
52
|
-
Global defaults live at:
|
|
53
|
-
|
|
54
|
-
```text
|
|
55
|
-
~/.pi/agent/delegation-policy.json
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
They use schema version 2. The file stores optional intensity, model references, preference, and an optional UI Design model. It never stores thinking.
|
|
59
|
-
|
|
60
|
-
```json
|
|
61
|
-
{
|
|
62
|
-
"schemaVersion": 2,
|
|
63
|
-
"intensity": "normal",
|
|
64
|
-
"preference": "standard",
|
|
65
|
-
"small": {
|
|
66
|
-
"provider": "example-provider",
|
|
67
|
-
"model": "example-small"
|
|
68
|
-
},
|
|
69
|
-
"medium": {
|
|
70
|
-
"provider": "example-provider",
|
|
71
|
-
"model": "example-medium"
|
|
72
|
-
},
|
|
73
|
-
"large": {
|
|
74
|
-
"provider": "example-provider",
|
|
75
|
-
"model": "example-large"
|
|
76
|
-
},
|
|
77
|
-
"uiDesign": {
|
|
78
|
-
"provider": "example-provider",
|
|
79
|
-
"model": "example-ui-design"
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
```
|
|
83
|
-
|
|
84
|
-
See [`examples/global.json`](examples/global.json) and the bundled [JSON Schema](schema/delegation-policy.schema.json). The values are fictional.
|
|
85
|
-
|
|
86
|
-
Schema version 1 is inactive and is not migrated automatically. Open `/delegate`, configure schema version 2, and save the effective configuration as defaults before using an active intensity.
|
|
87
|
-
|
|
88
|
-
### Global defaults and session branches
|
|
46
|
+
The editor is a bounded, keyboard-first panel. It shows model ID first and `[provider]` last, fuzzy-searches provider, model ID, and display name, and shows at most 10 model rows. Inheritance actions stay pinned while searching. Changes are drafts until **Apply changes**; saving effective configuration as defaults updates the global file without applying the draft, and closing a modified draft requires explicit discard.
|
|
89
47
|
|
|
90
|
-
|
|
48
|
+
## Configuration and safety
|
|
91
49
|
|
|
92
|
-
|
|
50
|
+
Global defaults are stored at `~/.pi/agent/delegation-policy.json` (schema version 2). The file stores optional intensity, preference, exact role references, and an optional UI Design reference; it never stores thinking. A valid active mode requires exact, available, in-scope, authenticated Small, Medium, and Large references. Invalid active configuration fails closed as `D:ERR` with no policy injection; `off` is always `D:OFF`.
|
|
93
51
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
- `off` injects nothing into the next agent run. Pi rebuilds the system prompt for each run, so a policy injected into an earlier run is absent; an agent already running is not rewritten. Invalid or incomplete defaults still show `D:OFF`.
|
|
97
|
-
- `normal` delegates substantial, separable work only when the expected benefit clearly outweighs briefing, supervision, review, and integration. It keeps borderline work with the main agent.
|
|
98
|
-
- `aggressive` delegates substantial, separable, independently checkable work by default when it has a clear objective and acceptance criteria. A plausible benefit can be enough, but tightly coupled work or clearly prohibitive overhead stays with the main agent.
|
|
99
|
-
|
|
100
|
-
The main agent keeps global strategy, coordination, integration, final review, and work whose essential context is too costly or risky to transfer in every mode.
|
|
101
|
-
|
|
102
|
-
### Model roles and preference
|
|
103
|
-
|
|
104
|
-
Active modes require exact `provider` and `model` references for Small, Medium, and Large. Pi must expose each reference in the current scope or available model catalog, and its provider must be authenticated. A missing, out-of-scope, unavailable, or unauthenticated role produces `D:ERR` and injects no policy. The extension never substitutes another model or role.
|
|
105
|
-
|
|
106
|
-
The policy chooses a role and thinking together from task demand, difficulty, and quantity. No single factor decides the role:
|
|
107
|
-
|
|
108
|
-
- Small is habitual for bounded, planned, and verifiable execution. Difficult but well-defined work can remain Small with higher thinking.
|
|
109
|
-
- Medium can be selected directly when the combined demands materially require planning, ambiguity reduction, broad synthesis, several-module tracing, comparison, context coordination, or difficult decisions. Small does not need to fail first.
|
|
110
|
-
- Large is exceptional and only unblocks genuinely stuck work, such as persistent failures, severe framework conflicts, or contradictory hypotheses. Reliable prior evidence can justify it without ceremonial failed attempts.
|
|
111
|
-
- Large quantities of repetitive, independent work favor multiple Small delegations. Agent type does not determine the model role.
|
|
112
|
-
|
|
113
|
-
Preference shifts credible Small/Medium choices; a clearly better task fit overrides it:
|
|
114
|
-
|
|
115
|
-
- `efficient` favors Small more strongly and uses Medium when it provides a material advantage.
|
|
116
|
-
- `standard` reproduces the canonical policy and chooses Small on a genuine Small/Medium tie.
|
|
117
|
-
- `intensive` normally favors Medium for non-trivial bounded work when both roles are credible, while retaining Small for clearly narrow, routine, mechanical, or especially clear Small work.
|
|
118
|
-
|
|
119
|
-
All three ordinary roles remain available in every preference. The main agent chooses thinking for each delegated task from task demand, difficulty, quantity, and model capabilities. Thinking is not configured or persisted by this extension.
|
|
120
|
-
|
|
121
|
-
UI Design is optional. When configured, it is limited to visual design direction, exploration, and review. It must not implement an interface, write code, or run tests. When it is off, ordinary roles handle design-related work.
|
|
122
|
-
|
|
123
|
-
## Security and privacy
|
|
124
|
-
|
|
125
|
-
The extension stores intensity, preference, and provider/model identifiers in local configuration and session entries. It does not store credentials, send telemetry, or make network requests. Review configuration before using it and remove credentials, prompts, personal paths, session files, and unredacted logs from reports.
|
|
126
|
-
|
|
127
|
-
Read [`SECURITY.md`](SECURITY.md) for reporting guidance.
|
|
52
|
+
The extension stores only policy settings and provider/model identifiers in local defaults and session entries. Review local configuration before sharing diagnostics, and remove credentials, prompts, personal paths, session files, and unredacted logs from reports. See the [limits and privacy reference](https://yivas.github.io/pi-delegation-policy/limits-and-privacy/) and [security policy](https://github.com/Yivas/pi-delegation-policy/blob/main/SECURITY.md).
|
|
128
53
|
|
|
129
54
|
## Development
|
|
130
55
|
|
|
@@ -138,12 +63,8 @@ npm run build
|
|
|
138
63
|
npm run pack:check
|
|
139
64
|
```
|
|
140
65
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
## Contributing
|
|
144
|
-
|
|
145
|
-
Read [`CONTRIBUTING.md`](CONTRIBUTING.md). Contributions must preserve the boundary: this extension guides the main agent and does not become a subagent runner, tool interceptor, credential store, or telemetry client.
|
|
66
|
+
Tests use local mocks and do not make paid model calls or network requests. See [CONTRIBUTING.md](https://github.com/Yivas/pi-delegation-policy/blob/main/CONTRIBUTING.md) for contribution guidance.
|
|
146
67
|
|
|
147
68
|
## License
|
|
148
69
|
|
|
149
|
-
MIT. See [
|
|
70
|
+
MIT. See [LICENSE](https://github.com/Yivas/pi-delegation-policy/blob/main/LICENSE).
|
package/SECURITY.md
CHANGED
|
@@ -14,4 +14,4 @@ Include the affected version or commit, operating system, Pi version, reproducti
|
|
|
14
14
|
|
|
15
15
|
## Supported versions
|
|
16
16
|
|
|
17
|
-
Only the latest published version is supported. Version 0.3.
|
|
17
|
+
Only the latest published version is supported. Version 0.3.2 is the current supported release.
|
package/package.json
CHANGED
package/src/delegate-panel.ts
CHANGED
|
@@ -470,22 +470,29 @@ export class DelegatePanel implements Component, Focusable {
|
|
|
470
470
|
),
|
|
471
471
|
);
|
|
472
472
|
const dividerRows = budget > pinnedLines.length + 3 ? 1 : 0;
|
|
473
|
-
const
|
|
474
|
-
const
|
|
473
|
+
const selectedChoice = choices[mode.selected];
|
|
474
|
+
const selectedName =
|
|
475
|
+
selectedChoice?.kind === "model" && selectedChoice.description
|
|
476
|
+
? [` Model Name: ${selectedChoice.description}`]
|
|
477
|
+
: [];
|
|
478
|
+
const detailRows = selectedName.length > 0 && budget > pinnedLines.length + 6 ? 2 : 0;
|
|
479
|
+
const availableListRows = Math.max(
|
|
480
|
+
0,
|
|
481
|
+
budget - 2 - pinnedLines.length - dividerRows - detailRows,
|
|
482
|
+
);
|
|
483
|
+
const listBudget = Math.min(11, availableListRows);
|
|
475
484
|
const modelBlocks = models.map((choice, index) => {
|
|
476
485
|
const combinedIndex = index + pinnedCount;
|
|
477
|
-
const
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
}
|
|
483
|
-
return lines;
|
|
486
|
+
const provider = choice.kind === "model" ? choice.reference.provider : "";
|
|
487
|
+
const label = provider
|
|
488
|
+
? `${choice.label} ${this.theme.fg("muted", `[${provider}]`)}`
|
|
489
|
+
: choice.label;
|
|
490
|
+
return [selectedLine(this.theme, label, width, mode.selected === combinedIndex)];
|
|
484
491
|
});
|
|
485
492
|
const modelSelected = Math.max(0, mode.selected - pinnedCount);
|
|
486
493
|
const modelLines =
|
|
487
494
|
listBudget > 0 && modelBlocks.length > 0
|
|
488
|
-
? this.renderBlockViewport(modelBlocks, modelSelected, width, listBudget)
|
|
495
|
+
? this.renderBlockViewport(modelBlocks, modelSelected, width, listBudget, 10)
|
|
489
496
|
: [];
|
|
490
497
|
if (models.length === 0 && modelLines.length < listBudget) {
|
|
491
498
|
modelLines.push(
|
|
@@ -505,6 +512,7 @@ export class DelegatePanel implements Component, Focusable {
|
|
|
505
512
|
...pinnedLines,
|
|
506
513
|
...(dividerRows ? [this.theme.fg("borderMuted", "─".repeat(width))] : []),
|
|
507
514
|
...modelLines,
|
|
515
|
+
...(detailRows ? ["", ...selectedName.map((line) => this.theme.fg("muted", line))] : []),
|
|
508
516
|
].slice(0, budget);
|
|
509
517
|
}
|
|
510
518
|
|
|
@@ -523,10 +531,11 @@ export class DelegatePanel implements Component, Focusable {
|
|
|
523
531
|
selected: number,
|
|
524
532
|
width: number,
|
|
525
533
|
budget: number,
|
|
534
|
+
maxVisibleBlocks = Number.POSITIVE_INFINITY,
|
|
526
535
|
): string[] {
|
|
527
536
|
const totalRows = blocks.reduce((sum, block) => sum + block.length, 0);
|
|
528
|
-
const reserveIndicator = totalRows > budget ? 1 : 0;
|
|
529
|
-
const contentBudget = Math.max(1, budget - reserveIndicator);
|
|
537
|
+
const reserveIndicator = totalRows > budget || blocks.length > maxVisibleBlocks ? 1 : 0;
|
|
538
|
+
const contentBudget = Math.max(1, Math.min(budget - reserveIndicator, maxVisibleBlocks));
|
|
530
539
|
const [start, end] = visibleBlockRange(blocks, selected, contentBudget);
|
|
531
540
|
const lines = blocks
|
|
532
541
|
.slice(start, end)
|
|
@@ -672,7 +681,7 @@ export class DelegatePanel implements Component, Focusable {
|
|
|
672
681
|
}
|
|
673
682
|
const filtered = query
|
|
674
683
|
? fuzzyFilter(this.candidates, query, (model) =>
|
|
675
|
-
`${model.provider}/${model.id} ${model.name ?? ""}`.trim(),
|
|
684
|
+
`${model.provider} ${model.provider}/${model.id} ${model.provider} ${model.id} ${model.name ?? ""}`.trim(),
|
|
676
685
|
)
|
|
677
686
|
: this.candidates;
|
|
678
687
|
return [
|
|
@@ -680,7 +689,7 @@ export class DelegatePanel implements Component, Focusable {
|
|
|
680
689
|
...filtered.map<ModelChoice>((model) => ({
|
|
681
690
|
kind: "model",
|
|
682
691
|
key: modelKey({ provider: model.provider, model: model.id }),
|
|
683
|
-
label:
|
|
692
|
+
label: model.id,
|
|
684
693
|
...(model.name && model.name !== model.id ? { description: model.name } : {}),
|
|
685
694
|
reference: { provider: model.provider, model: model.id },
|
|
686
695
|
})),
|