@ian-pascoe/pi-advisor 0.3.0 → 0.3.1
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 +2 -2
- package/package.json +1 -6
- package/src/advisor-observer.ts +17 -9
- package/src/advisor-session.ts +5 -5
- package/src/advisor-settings.ts +1 -1
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
`@ian-pascoe/pi-advisor` reviews a Pi agent's completed work and surfaces concise, attributed findings for material problems and worthwhile low-risk cleanup.
|
|
4
4
|
|
|
5
|
-
Requires Pi `0.
|
|
5
|
+
Requires Pi `0.87.1` and Node `>=22.19.0`. Other Pi versions pause review with an explicit compatibility error.
|
|
6
6
|
|
|
7
7
|
## Install
|
|
8
8
|
|
|
@@ -60,7 +60,7 @@ The Advisor inherits each observed agent's model and thinking level independentl
|
|
|
60
60
|
|
|
61
61
|
## Sessions and Context Management
|
|
62
62
|
|
|
63
|
-
Each watched agent has a private, persisted native Advisor Session with fresh, session-bound extension resources. Reviews reuse that session until context or configuration changes require rebuilding. Pi 0.
|
|
63
|
+
Each watched agent has a private, persisted native Advisor Session with fresh, session-bound extension resources. Reviews reuse that session until context or configuration changes require rebuilding. Pi 0.87.1's hidden inline `llama.cpp` built-in is recreated from the installed Pi package's shipped extension file, retaining its ordered metadata and fresh provider state. This is a fixed-version compatibility recipe, not general inline-factory support; it requires the shipped file and the built-in's expected registration shape. Other opaque inline or custom extension resources that cannot be safely recreated are reported as unsupported and pause the Advisor; they are not silently reused or omitted. The Advisor's session state remains separate from the observed agent's state.
|
|
64
64
|
|
|
65
65
|
Context Management is optional. If loaded and its tools are granted, `context_notes`, `context_history`, and `context_rollover` operate on the Advisor's private context. If any of those three tools is excluded, the Advisor pauses before reviewing. There is no autogrant or hook bypass.
|
|
66
66
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ian-pascoe/pi-advisor",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Background review and attributed corrective advice for Pi agent sessions.",
|
|
6
6
|
"keywords": [
|
|
@@ -34,11 +34,6 @@
|
|
|
34
34
|
"dependencies": {
|
|
35
35
|
"@ian-pascoe/pi-utils": "^0.2.0"
|
|
36
36
|
},
|
|
37
|
-
"devDependencies": {
|
|
38
|
-
"@earendil-works/pi-agent-core": "0.85.1",
|
|
39
|
-
"@earendil-works/pi-ai": "0.85.1",
|
|
40
|
-
"@earendil-works/pi-coding-agent": "0.85.1"
|
|
41
|
-
},
|
|
42
37
|
"peerDependencies": {
|
|
43
38
|
"@earendil-works/pi-agent-core": "*",
|
|
44
39
|
"@earendil-works/pi-ai": "*",
|
package/src/advisor-observer.ts
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
import { isDeepStrictEqual } from "node:util";
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
contentText,
|
|
4
|
+
getCurrentSystemPrompt,
|
|
5
|
+
getCurrentTools,
|
|
6
|
+
toToolDeclaration,
|
|
7
|
+
type Context,
|
|
8
|
+
type ImageContent,
|
|
9
|
+
} from "@earendil-works/pi-ai";
|
|
3
10
|
import {
|
|
4
11
|
defineTool,
|
|
5
12
|
convertToLlm,
|
|
@@ -58,7 +65,7 @@ const pendingQueuesSchema = Type.Object({
|
|
|
58
65
|
_pendingCustomMessages: Type.Array(Type.Unknown()),
|
|
59
66
|
});
|
|
60
67
|
|
|
61
|
-
// oxlint-disable-next-line anti-slop/no-unknown-parameters -- SAFETY: Pi 0.
|
|
68
|
+
// oxlint-disable-next-line anti-slop/no-unknown-parameters -- SAFETY: Pi 0.87.1 has no selective queue-removal API. Validate its native queue data and remove only exact owned finding identities, never unrelated messages or journal entries.
|
|
62
69
|
function retractFindings(session: unknown, findings: ReadonlySet<Finding>): void {
|
|
63
70
|
if (!findings.size) return;
|
|
64
71
|
if (!Value.Check(pendingQueuesSchema, session))
|
|
@@ -208,14 +215,15 @@ export class AdvisorObserver {
|
|
|
208
215
|
if (!this.closed && this.config.enabled) {
|
|
209
216
|
try {
|
|
210
217
|
if (this.active && !this.sameObservation(this.active)) this.reset();
|
|
211
|
-
//
|
|
218
|
+
// Pi carries the prompt and tool deltas as system messages. Replay them into the
|
|
219
|
+
// current state and copy tool declarations, never execute callbacks.
|
|
212
220
|
this.snapshot = structuredClone({
|
|
213
|
-
|
|
214
|
-
tools: (context.
|
|
215
|
-
name,
|
|
216
|
-
description,
|
|
217
|
-
|
|
218
|
-
|
|
221
|
+
systemPrompt: getCurrentSystemPrompt(context.messages),
|
|
222
|
+
tools: getCurrentTools(context.messages).map((tool) => {
|
|
223
|
+
const { name, description, parameters } = toToolDeclaration(tool);
|
|
224
|
+
return { name, description, parameters };
|
|
225
|
+
}),
|
|
226
|
+
messages: context.messages.filter((message) => message.role !== "system"),
|
|
219
227
|
});
|
|
220
228
|
} catch {
|
|
221
229
|
this.fail("Advisor cannot capture this model context safely");
|
package/src/advisor-session.ts
CHANGED
|
@@ -72,7 +72,7 @@ export async function disposeAdvisorSession(runtime: AgentSessionRuntime): Promi
|
|
|
72
72
|
}
|
|
73
73
|
}
|
|
74
74
|
|
|
75
|
-
// Pi 0.
|
|
75
|
+
// Pi 0.87.1 keeps these plain constructor inputs private; public scoped getters omit applyOverrides.
|
|
76
76
|
/* oxlint-disable anti-slop/no-unknown-parameters -- SAFETY: Capability-check native SDK data before copying; offline SDK creation tests cover these inputs. */
|
|
77
77
|
function recreationInputs(
|
|
78
78
|
loader: unknown,
|
|
@@ -111,7 +111,7 @@ function recreationInputs(
|
|
|
111
111
|
if (
|
|
112
112
|
Value.Check(fileAuthSchema, store) &&
|
|
113
113
|
store.authPath === store.storage.authPath &&
|
|
114
|
-
// Pi 0.
|
|
114
|
+
// Pi 0.87.1's bundled CLI names the same native class _AuthStorage.
|
|
115
115
|
["AuthStorage", "_AuthStorage"].includes(Object.getPrototypeOf(store)?.constructor.name) &&
|
|
116
116
|
Object.getPrototypeOf(store.storage)?.constructor.name === "FileAuthStorageBackend"
|
|
117
117
|
)
|
|
@@ -136,9 +136,9 @@ export async function createAdvisorSession(
|
|
|
136
136
|
observed: AgentSession,
|
|
137
137
|
options: AdvisorSessionOptions,
|
|
138
138
|
): Promise<AgentSessionRuntime> {
|
|
139
|
-
if (VERSION !== "0.
|
|
139
|
+
if (VERSION !== "0.87.1")
|
|
140
140
|
throw new Error(
|
|
141
|
-
`Unsupported Pi ${VERSION}: Advisor's native tool ceiling and session lifecycle are verified on Pi 0.
|
|
141
|
+
`Unsupported Pi ${VERSION}: Advisor's native tool ceiling and session lifecycle are verified on Pi 0.87.1`,
|
|
142
142
|
);
|
|
143
143
|
options.signal?.throwIfAborted();
|
|
144
144
|
const cancelled = Promise.withResolvers<never>();
|
|
@@ -203,7 +203,7 @@ async function buildAdvisorSession(
|
|
|
203
203
|
const extensionPaths = source.getExtensions().extensions.map((extension) => {
|
|
204
204
|
if (extension.resolvedPath && !extension.resolvedPath.startsWith("<"))
|
|
205
205
|
return extension.resolvedPath;
|
|
206
|
-
// Pi 0.
|
|
206
|
+
// Pi 0.87.1 injects this built-in inline, but ships a fresh file-backed factory.
|
|
207
207
|
// Match its registration shape, not arbitrary inline closures or hidden extensions.
|
|
208
208
|
if (
|
|
209
209
|
extension.path === "<inline:llama.cpp>" &&
|
package/src/advisor-settings.ts
CHANGED
|
@@ -171,7 +171,7 @@ const storageSchema = Type.Object({
|
|
|
171
171
|
),
|
|
172
172
|
});
|
|
173
173
|
|
|
174
|
-
/** Use Pi's actual backend: its generic storage API is not exported in 0.
|
|
174
|
+
/** Use Pi's actual backend: its generic storage API is not exported in 0.87.1. */
|
|
175
175
|
export async function writeAdvisorSettings(
|
|
176
176
|
manager: SettingsManager,
|
|
177
177
|
scope: "global" | "project",
|