pi-advisor-flow 0.2.4 → 0.2.7
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 +232 -0
- package/README.md +37 -9
- package/package.json +48 -29
- package/src/commands.ts +34 -4
- package/src/config.ts +112 -22
- package/src/conversation.ts +34 -1
- package/src/git.ts +190 -0
- package/src/herdr.ts +9 -9
- package/src/outcomes.ts +85 -0
- package/src/preferences.ts +50 -0
- package/src/session-state.ts +36 -1
- package/src/tools.ts +307 -33
- package/src/ui.ts +104 -24
- package/src/untracked.ts +121 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project are documented here.
|
|
4
|
+
|
|
5
|
+
The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
|
+
|
|
7
|
+
## 0.2.7
|
|
8
|
+
|
|
9
|
+
### Security
|
|
10
|
+
|
|
11
|
+
- Escaped every untrusted Advisor prompt region and hardened automatic decision parsing against malformed fenced blocks ([#2](https://github.com/philipbrembeck/pi-advisor/issues/2)).
|
|
12
|
+
- Kept Advisor prompts, models, gates, budgets, disclosure, redaction, integrations, and consent global by no longer applying repository-controlled project `advisor.json` files ([#3](https://github.com/philipbrembeck/pi-advisor/issues/3)).
|
|
13
|
+
- Redacted unterminated oversized PEM blocks before bounded preference or untracked-file content can leave the process ([#4](https://github.com/philipbrembeck/pi-advisor/issues/4)).
|
|
14
|
+
- Bounded and redacted Herdr blocked-state metadata while reliably clearing previously reported labels ([#5](https://github.com/philipbrembeck/pi-advisor/issues/5)).
|
|
15
|
+
- Bounded untracked-file Git probes and switched to NUL-delimited path handling for non-ASCII filenames ([#6](https://github.com/philipbrembeck/pi-advisor/issues/6)).
|
|
16
|
+
|
|
17
|
+
### Changed
|
|
18
|
+
|
|
19
|
+
- Advisor settings now load and save globally. Move any intended values from project `.pi/advisor.json` files into the Pi agent directory's global `advisor.json`.
|
|
20
|
+
- Pi's bundled modules (`@earendil-works/pi-ai`, `@earendil-works/pi-coding-agent`, `@earendil-works/pi-tui`, and `typebox`) are declared as optional peer dependencies. Installing the extension no longer installs a copy of them; Pi supplies them at runtime. Version ranges continue to document the supported Pi API.
|
|
21
|
+
- Published packages now include `CHANGELOG.md`.
|
|
22
|
+
- Release workflows pin GitHub Actions to commit SHAs, kept current by Dependabot.
|
|
23
|
+
|
|
24
|
+
## 0.2.6
|
|
25
|
+
|
|
26
|
+
### Added
|
|
27
|
+
|
|
28
|
+
- Draft-aware `ask_advisor` reviews with opaque advice IDs, explicit outcome reporting, trusted-project preferences, and opt-in explicit untracked-file context.
|
|
29
|
+
- Global-only, privacy-minimal outcome JSONL logging with salted advice digests and no raw advice, prompts, paths, repository data, or session identifiers.
|
|
30
|
+
- `.pi/advisor-preferences.md` support for trusted projects; preferences remain untrusted, redacted, capped, and never auto-written.
|
|
31
|
+
|
|
32
|
+
## 0.2.5
|
|
33
|
+
|
|
34
|
+
This version was never published to npm; its changes shipped in 0.2.6.
|
|
35
|
+
|
|
36
|
+
### Added
|
|
37
|
+
|
|
38
|
+
- Repository change context for consultations, controlled by `advisorGitContext` (`off`, `summary`, `full`, default `summary`) and capped by `advisorGitContextMaxChars`. `summary` discloses changed file names, change status, and line counts; `full` adds the patch. Untracked files are always reported by name only.
|
|
39
|
+
- An optional `gitContext` argument on `ask_advisor` so the Executor can request less, or request more up to the configured allowance. A request above the allowance is narrowed to it and the Advisor is told that a fuller view was withheld.
|
|
40
|
+
- Repository context is escaped and capped as a single labelled untrusted region, so a crafted path cannot end the region early and have following text read as instructions.
|
|
41
|
+
|
|
42
|
+
### Fixed
|
|
43
|
+
|
|
44
|
+
- Restored keyboard selection for the Context window slider in advanced `/advisor-settings` mode, matching its position at the top of the screen.
|
|
45
|
+
|
|
46
|
+
## 0.2.4
|
|
47
|
+
|
|
48
|
+
### Added
|
|
49
|
+
|
|
50
|
+
- Simple mode for voluntary `ask_advisor` and `/advisor-manual` consultations without automatic gates, blocks, budgets, or session summaries; privacy and context controls remain active.
|
|
51
|
+
- Persistent `alwaysOn` Advisor-flow activation, including Executor restoration and, while the flow is active, adoption of an explicit `/model` selection as the Executor. `/advisor-off` also turns persistent activation off.
|
|
52
|
+
- Simple-mode settings for voluntary Advisor use and persistent activation.
|
|
53
|
+
- Static `◆ ADVISOR · SOUND` rendering for ordinary Advisor replies beginning with `Verdict: sound`, for both `ask_advisor` results and `/advisor-manual` responses.
|
|
54
|
+
|
|
55
|
+
### Changed
|
|
56
|
+
|
|
57
|
+
- Session Advisor Summary now defaults to off.
|
|
58
|
+
|
|
59
|
+
### Fixed
|
|
60
|
+
|
|
61
|
+
- `/advisor contextMaxChars=N` now persists, so the supplied limit applies to later consultations instead of reverting at the next tool call.
|
|
62
|
+
- A zero context limit with no targeted focus no longer sends an empty Advisor request that some providers reject.
|
|
63
|
+
- An Advisor gate response that quotes a decision line inside a fenced example is no longer rejected as a duplicate or contradictory decision.
|
|
64
|
+
- Reconstructed Advisor context is assembled without re-joining the accumulated branch on every entry, which removes a slowdown on long sessions with large context limits.
|
|
65
|
+
|
|
66
|
+
## 0.2.3
|
|
67
|
+
|
|
68
|
+
### Added
|
|
69
|
+
|
|
70
|
+
- Optional local secret redaction for reconstructed Advisor context, including user messages, assistant text and tool arguments, compaction summaries, and full tool results.
|
|
71
|
+
- Exact-name Advisor tool disclosure policies: `full` includes call arguments and capped output; `summary` retains only result status and size metadata; `exclude` omits call details and output. Tools without a policy remain `full` for compatibility.
|
|
72
|
+
- `/advisor-settings` controls for secret redaction and inline JSON editing of tool disclosure policies, with validation errors that keep invalid input open for correction.
|
|
73
|
+
- Configuration validation, loading, and persistence for `advisorRedactSecrets` and `advisorToolPolicies`.
|
|
74
|
+
|
|
75
|
+
### Changed
|
|
76
|
+
|
|
77
|
+
- Redact eligible tool output before applying line and byte limits so truncated context cannot retain the beginning or end of a matched secret.
|
|
78
|
+
- Reorganize the README around installation, first use, commands, automatic gate behavior, configuration, privacy boundaries, development, and releases.
|
|
79
|
+
|
|
80
|
+
## 0.2.2
|
|
81
|
+
|
|
82
|
+
### Fixed
|
|
83
|
+
|
|
84
|
+
- Reopening `/advisor-settings` now displays values saved earlier in the same Pi session without requiring `/reload`.
|
|
85
|
+
|
|
86
|
+
## 0.2.1
|
|
87
|
+
|
|
88
|
+
### Added
|
|
89
|
+
|
|
90
|
+
- Ultracite lint commands and a Husky pre-commit hook that formats and lints staged TypeScript and JSON files.
|
|
91
|
+
|
|
92
|
+
### Changed
|
|
93
|
+
|
|
94
|
+
- Resolved the existing Ultracite lint violations through structural refactors and stronger type boundaries without changing Advisor-flow behavior.
|
|
95
|
+
|
|
96
|
+
### Fixed
|
|
97
|
+
|
|
98
|
+
- Empty persisted Executor, Advisor, and reasoning-effort settings now retain their configured defaults.
|
|
99
|
+
- Keep a session blocked after a critical automatic-gate decision or session-blocking gate failure.
|
|
100
|
+
- Preserve custom Advisor context and reasoning settings when saving unrelated changes.
|
|
101
|
+
- Persist an unlimited Advisor-call budget correctly after removing a prior finite limit.
|
|
102
|
+
- Enforce configured Advisor tool-result byte and line limits, including for long Unicode lines.
|
|
103
|
+
- Render automatic and manual Advisor failures in the transcript.
|
|
104
|
+
- Avoid false loop detection for semantic field names such as `update`.
|
|
105
|
+
- Make release automation skip unchanged versions while explicitly dispatching publication after an Action-created tag.
|
|
106
|
+
|
|
107
|
+
## 0.2.0
|
|
108
|
+
|
|
109
|
+
### Added
|
|
110
|
+
|
|
111
|
+
- Separate Markdown consultations from strict automatic loop-gate decisions.
|
|
112
|
+
- Typed gate parsing for `proceed`, `revise`, and `blocked`, including safe failure classification.
|
|
113
|
+
|
|
114
|
+
### Changed
|
|
115
|
+
|
|
116
|
+
- Normal Advisor and Executor-requested consultations preserve raw Markdown and no longer fabricate or enforce a structured verdict.
|
|
117
|
+
- Automatic gate decisions render separately from their Markdown explanation.
|
|
118
|
+
- Advisor calls now use one shared per-session budget with explicit used/remaining accounting.
|
|
119
|
+
- Gate failures support `block-session`, `block-tool`, and `warn-and-continue`; Herdr failures also show sanitized `notification.show` toasts when integration is enabled.
|
|
120
|
+
- Advisor settings validate values at startup, preserve unknown fields on save, and expose Herdr integration plus tool-result limits.
|
|
121
|
+
- Advisor context keeps complete semantic entries and caps oversized tool results using Pi-compatible defaults while preserving head/tail sections.
|
|
122
|
+
- Tool-result limits are configurable by line and byte count, with explicit omission markers that never split semantic entries.
|
|
123
|
+
- Loop detection now uses explainable normalized tool signatures with allowlisted volatile-field and shell-whitespace normalization.
|
|
124
|
+
- Local ephemeral summaries distinguish Markdown advice from automatic gate decisions and include triggers, models, usage/cost when available, budget, failures, and execution effects.
|
|
125
|
+
|
|
126
|
+
## [0.1.9]
|
|
127
|
+
|
|
128
|
+
### Fixed
|
|
129
|
+
|
|
130
|
+
- Keep manual and automatic Advisor responses human-readable. Manual consultations return direct Markdown; automatic loop reviews use a concise Markdown `Decision:` line for machine-readable gating without exposing a JSON protocol.
|
|
131
|
+
|
|
132
|
+
## [0.1.8]
|
|
133
|
+
|
|
134
|
+
### Added
|
|
135
|
+
|
|
136
|
+
- Structured Advisor verdicts: `proceed`, `revise`, `insufficient-evidence`, and critical `blocked` responses, with findings, required verification, and a smallest next step.
|
|
137
|
+
- Critical-block handling: optionally abort the active run, mark the session blocked, and report the blocked state to Herdr.
|
|
138
|
+
- Automatic loop gate that consults the Advisor after three equivalent tool calls. A `proceed` verdict resumes execution; `revise` and `insufficient-evidence` block only the repeated action; critical verdicts, failed reviews, and exhausted budgets block the session and report Herdr state.
|
|
139
|
+
- Per-session Advisor-call limit, with an Executor prompt hint only when a finite limit is configured.
|
|
140
|
+
- Local, in-memory-only `[Session Advisor Summary]` after a non-blocked settled run; no summary data is persisted or sent to Herdr.
|
|
141
|
+
- `/advisor-settings` controls for critical blocking, enabling/disabling the automatic loop gate, loop threshold, max Advisor calls per session, and the Session Advisor Summary.
|
|
142
|
+
- Session-state tests covering loop detection, Advisor-call budgets, and summary generation.
|
|
143
|
+
- Research note covering evidence-backed Advisor-flow improvements.
|
|
144
|
+
|
|
145
|
+
### Changed
|
|
146
|
+
|
|
147
|
+
- Advisor responses now require validated JSON and safely fall back to `insufficient-evidence` when the response is malformed.
|
|
148
|
+
- Manual, Executor-requested, and automatic Advisor consultations share the configured session call limit.
|
|
149
|
+
- Herdr activity and blocked state use separate extension metadata sources so clearing one does not clear the other.
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
## [0.1.7]
|
|
153
|
+
|
|
154
|
+
### Added
|
|
155
|
+
|
|
156
|
+
- Herdr integration: Advisor consultations display as `seeking advice` while active when Pi runs in a Herdr-managed pane.
|
|
157
|
+
|
|
158
|
+
## [0.1.6]
|
|
159
|
+
|
|
160
|
+
### Added
|
|
161
|
+
|
|
162
|
+
- `/advisor-manual [focus]` to start an Advisor consultation in parallel without interrupting the Executor's active tool work; the completed advice is delivered before the Executor's next model call.
|
|
163
|
+
- Immediate transcript entries and rendered Advisor responses for manual consultations.
|
|
164
|
+
|
|
165
|
+
### Changed
|
|
166
|
+
|
|
167
|
+
- Reuse the Advisor call UI for manual consultations and cancel an earlier manual request when a newer one starts or the session shuts down.
|
|
168
|
+
|
|
169
|
+
## [0.1.5]
|
|
170
|
+
|
|
171
|
+
### Added
|
|
172
|
+
|
|
173
|
+
- `/advisor-settings`: one keyboard-navigable screen for Advisor context size, reasoning effort, invocation gates, response collapsing, and a custom invocation rule.
|
|
174
|
+
- Claude Code-style Advisor context selector with `0`, `10k`, `25k`, `100k`, `200k`, and `ALL` presets.
|
|
175
|
+
- Individually configurable plan, repeated-failure, and completion-review Advisor gates.
|
|
176
|
+
- Optional collapsed Advisor responses that expand with `Ctrl+O`.
|
|
177
|
+
- Inline custom invocation-rule editing in Advisor settings.
|
|
178
|
+
|
|
179
|
+
### Changed
|
|
180
|
+
|
|
181
|
+
- General `ask_advisor({})` consultations now send conversation context without an invented request or question; targeted questions remain optional.
|
|
182
|
+
- Advisor instructions explicitly tell the Executor not to invent a question for a normal review and tell the Advisor to make a best-effort contextual review without requesting more input.
|
|
183
|
+
- Preserve unknown fields when saving `advisor.json`.
|
|
184
|
+
- Support `0` as a no-history context setting and `Number.MAX_SAFE_INTEGER` as the ALL-context sentinel.
|
|
185
|
+
|
|
186
|
+
### Fixed
|
|
187
|
+
|
|
188
|
+
- Ignore persisted Advisor configuration files with invalid field types instead of crashing during model resolution.
|
|
189
|
+
- Restore interactive Advisor settings arrow-key navigation using Pi TUI key matching.
|
|
190
|
+
|
|
191
|
+
## [0.1.4]
|
|
192
|
+
|
|
193
|
+
### Added
|
|
194
|
+
|
|
195
|
+
- Configurable reconstructed-conversation limit via `contextMaxChars` in `advisor.json` or `/advisor contextMaxChars=N` (default: 15,000; maximum: 1,000,000).
|
|
196
|
+
|
|
197
|
+
### Changed
|
|
198
|
+
|
|
199
|
+
- Clarified that the Executor may call `ask_advisor({})` without a question for a general review.
|
|
200
|
+
- Removed the extra no-question “General task review” text from the Advisor call UI.
|
|
201
|
+
- Reframed Advisor guidance as a brief second opinion that stress-tests the Executor's own candidate direction rather than taking over planning.
|
|
202
|
+
|
|
203
|
+
## [0.1.3]
|
|
204
|
+
|
|
205
|
+
### Documentation
|
|
206
|
+
|
|
207
|
+
- Changed publication flow, no code changes
|
|
208
|
+
|
|
209
|
+
## [0.1.2]
|
|
210
|
+
|
|
211
|
+
### Added
|
|
212
|
+
|
|
213
|
+
- General contextual Advisor reviews: the Executor can call `ask_advisor({})` without a specific question.
|
|
214
|
+
- A skill-style Advisor invocation row that distinguishes an Executor request from an Advisor response.
|
|
215
|
+
- Markdown rendering support for the Advisor response, including code blocks and inline code.
|
|
216
|
+
|
|
217
|
+
### Changed
|
|
218
|
+
|
|
219
|
+
- Advisor responses display the advising model and advice separately from the tool-result payload.
|
|
220
|
+
- The Advisor spinner is shown only while a response is streaming and is cleared when the response completes.
|
|
221
|
+
|
|
222
|
+
## [0.1.1]
|
|
223
|
+
|
|
224
|
+
### Documentation
|
|
225
|
+
|
|
226
|
+
- Fixed documentation link
|
|
227
|
+
|
|
228
|
+
## [0.1.0]
|
|
229
|
+
|
|
230
|
+
### Added
|
|
231
|
+
|
|
232
|
+
- Initial npm and git package release.
|
package/README.md
CHANGED
|
@@ -1,22 +1,23 @@
|
|
|
1
1
|
# pi-advisor
|
|
2
2
|
|
|
3
3
|
<div align="center">
|
|
4
|
-
<img src="https://raw.githubusercontent.com/philipbrembeck/pi-advisor/refs/heads/main/assets/screenshot.png" alt="Pi Advisor consultation in the terminal" width="760">
|
|
5
4
|
|
|
6
|
-
|
|
5
|
+

|
|
7
6
|
|
|
8
|
-
</
|
|
7
|
+
A configurable second-opinion workflow for <a href="https://github.com/earendil-works/pi">Pi</a> coding agents, inspired by the ["Steering Black-Box LLMs with Advisor Models" paper](https://arxiv.org/abs/2510.02453) and Claude's [Advisor](https://code.claude.com/docs/en/advisor) feature.
|
|
9
8
|
|
|
10
|
-
|
|
9
|
+
</div>
|
|
11
10
|
|
|
12
|
-
This extension introduces a strategic "Executor/Advisor" workflow
|
|
11
|
+
This extension introduces a strategic "Executor/Advisor" workflow.
|
|
13
12
|
|
|
14
13
|
`pi-advisor-flow` keeps one model focused on execution and makes a second, smarter model available for consequential decisions, stalled work, and final reviews. The Executor still owns the work. The Advisor provides a concise review, answers questions and can provide help; it does not take over planning or run tools.
|
|
15
14
|
|
|
16
|
-
[Read more about Advisors here](https://philipbrembeck.com/writings/2026/07/only-as-much-intelligence-as-you-need).
|
|
15
|
+
The concept is simple, keep implementation on a fast model, borrow frontier reasoning only when decisions actually matter. [Read more about Advisors here](https://philipbrembeck.com/writings/2026/07/only-as-much-intelligence-as-you-need).
|
|
17
16
|
|
|
18
17
|
## Install
|
|
19
18
|
|
|
19
|
+
Requires Pi 0.80.7 or later. The extension installs no dependencies of its own; Pi supplies the modules it uses at runtime.
|
|
20
|
+
|
|
20
21
|
Install into your Pi agent environment:
|
|
21
22
|
|
|
22
23
|
```bash
|
|
@@ -58,7 +59,9 @@ Enable with models in one command when preferred:
|
|
|
58
59
|
|
|
59
60
|
### `ask_advisor`
|
|
60
61
|
|
|
61
|
-
The Executor calls `ask_advisor({})` for a general review of the current task and reconstructed conversation. It can pass a `question` for a targeted review.
|
|
62
|
+
The Executor calls `ask_advisor({})` for a general review of the current task and reconstructed conversation. It can pass a `question` for a targeted review, or a concise `draft` for plan and completion reviews. A draft should name proposed work, validation, and remaining risks; it is an unverified claim, not evidence.
|
|
63
|
+
|
|
64
|
+
Successful calls return an opaque `adviceId`. When global outcome logging is enabled, the Executor may voluntarily call `record_advisor_outcome` once with that ID, an adoption value, and a final validation status.
|
|
62
65
|
|
|
63
66
|
Use the Advisor after the Executor has investigated and formed a candidate direction. It is intended to challenge assumptions, expose risks, and confirm the next verification step—not to replace the Executor's work.
|
|
64
67
|
|
|
@@ -101,7 +104,7 @@ Malformed, missing, duplicate, or contradictory decisions are gate failures. The
|
|
|
101
104
|
|
|
102
105
|
## Settings and configuration
|
|
103
106
|
|
|
104
|
-
`/advisor-models` and `/advisor-settings` save to `advisor.json` in the Pi agent directory.
|
|
107
|
+
`/advisor-models` and `/advisor-settings` save to global `advisor.json` in the Pi agent directory. Repository-controlled project `advisor.json` files are not applied; models, prompts, gates, budgets, disclosure, redaction, integrations, and consent remain under the user's global configuration.
|
|
105
108
|
|
|
106
109
|
All fields are optional. This example shows the available settings and their normal defaults:
|
|
107
110
|
|
|
@@ -126,6 +129,8 @@ All fields are optional. This example shows the available settings and their nor
|
|
|
126
129
|
"gateFailureMode": "block-session",
|
|
127
130
|
|
|
128
131
|
"advisorSessionSummary": false,
|
|
132
|
+
"advisorGitContext": "summary",
|
|
133
|
+
"advisorGitContextMaxChars": 20000,
|
|
129
134
|
"simpleMode": false,
|
|
130
135
|
"alwaysOn": false,
|
|
131
136
|
"advisorHerdrIntegration": true,
|
|
@@ -133,6 +138,8 @@ All fields are optional. This example shows the available settings and their nor
|
|
|
133
138
|
"advisorToolResultMaxBytes": 51200,
|
|
134
139
|
|
|
135
140
|
"advisorRedactSecrets": false,
|
|
141
|
+
"advisorUntrackedContent": false,
|
|
142
|
+
"advisorOutcomeLogging": false,
|
|
136
143
|
"advisorToolPolicies": {
|
|
137
144
|
"bash": "summary",
|
|
138
145
|
"deploy": "exclude"
|
|
@@ -146,6 +153,27 @@ All fields are optional. This example shows the available settings and their nor
|
|
|
146
153
|
- `alwaysOn` defaults to `false`. When enabled, Pi restores the configured Executor and activates `ask_advisor` for new, resumed, forked, and reloaded sessions. While the Advisor flow is active, an explicit `/model` selection becomes the persisted Executor for the next activation; a model restored with a session does not change the saved Executor. `/advisor-off` turns `alwaysOn` off so the flow stays disabled in later sessions.
|
|
147
154
|
- In Simple mode, settings keeps the Context window/history slider alongside Simple mode and Always on; advanced values remain saved and take effect when Simple mode is disabled.
|
|
148
155
|
|
|
156
|
+
### Repository context
|
|
157
|
+
|
|
158
|
+
- `advisorGitContext` defaults to `summary`. It controls how much of the working tree reaches the Advisor:
|
|
159
|
+
- `off` sends no repository information.
|
|
160
|
+
- `summary` sends changed file names, change status, and line counts. It never sends file contents.
|
|
161
|
+
- `full` additionally sends the patch.
|
|
162
|
+
- Changes are measured against the last commit and cover staged and unstaged work. Untracked files are always listed by name only; their contents are never sent by `gitContext: full`.
|
|
163
|
+
- `advisorUntrackedContent` defaults to false. When enabled, `includeUntracked` can attach only exact named, repository-relative, untracked regular files. Files are redacted and capped before egress; sibling files remain withheld.
|
|
164
|
+
- `advisorGitContextMaxChars` defaults to `20000`. Repository context may claim its own cap or half of `contextMaxChars`, whichever is smaller, so it cannot crowd out the conversation.
|
|
165
|
+
- The Executor may pass `gitContext` to `ask_advisor` as `none`, `summary`, or `full`. `advisorGitContext` is the ceiling: a larger request is narrowed to the configured level and the Advisor is told that a fuller view was withheld, so it does not claim verification it could not perform.
|
|
166
|
+
- `summary` deliberately excludes diff hunk headers. Git derives those from surrounding file content, so a hunk header can reproduce a line the change never touched, including a credential.
|
|
167
|
+
- Redaction runs before the region is capped, and repository content is labelled as untrusted data in the request. Paths and patch text are escaped so a crafted path cannot close the region early and have the remainder read as instructions.
|
|
168
|
+
- File names themselves can be sensitive. `summary` withholds file contents, not file names; use `off` when names must not leave the machine.
|
|
169
|
+
- Collection shares a single overall time budget across its git commands and degrades to a stated failure rather than implying a clean tree.
|
|
170
|
+
|
|
171
|
+
### Project preferences and outcomes
|
|
172
|
+
|
|
173
|
+
In a trusted project only, `.pi/advisor-preferences.md` may provide a short local brief. It is never written by pi-advisor, is treated as lower-priority untrusted text, and is redacted/capped before egress. Symlinks, unreadable files, and paths outside the project are ignored.
|
|
174
|
+
|
|
175
|
+
`advisorOutcomeLogging` defaults to false and is global-only: a project config cannot enable it. When enabled, `~/.pi/agent/advisor-outcomes.jsonl` stores bounded rotating JSONL records with only a version, timestamp, salted truncated advice digest, trigger, adoption, and validation status. It stores no prompt, advice, paths, tool output, repository data, session ID, or advice ID.
|
|
176
|
+
|
|
149
177
|
### Context and limits
|
|
150
178
|
|
|
151
179
|
- `contextMaxChars` defaults to `15000`. It preserves complete semantic entries and adds an omission marker rather than splitting a message.
|
|
@@ -173,7 +201,7 @@ The optional Session Advisor Summary defaults to off. When enabled, it is local
|
|
|
173
201
|
|
|
174
202
|
It distinguishes regular Markdown advice from gate decisions and records the trigger, model, usage/cost when available, failures, budget, and execution effect.
|
|
175
203
|
|
|
176
|
-
[Herdr](https://github.com/ogulcancelik/herdr) integration is enabled by default. It reports Advisor activity and blocked
|
|
204
|
+
[Herdr](https://github.com/ogulcancelik/herdr) integration is enabled by default. It reports Advisor activity and a bounded, redacted blocked-state summary through Herdr's metadata paths; disable it with `advisorHerdrIntegration`. Previously reported state is still cleared when integration is disabled.
|
|
177
205
|
|
|
178
206
|
## Development
|
|
179
207
|
|
package/package.json
CHANGED
|
@@ -1,4 +1,12 @@
|
|
|
1
1
|
{
|
|
2
|
+
"name": "pi-advisor-flow",
|
|
3
|
+
"version": "0.2.7",
|
|
4
|
+
"author": "Philip Brembeck",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "https://github.com/philipbrembeck/pi-advisor.git"
|
|
8
|
+
},
|
|
9
|
+
"main": "extensions/index.ts",
|
|
2
10
|
"devDependencies": {
|
|
3
11
|
"@biomejs/biome": "2.5.3",
|
|
4
12
|
"@earendil-works/pi-ai": "^0.80.7",
|
|
@@ -12,37 +20,35 @@
|
|
|
12
20
|
"typescript": "^5.3.3",
|
|
13
21
|
"ultracite": "7.9.4"
|
|
14
22
|
},
|
|
15
|
-
"name": "pi-advisor-flow",
|
|
16
23
|
"peerDependencies": {
|
|
17
24
|
"@earendil-works/pi-ai": "^0.80.7",
|
|
18
25
|
"@earendil-works/pi-coding-agent": "^0.80.7",
|
|
19
26
|
"@earendil-works/pi-tui": "^0.80.7",
|
|
20
27
|
"typebox": "^1.1.38"
|
|
21
28
|
},
|
|
22
|
-
"
|
|
23
|
-
"
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
"
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
"
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
"
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
"version": "0.2.4",
|
|
36
|
-
"license": "MIT",
|
|
37
|
-
"repository": {
|
|
38
|
-
"type": "git",
|
|
39
|
-
"url": "https://github.com/philipbrembeck/pi-advisor.git"
|
|
29
|
+
"peerDependenciesMeta": {
|
|
30
|
+
"@earendil-works/pi-ai": {
|
|
31
|
+
"optional": true
|
|
32
|
+
},
|
|
33
|
+
"@earendil-works/pi-coding-agent": {
|
|
34
|
+
"optional": true
|
|
35
|
+
},
|
|
36
|
+
"@earendil-works/pi-tui": {
|
|
37
|
+
"optional": true
|
|
38
|
+
},
|
|
39
|
+
"typebox": {
|
|
40
|
+
"optional": true
|
|
41
|
+
}
|
|
40
42
|
},
|
|
41
|
-
"homepage": "https://github.com/philipbrembeck/pi-advisor",
|
|
42
|
-
"author": "Philip Brembeck",
|
|
43
43
|
"description": "Advanced Executor/Advisor flow for Pi, fully configurable and extendable.",
|
|
44
|
-
"
|
|
45
|
-
|
|
44
|
+
"files": [
|
|
45
|
+
"extensions",
|
|
46
|
+
"src",
|
|
47
|
+
"CHANGELOG.md",
|
|
48
|
+
"LICENSE",
|
|
49
|
+
"README.md"
|
|
50
|
+
],
|
|
51
|
+
"homepage": "https://github.com/philipbrembeck/pi-advisor",
|
|
46
52
|
"keywords": [
|
|
47
53
|
"pi-package",
|
|
48
54
|
"pi-extension",
|
|
@@ -51,15 +57,28 @@
|
|
|
51
57
|
"pi-advisor",
|
|
52
58
|
"herdr"
|
|
53
59
|
],
|
|
54
|
-
"
|
|
55
|
-
|
|
56
|
-
"
|
|
57
|
-
|
|
58
|
-
|
|
60
|
+
"license": "MIT",
|
|
61
|
+
"lint-staged": {
|
|
62
|
+
"*.{json,jsonc,ts}": "bun run lint:fix --"
|
|
63
|
+
},
|
|
64
|
+
"overrides": {
|
|
65
|
+
"brace-expansion": "5.0.8"
|
|
66
|
+
},
|
|
59
67
|
"pi": {
|
|
60
68
|
"extensions": [
|
|
61
69
|
"./extensions/index.ts"
|
|
62
70
|
],
|
|
63
71
|
"image": "https://raw.githubusercontent.com/philipbrembeck/pi-advisor/refs/heads/main/assets/hero.png"
|
|
64
|
-
}
|
|
72
|
+
},
|
|
73
|
+
"scripts": {
|
|
74
|
+
"test": "bun test",
|
|
75
|
+
"typecheck": "tsc --noEmit",
|
|
76
|
+
"format": "bunx ultracite fix --linter-enabled=false",
|
|
77
|
+
"lint": "bunx ultracite check",
|
|
78
|
+
"lint:fix": "bunx ultracite fix",
|
|
79
|
+
"package:check": "npm pack --dry-run --json >/dev/null",
|
|
80
|
+
"prepare": "husky"
|
|
81
|
+
},
|
|
82
|
+
"type": "module",
|
|
83
|
+
"types": "extensions/index.ts"
|
|
65
84
|
}
|
package/src/commands.ts
CHANGED
|
@@ -16,6 +16,7 @@ import {
|
|
|
16
16
|
loadConfig,
|
|
17
17
|
parseArgs,
|
|
18
18
|
saveConfig,
|
|
19
|
+
saveGlobalOutcomeLogging,
|
|
19
20
|
setAdvisorAutoLoopGateRef,
|
|
20
21
|
setAdvisorBlockOnBlockedRef,
|
|
21
22
|
setAdvisorCollapseResponsesRef,
|
|
@@ -24,9 +25,12 @@ import {
|
|
|
24
25
|
setAdvisorEffortRef,
|
|
25
26
|
setAdvisorFailureGateRef,
|
|
26
27
|
setAdvisorFailureModeRef,
|
|
28
|
+
setAdvisorGitContextMaxCharsRef,
|
|
29
|
+
setAdvisorGitContextRef,
|
|
27
30
|
setAdvisorHerdrIntegrationRef,
|
|
28
31
|
setAdvisorLoopThresholdRef,
|
|
29
32
|
setAdvisorMaxCallsPerSessionRef,
|
|
33
|
+
setAdvisorOutcomeLoggingRef,
|
|
30
34
|
setAdvisorPlanGateRef,
|
|
31
35
|
setAdvisorRedactSecretsRef,
|
|
32
36
|
setAdvisorRef,
|
|
@@ -34,6 +38,7 @@ import {
|
|
|
34
38
|
setAdvisorToolPoliciesRef,
|
|
35
39
|
setAdvisorToolResultMaxBytesRef,
|
|
36
40
|
setAdvisorToolResultMaxLinesRef,
|
|
41
|
+
setAdvisorUntrackedContentRef,
|
|
37
42
|
setAlwaysOnRef,
|
|
38
43
|
setContextMaxCharsRef,
|
|
39
44
|
setExecutorEffortRef,
|
|
@@ -108,7 +113,12 @@ type ManualConsult = (
|
|
|
108
113
|
ctx: ExtensionContext,
|
|
109
114
|
question?: string,
|
|
110
115
|
signal?: AbortSignal
|
|
111
|
-
) => Promise<{
|
|
116
|
+
) => Promise<{
|
|
117
|
+
markdown: string;
|
|
118
|
+
thinkingText: string;
|
|
119
|
+
draftBytes?: number;
|
|
120
|
+
preferenceBytes?: number;
|
|
121
|
+
}>;
|
|
112
122
|
type ThinkingLevel = Parameters<ExtensionAPI["setThinkingLevel"]>[0];
|
|
113
123
|
|
|
114
124
|
const notify = (
|
|
@@ -248,7 +258,11 @@ export const registerCommands = (
|
|
|
248
258
|
pi.setThinkingLevel(executorEffortRef as ThinkingLevel);
|
|
249
259
|
}
|
|
250
260
|
if (!flowEnabled()) {
|
|
251
|
-
pi.setActiveTools([
|
|
261
|
+
pi.setActiveTools([
|
|
262
|
+
...pi.getActiveTools(),
|
|
263
|
+
"ask_advisor",
|
|
264
|
+
"record_advisor_outcome",
|
|
265
|
+
]);
|
|
252
266
|
}
|
|
253
267
|
if (announce) {
|
|
254
268
|
notify(
|
|
@@ -459,6 +473,7 @@ export const registerCommands = (
|
|
|
459
473
|
|
|
460
474
|
pi.registerCommand("advisor-settings", {
|
|
461
475
|
description: "Configure Advisor context and reasoning effort",
|
|
476
|
+
// biome-ignore lint/complexity/noExcessiveCognitiveComplexity: one settings form maps every persisted control.
|
|
462
477
|
handler: async (_args, ctx) => {
|
|
463
478
|
loadConfig(ctx);
|
|
464
479
|
if (!ctx.hasUI) {
|
|
@@ -505,9 +520,19 @@ export const registerCommands = (
|
|
|
505
520
|
setAdvisorToolResultMaxLinesRef(settings.toolResultMaxLines ?? 2000);
|
|
506
521
|
setAdvisorToolResultMaxBytesRef(settings.toolResultMaxBytes ?? 50 * 1024);
|
|
507
522
|
setAdvisorRedactSecretsRef(settings.redactSecrets ?? false);
|
|
523
|
+
setAdvisorGitContextRef(settings.gitContext ?? "summary");
|
|
524
|
+
setAdvisorGitContextMaxCharsRef(settings.gitContextMaxChars ?? 20_000);
|
|
508
525
|
setAdvisorToolPoliciesRef(settings.toolPolicies ?? {});
|
|
526
|
+
setAdvisorUntrackedContentRef(settings.untrackedContent ?? false);
|
|
527
|
+
setAdvisorOutcomeLoggingRef(settings.outcomeLogging ?? false);
|
|
509
528
|
const path = saveConfig(ctx);
|
|
510
|
-
|
|
529
|
+
const globalPath = saveGlobalOutcomeLogging(
|
|
530
|
+
settings.outcomeLogging ?? false
|
|
531
|
+
);
|
|
532
|
+
ctx.ui.notify(
|
|
533
|
+
`Saved Advisor settings to ${path}; outcome logging globally to ${globalPath}`,
|
|
534
|
+
"info"
|
|
535
|
+
);
|
|
511
536
|
},
|
|
512
537
|
});
|
|
513
538
|
|
|
@@ -515,7 +540,12 @@ export const registerCommands = (
|
|
|
515
540
|
description: "Disable on-demand Advisor calls; keep the current model",
|
|
516
541
|
handler: (_args, ctx) => {
|
|
517
542
|
pi.setActiveTools(
|
|
518
|
-
pi
|
|
543
|
+
pi
|
|
544
|
+
.getActiveTools()
|
|
545
|
+
.filter(
|
|
546
|
+
(name) =>
|
|
547
|
+
name !== "ask_advisor" && name !== "record_advisor_outcome"
|
|
548
|
+
)
|
|
519
549
|
);
|
|
520
550
|
// Leaving alwaysOn set would silently reactivate the flow next session.
|
|
521
551
|
const wasAlwaysOn = alwaysOnRef;
|