pi-advisor-flow 0.8.1-dev.2 → 0.8.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/CHANGELOG.md +7 -1
- package/dist/index.js +26 -12
- package/package.json +1 -1
- package/src/child-session.ts +15 -0
- package/src/commands/activation.ts +10 -3
- package/src/commands/lifecycle.ts +6 -1
- package/src/scout.ts +16 -7
package/CHANGELOG.md
CHANGED
|
@@ -4,7 +4,13 @@ All notable changes to this project are documented here.
|
|
|
4
4
|
|
|
5
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/).
|
|
6
6
|
|
|
7
|
-
##
|
|
7
|
+
## 0.8.1 - 2026-09-23
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
|
|
11
|
+
- Preserve a native subagent's host-selected model and thinking level when `alwaysOn` or explicit `/advisor` activation runs in a process marked with `PI_SUBAGENT_CHILD=1`.
|
|
12
|
+
- Keep marked child model selections out of the persisted parent Executor configuration.
|
|
13
|
+
- Run Advisor Scout with the marked child's active model and thinking level instead of replacing them with the configured parent Executor.
|
|
8
14
|
|
|
9
15
|
### Added
|
|
10
16
|
|
package/dist/index.js
CHANGED
|
@@ -272,6 +272,16 @@ var splitRef = (ref) => {
|
|
|
272
272
|
return i === -1 ? ["openai-codex", ref] : [ref.slice(0, i), ref.slice(i + 1)];
|
|
273
273
|
};
|
|
274
274
|
|
|
275
|
+
// src/child-session.ts
|
|
276
|
+
var isMarkedSubagent = () => process.env.PI_SUBAGENT_CHILD === "1";
|
|
277
|
+
var effectiveExecutorRef = (ctx) => {
|
|
278
|
+
if (isMarkedSubagent() && ctx.model) {
|
|
279
|
+
return `${ctx.model.provider}/${ctx.model.id}`;
|
|
280
|
+
}
|
|
281
|
+
return executorRef;
|
|
282
|
+
};
|
|
283
|
+
var effectiveExecutorEffort = (ctx) => isMarkedSubagent() ? ctx.thinkingLevel : executorEffortRef;
|
|
284
|
+
|
|
275
285
|
// src/content-utils.ts
|
|
276
286
|
var isRecord = (value) => Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
277
287
|
var isRecordOf = (value) => Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
@@ -2814,17 +2824,17 @@ var setupAbortWatch = (parentSignal, timeoutMs) => {
|
|
|
2814
2824
|
wasTimedOut: () => timedOut
|
|
2815
2825
|
};
|
|
2816
2826
|
};
|
|
2817
|
-
var streamScoutResponse = async (dependencies, resolved, manifest, parentSignal, timeoutMs, publish) => {
|
|
2827
|
+
var streamScoutResponse = async (dependencies, resolved, executorModel, executorEffort, manifest, parentSignal, timeoutMs, publish) => {
|
|
2818
2828
|
const { abortPromise, controller, teardown, wasTimedOut } = setupAbortWatch(parentSignal, timeoutMs);
|
|
2819
2829
|
try {
|
|
2820
2830
|
const collection = dependencies.collect(resolved, {
|
|
2821
2831
|
messages: [manifestMessage(manifest)],
|
|
2822
2832
|
onChunk: (thinking, text) => {
|
|
2823
2833
|
if (!controller.signal.aborted) {
|
|
2824
|
-
publish({ model:
|
|
2834
|
+
publish({ model: executorModel, text, thinking, type: "chunk" });
|
|
2825
2835
|
}
|
|
2826
2836
|
},
|
|
2827
|
-
reasoning:
|
|
2837
|
+
reasoning: executorEffort,
|
|
2828
2838
|
signal: controller.signal,
|
|
2829
2839
|
systemPrompt: SCOUT_SYSTEM
|
|
2830
2840
|
});
|
|
@@ -2857,7 +2867,7 @@ var runAdvisorScout = async (ctx, manifest, parentSignal, onEvent, timeoutMs = S
|
|
|
2857
2867
|
category,
|
|
2858
2868
|
message,
|
|
2859
2869
|
metrics: usage === undefined ? baseMetrics(manifest, startedAt) : { ...baseMetrics(manifest, startedAt), usage },
|
|
2860
|
-
model:
|
|
2870
|
+
model: effectiveExecutorRef(ctx),
|
|
2861
2871
|
ok: false
|
|
2862
2872
|
};
|
|
2863
2873
|
publish({ outcome, type: "fallback" });
|
|
@@ -2866,9 +2876,11 @@ var runAdvisorScout = async (ctx, manifest, parentSignal, onEvent, timeoutMs = S
|
|
|
2866
2876
|
if (parentSignal?.aborted) {
|
|
2867
2877
|
return cancelled();
|
|
2868
2878
|
}
|
|
2879
|
+
const executorModel = effectiveExecutorRef(ctx);
|
|
2880
|
+
const executorEffort = effectiveExecutorEffort(ctx);
|
|
2869
2881
|
let resolved;
|
|
2870
2882
|
try {
|
|
2871
|
-
resolved = await dependencies.resolve(ctx,
|
|
2883
|
+
resolved = await dependencies.resolve(ctx, executorModel, "Scout");
|
|
2872
2884
|
} catch (error) {
|
|
2873
2885
|
if (parentSignal?.aborted) {
|
|
2874
2886
|
return cancelled();
|
|
@@ -2879,8 +2891,8 @@ var runAdvisorScout = async (ctx, manifest, parentSignal, onEvent, timeoutMs = S
|
|
|
2879
2891
|
if (parentSignal?.aborted) {
|
|
2880
2892
|
return cancelled();
|
|
2881
2893
|
}
|
|
2882
|
-
publish({ model:
|
|
2883
|
-
const streamed = await streamScoutResponse(dependencies, resolved, manifest, parentSignal, timeoutMs, publish);
|
|
2894
|
+
publish({ model: executorModel, type: "call" });
|
|
2895
|
+
const streamed = await streamScoutResponse(dependencies, resolved, executorModel, executorEffort, manifest, parentSignal, timeoutMs, publish);
|
|
2884
2896
|
if (!streamed.ok) {
|
|
2885
2897
|
if (parentSignal?.aborted) {
|
|
2886
2898
|
return cancelled();
|
|
@@ -2907,7 +2919,7 @@ var runAdvisorScout = async (ctx, manifest, parentSignal, onEvent, timeoutMs = S
|
|
|
2907
2919
|
]).size,
|
|
2908
2920
|
usage: snapshotAdvisorUsage(streamed.streamed.usage)
|
|
2909
2921
|
},
|
|
2910
|
-
model:
|
|
2922
|
+
model: executorModel,
|
|
2911
2923
|
ok: true,
|
|
2912
2924
|
selectedLabels: manifest.groups.filter((group) => group.required || selection.selectedIds.includes(group.id)).map((group) => group.label),
|
|
2913
2925
|
selection
|
|
@@ -4173,7 +4185,7 @@ var resolveActivationModels = async (runtime, ctx) => {
|
|
|
4173
4185
|
if (!(advisorAuth.ok && advisorAuth.apiKey)) {
|
|
4174
4186
|
return { error: `No API key for Advisor ${advisorRef}` };
|
|
4175
4187
|
}
|
|
4176
|
-
if (!await runtime.setExecutorModel(executor)) {
|
|
4188
|
+
if (!isMarkedSubagent() && !await runtime.setExecutorModel(executor)) {
|
|
4177
4189
|
return { error: `No API key for Executor ${executorRef}` };
|
|
4178
4190
|
}
|
|
4179
4191
|
return {};
|
|
@@ -4219,7 +4231,7 @@ var activateAdvisor = async (runtime, args, ctx, announce = true) => {
|
|
|
4219
4231
|
saveConfig(ctx, { persistAdvisor: true, persistExecutor: true });
|
|
4220
4232
|
}
|
|
4221
4233
|
runtime.pendingExecutorModelRef = undefined;
|
|
4222
|
-
if (executorEffortRef) {
|
|
4234
|
+
if (executorEffortRef && !isMarkedSubagent()) {
|
|
4223
4235
|
runtime.pi.setThinkingLevel(executorEffortRef);
|
|
4224
4236
|
}
|
|
4225
4237
|
if (!runtime.flowEnabled()) {
|
|
@@ -4230,9 +4242,11 @@ var activateAdvisor = async (runtime, args, ctx, announce = true) => {
|
|
|
4230
4242
|
]);
|
|
4231
4243
|
}
|
|
4232
4244
|
if (announce) {
|
|
4245
|
+
const activeExecutorRef = effectiveExecutorRef(ctx);
|
|
4246
|
+
const activeExecutorEffort = effectiveExecutorEffort(ctx);
|
|
4233
4247
|
notify(ctx, `${ADVISOR_ACTIVATION_EXPLANATION}
|
|
4234
4248
|
|
|
4235
|
-
Advisor flow ready — Executor: ${
|
|
4249
|
+
Advisor flow ready — Executor: ${activeExecutorRef} (thinking: ${activeExecutorEffort || "default"}) · Advisor: ${advisorRef} (thinking: ${advisorEffortRef || "default"})`, "info");
|
|
4236
4250
|
}
|
|
4237
4251
|
};
|
|
4238
4252
|
|
|
@@ -4251,7 +4265,7 @@ var registerCommandLifecycle = (runtime, activateAdvisor) => {
|
|
|
4251
4265
|
}
|
|
4252
4266
|
});
|
|
4253
4267
|
runtime.pi.on("model_select", (event, ctx) => {
|
|
4254
|
-
if (event.source !== "set" || runtime.suppressModelSelectionSync) {
|
|
4268
|
+
if (event.source !== "set" || runtime.suppressModelSelectionSync || isMarkedSubagent()) {
|
|
4255
4269
|
return;
|
|
4256
4270
|
}
|
|
4257
4271
|
const selected = `${event.model.provider}/${event.model.id}`;
|
package/package.json
CHANGED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { ExtensionContext } from "@earendil-works/pi-coding-agent";
|
|
2
|
+
|
|
3
|
+
import { executorEffortRef, executorRef } from "./config/state.ts";
|
|
4
|
+
|
|
5
|
+
export const isMarkedSubagent = () => process.env.PI_SUBAGENT_CHILD === "1";
|
|
6
|
+
|
|
7
|
+
export const effectiveExecutorRef = (ctx: ExtensionContext) => {
|
|
8
|
+
if (isMarkedSubagent() && ctx.model) {
|
|
9
|
+
return `${ctx.model.provider}/${ctx.model.id}`;
|
|
10
|
+
}
|
|
11
|
+
return executorRef;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export const effectiveExecutorEffort = (ctx: ExtensionContext) =>
|
|
15
|
+
isMarkedSubagent() ? ctx.thinkingLevel : executorEffortRef;
|
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
import type { ExtensionContext } from "@earendil-works/pi-coding-agent";
|
|
2
2
|
|
|
3
|
+
import {
|
|
4
|
+
effectiveExecutorEffort,
|
|
5
|
+
effectiveExecutorRef,
|
|
6
|
+
isMarkedSubagent,
|
|
7
|
+
} from "../child-session.ts";
|
|
3
8
|
import { parseArgs } from "../config/args.ts";
|
|
4
9
|
import {
|
|
5
10
|
advisorEffortRef,
|
|
@@ -51,7 +56,7 @@ const resolveActivationModels = async (
|
|
|
51
56
|
if (!(advisorAuth.ok && advisorAuth.apiKey)) {
|
|
52
57
|
return { error: `No API key for Advisor ${advisorRef}` };
|
|
53
58
|
}
|
|
54
|
-
if (!(await runtime.setExecutorModel(executor))) {
|
|
59
|
+
if (!isMarkedSubagent() && !(await runtime.setExecutorModel(executor))) {
|
|
55
60
|
return { error: `No API key for Executor ${executorRef}` };
|
|
56
61
|
}
|
|
57
62
|
return {};
|
|
@@ -116,7 +121,7 @@ export const activateAdvisor = async (
|
|
|
116
121
|
// an older inactive selection override an explicit activation argument on a
|
|
117
122
|
// later attempt.
|
|
118
123
|
runtime.pendingExecutorModelRef = undefined;
|
|
119
|
-
if (executorEffortRef) {
|
|
124
|
+
if (executorEffortRef && !isMarkedSubagent()) {
|
|
120
125
|
// SAFETY: executorEffortRef is operator-configured and trusted to name a ThinkingLevel.
|
|
121
126
|
runtime.pi.setThinkingLevel(executorEffortRef as ThinkingLevel);
|
|
122
127
|
}
|
|
@@ -128,9 +133,11 @@ export const activateAdvisor = async (
|
|
|
128
133
|
]);
|
|
129
134
|
}
|
|
130
135
|
if (announce) {
|
|
136
|
+
const activeExecutorRef = effectiveExecutorRef(ctx);
|
|
137
|
+
const activeExecutorEffort = effectiveExecutorEffort(ctx);
|
|
131
138
|
notify(
|
|
132
139
|
ctx,
|
|
133
|
-
`${ADVISOR_ACTIVATION_EXPLANATION}\n\nAdvisor flow ready — Executor: ${
|
|
140
|
+
`${ADVISOR_ACTIVATION_EXPLANATION}\n\nAdvisor flow ready — Executor: ${activeExecutorRef} (thinking: ${activeExecutorEffort || "default"}) · Advisor: ${advisorRef} (thinking: ${advisorEffortRef || "default"})`,
|
|
134
141
|
"info"
|
|
135
142
|
);
|
|
136
143
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { ExtensionContext } from "@earendil-works/pi-coding-agent";
|
|
2
2
|
|
|
3
|
+
import { isMarkedSubagent } from "../child-session.ts";
|
|
3
4
|
import {
|
|
4
5
|
alwaysOnRef,
|
|
5
6
|
executorRef,
|
|
@@ -40,7 +41,11 @@ export const registerCommandLifecycle = (
|
|
|
40
41
|
// "restore" replays a stored session model and "cycle" changes the active
|
|
41
42
|
// model without an explicit `/model` choice. Neither should redefine the
|
|
42
43
|
// configured Executor.
|
|
43
|
-
if (
|
|
44
|
+
if (
|
|
45
|
+
event.source !== "set" ||
|
|
46
|
+
runtime.suppressModelSelectionSync ||
|
|
47
|
+
isMarkedSubagent()
|
|
48
|
+
) {
|
|
44
49
|
return;
|
|
45
50
|
}
|
|
46
51
|
const selected = `${event.model.provider}/${event.model.id}`;
|
package/src/scout.ts
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import type { Message } from "@earendil-works/pi-ai/compat";
|
|
2
2
|
import type { ExtensionContext } from "@earendil-works/pi-coding-agent";
|
|
3
3
|
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
effectiveExecutorEffort,
|
|
6
|
+
effectiveExecutorRef,
|
|
7
|
+
} from "./child-session.ts";
|
|
5
8
|
import { isRecord, isString } from "./content-utils.ts";
|
|
6
9
|
import { collectTextStream, resolveConfiguredModel } from "./model-stream.ts";
|
|
7
10
|
import type {
|
|
@@ -250,6 +253,8 @@ type ScoutStreamResult =
|
|
|
250
253
|
const streamScoutResponse = async (
|
|
251
254
|
dependencies: ScoutDependencies,
|
|
252
255
|
resolved: ResolvedConfiguredModel,
|
|
256
|
+
executorModel: string,
|
|
257
|
+
executorEffort: string | undefined,
|
|
253
258
|
manifest: ScoutManifest,
|
|
254
259
|
parentSignal: AbortSignal | undefined,
|
|
255
260
|
timeoutMs: number,
|
|
@@ -264,10 +269,10 @@ const streamScoutResponse = async (
|
|
|
264
269
|
messages: [manifestMessage(manifest)],
|
|
265
270
|
onChunk: (thinking, text) => {
|
|
266
271
|
if (!controller.signal.aborted) {
|
|
267
|
-
publish({ model:
|
|
272
|
+
publish({ model: executorModel, text, thinking, type: "chunk" });
|
|
268
273
|
}
|
|
269
274
|
},
|
|
270
|
-
reasoning:
|
|
275
|
+
reasoning: executorEffort,
|
|
271
276
|
signal: controller.signal,
|
|
272
277
|
systemPrompt: SCOUT_SYSTEM,
|
|
273
278
|
});
|
|
@@ -317,7 +322,7 @@ export const runAdvisorScout = async (
|
|
|
317
322
|
usage === undefined
|
|
318
323
|
? baseMetrics(manifest, startedAt)
|
|
319
324
|
: { ...baseMetrics(manifest, startedAt), usage },
|
|
320
|
-
model:
|
|
325
|
+
model: effectiveExecutorRef(ctx),
|
|
321
326
|
ok: false as const,
|
|
322
327
|
};
|
|
323
328
|
publish({ outcome, type: "fallback" });
|
|
@@ -328,9 +333,11 @@ export const runAdvisorScout = async (
|
|
|
328
333
|
return cancelled();
|
|
329
334
|
}
|
|
330
335
|
|
|
336
|
+
const executorModel = effectiveExecutorRef(ctx);
|
|
337
|
+
const executorEffort = effectiveExecutorEffort(ctx);
|
|
331
338
|
let resolved: ResolvedConfiguredModel;
|
|
332
339
|
try {
|
|
333
|
-
resolved = await dependencies.resolve(ctx,
|
|
340
|
+
resolved = await dependencies.resolve(ctx, executorModel, "Scout");
|
|
334
341
|
} catch (error) {
|
|
335
342
|
if (parentSignal?.aborted) {
|
|
336
343
|
return cancelled();
|
|
@@ -342,11 +349,13 @@ export const runAdvisorScout = async (
|
|
|
342
349
|
if (parentSignal?.aborted) {
|
|
343
350
|
return cancelled();
|
|
344
351
|
}
|
|
345
|
-
publish({ model:
|
|
352
|
+
publish({ model: executorModel, type: "call" });
|
|
346
353
|
|
|
347
354
|
const streamed = await streamScoutResponse(
|
|
348
355
|
dependencies,
|
|
349
356
|
resolved,
|
|
357
|
+
executorModel,
|
|
358
|
+
executorEffort,
|
|
350
359
|
manifest,
|
|
351
360
|
parentSignal,
|
|
352
361
|
timeoutMs,
|
|
@@ -390,7 +399,7 @@ export const runAdvisorScout = async (
|
|
|
390
399
|
]).size,
|
|
391
400
|
usage: snapshotAdvisorUsage(streamed.streamed.usage),
|
|
392
401
|
},
|
|
393
|
-
model:
|
|
402
|
+
model: executorModel,
|
|
394
403
|
ok: true as const,
|
|
395
404
|
selectedLabels: manifest.groups
|
|
396
405
|
.filter(
|