@henryqw/pi-subagent 2.10.1 → 2.10.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/extensions/subagent.ts +4 -16
- package/package.json +1 -1
package/extensions/subagent.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { spawn } from "node:child_process";
|
|
2
2
|
import { existsSync } from "node:fs";
|
|
3
3
|
import { basename } from "node:path";
|
|
4
|
+
import { StringDecoder } from "node:string_decoder";
|
|
4
5
|
import { StringEnum } from "@earendil-works/pi-ai";
|
|
5
6
|
import { type ExtensionAPI, type ExtensionContext, type Theme } from "@earendil-works/pi-coding-agent";
|
|
6
7
|
import { type Component, truncateToWidth, type TUI, visibleWidth } from "@earendil-works/pi-tui";
|
|
@@ -11,7 +12,6 @@ import {
|
|
|
11
12
|
type ThinkingLevel,
|
|
12
13
|
modelReference,
|
|
13
14
|
PROFILE_NAMES,
|
|
14
|
-
type ProfileName,
|
|
15
15
|
resolveAvailableModel,
|
|
16
16
|
resolveConfiguredTaskRoute,
|
|
17
17
|
type ResolvedTaskRoute,
|
|
@@ -20,7 +20,6 @@ import {
|
|
|
20
20
|
import { Type } from "typebox";
|
|
21
21
|
import { createRoleLaunch, isProfileName, loadRoles, resolveTaskRoute } from "@henryqw/pi-subagent";
|
|
22
22
|
|
|
23
|
-
const MODEL_CLASSES = PROFILE_NAMES;
|
|
24
23
|
const SUBAGENT_TASK = "pi-subagent/delegateTask";
|
|
25
24
|
const MAX_OUTPUT_BYTES = 50 * 1024;
|
|
26
25
|
const MAX_JSON_EVENT_BYTES = 1024 * 1024;
|
|
@@ -48,7 +47,6 @@ export function resolveTimeoutPolicy(partial: SubagentTimeoutConfig | undefined)
|
|
|
48
47
|
if (partial.activeWindowSeconds !== undefined) policy.activeWindowMs = partial.activeWindowSeconds * 1_000;
|
|
49
48
|
return policy;
|
|
50
49
|
}
|
|
51
|
-
type ModelClass = ProfileName;
|
|
52
50
|
class SubagentTimeoutError extends Error {}
|
|
53
51
|
type ChildResult = {
|
|
54
52
|
exitCode: number;
|
|
@@ -68,8 +66,6 @@ type WidgetItem = {
|
|
|
68
66
|
removeAt?: number;
|
|
69
67
|
};
|
|
70
68
|
|
|
71
|
-
const isModelClass = isProfileName;
|
|
72
|
-
|
|
73
69
|
const cleanText = (value: unknown, field: string, file: string): string => {
|
|
74
70
|
if (typeof value !== "string" || !value.trim() || value.includes("\0")) {
|
|
75
71
|
throw new Error(`${file}: ${field} must be non-empty text.`);
|
|
@@ -103,15 +99,7 @@ function assistantText(message: unknown): string | undefined {
|
|
|
103
99
|
}
|
|
104
100
|
|
|
105
101
|
function utf8Prefix(text: string, maxBytes: number): string {
|
|
106
|
-
|
|
107
|
-
let high = Math.min(text.length, maxBytes);
|
|
108
|
-
while (low < high) {
|
|
109
|
-
const middle = Math.ceil((low + high) / 2);
|
|
110
|
-
if (Buffer.byteLength(text.slice(0, middle), "utf8") <= maxBytes) low = middle;
|
|
111
|
-
else high = middle - 1;
|
|
112
|
-
}
|
|
113
|
-
if (low > 0 && low < text.length && /[\uD800-\uDBFF]/.test(text[low - 1]) && /[\uDC00-\uDFFF]/.test(text[low])) low--;
|
|
114
|
-
return text.slice(0, low);
|
|
102
|
+
return new StringDecoder().write(Buffer.from(text).subarray(0, maxBytes));
|
|
115
103
|
}
|
|
116
104
|
|
|
117
105
|
function cappedPrefix(text: string, totalBytes: number): string {
|
|
@@ -439,7 +427,7 @@ const Parameters = Type.Object({
|
|
|
439
427
|
model: Type.Optional(Type.String({
|
|
440
428
|
description: "Designated model as provider/modelId; overrides modelClass. Unknown references reject with the list of available models.",
|
|
441
429
|
})),
|
|
442
|
-
modelClass: Type.Optional(StringEnum(
|
|
430
|
+
modelClass: Type.Optional(StringEnum(PROFILE_NAMES, {
|
|
443
431
|
description: "Classify task complexity: fast for narrow lookups or mechanical edits; balanced for normal bounded work; frontier for ambiguous, cross-cutting, or high-risk reasoning; fav for the user's favorite model when they ask for it. Defaults to the shared pi-subagent/delegateTask assignment.",
|
|
444
432
|
})),
|
|
445
433
|
background: Type.Optional(Type.Boolean({
|
|
@@ -693,7 +681,7 @@ export default function subagentExtension(
|
|
|
693
681
|
throw new Error(`Unknown Subagent role: ${params.role}. Available roles: ${roles.map(({ name }) => name).join(", ") || "none"}.`);
|
|
694
682
|
}
|
|
695
683
|
|
|
696
|
-
if (params.modelClass !== undefined && !
|
|
684
|
+
if (params.modelClass !== undefined && !isProfileName(params.modelClass)) {
|
|
697
685
|
throw new Error("delegate_task modelClass must be fast, balanced, frontier, or fav.");
|
|
698
686
|
}
|
|
699
687
|
// Resolve against the latest known session context: a task queued past
|