pi-subagents 0.35.1 → 0.37.0
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 +71 -0
- package/README.md +224 -31
- package/agents/advisor.md +73 -0
- package/agents/delegate.md +2 -0
- package/agents/worker.md +2 -0
- package/package.json +11 -13
- package/skills/pi-subagents/SKILL.md +42 -13
- package/src/agents/agent-management.ts +7 -1
- package/src/agents/agents.ts +121 -17
- package/src/api/capability-ceiling.ts +17 -0
- package/src/api/delegation.ts +127 -0
- package/src/api/preflight.ts +399 -0
- package/src/extension/config.ts +7 -1
- package/src/extension/index.ts +52 -38
- package/src/extension/rpc.ts +31 -2
- package/src/extension/schemas.ts +29 -3
- package/src/extension/tool-description.ts +4 -2
- package/src/intercom/intercom-bridge.ts +1 -1
- package/src/intercom/native-supervisor-channel.ts +45 -6
- package/src/intercom/result-intercom.ts +7 -0
- package/src/runs/background/async-execution.ts +158 -17
- package/src/runs/background/async-job-tracker.ts +4 -0
- package/src/runs/background/async-resume.ts +47 -8
- package/src/runs/background/async-status.ts +94 -3
- package/src/runs/background/chain-append.ts +2 -0
- package/src/runs/background/completion-batcher.ts +6 -4
- package/src/runs/background/completion-dedupe.ts +2 -11
- package/src/runs/background/fleet-view.ts +9 -4
- package/src/runs/background/notify.ts +132 -120
- package/src/runs/background/process-terminal.ts +280 -0
- package/src/runs/background/result-watcher.ts +138 -78
- package/src/runs/background/run-status.ts +10 -2
- package/src/runs/background/scheduled-runs.ts +6 -1
- package/src/runs/background/stale-run-reconciler.ts +6 -0
- package/src/runs/background/subagent-runner.ts +406 -54
- package/src/runs/background/subagent-wait.ts +130 -4
- package/src/runs/background/wait-tool.ts +2 -2
- package/src/runs/foreground/chain-execution.ts +181 -111
- package/src/runs/foreground/execution.ts +147 -47
- package/src/runs/foreground/foreground-control.ts +90 -0
- package/src/runs/foreground/subagent-executor.ts +426 -165
- package/src/runs/shared/acceptance.ts +94 -41
- package/src/runs/shared/agent-contract.ts +38 -0
- package/src/runs/shared/capability-ceiling.ts +177 -0
- package/src/runs/shared/child-protocol.ts +1 -1
- package/src/runs/shared/completion-guard.ts +36 -5
- package/src/runs/shared/context-mode.ts +44 -0
- package/src/runs/shared/dynamic-fanout.ts +5 -5
- package/src/runs/shared/long-running-guard.ts +4 -0
- package/src/runs/shared/mcp-direct-tool-allowlist.ts +12 -6
- package/src/runs/shared/nested-events.ts +35 -3
- package/src/runs/shared/parallel-handoff.ts +154 -0
- package/src/runs/shared/parallel-utils.ts +11 -0
- package/src/runs/shared/pi-args.ts +148 -56
- package/src/runs/shared/run-history.ts +90 -5
- package/src/runs/shared/session-lease.ts +25 -5
- package/src/runs/shared/structured-output.ts +112 -7
- package/src/runs/shared/subagent-control.ts +4 -0
- package/src/runs/shared/subagent-prompt-runtime.ts +31 -19
- package/src/runs/shared/task-intent.ts +10 -5
- package/src/runs/shared/tool-availability.ts +21 -3
- package/src/runs/shared/tool-budget.ts +11 -5
- package/src/runs/shared/turn-budget.ts +2 -1
- package/src/runs/shared/worktree.ts +63 -14
- package/src/shared/accessible-dir.ts +25 -0
- package/src/shared/artifacts.ts +37 -7
- package/src/shared/atomic-json.ts +14 -42
- package/src/shared/child-transcript.ts +52 -0
- package/src/shared/file-system-retry.ts +47 -0
- package/src/shared/launch-contract.ts +123 -0
- package/src/shared/settings.ts +9 -1
- package/src/shared/types.ts +314 -28
- package/src/shared/utils.ts +17 -42
- package/src/slash/delegation-adapters.ts +153 -6
- package/src/slash/delegation-json.ts +108 -0
- package/src/slash/delegation-request.ts +182 -36
- package/src/slash/prompt-template-bridge.ts +222 -37
- package/src/slash/selector.ts +147 -0
- package/src/slash/slash-commands.ts +15 -6
- package/src/slash/slash-live-state.ts +2 -2
- package/src/slash/subagents-admin.ts +42 -42
- package/src/tui/fleet-status.ts +362 -0
- package/src/tui/fleet-transcript.ts +472 -0
- package/src/tui/fleet.ts +318 -59
- package/src/tui/render.ts +17 -15
- package/src/watchdog/change-signature.ts +105 -12
- package/src/watchdog/review.ts +7 -2
- package/src/watchdog/runtime.ts +5 -3
- package/src/slash/subagents-editor.ts +0 -86
package/src/agents/agents.ts
CHANGED
|
@@ -35,6 +35,7 @@ export interface AgentMemoryConfig {
|
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
export const BUILTIN_AGENT_NAMES = [
|
|
38
|
+
"advisor",
|
|
38
39
|
"context-builder",
|
|
39
40
|
"delegate",
|
|
40
41
|
"oracle",
|
|
@@ -72,6 +73,7 @@ export interface BuiltinAgentOverrideBase {
|
|
|
72
73
|
skillPath?: string[];
|
|
73
74
|
tools?: string[];
|
|
74
75
|
mcpDirectTools?: string[];
|
|
76
|
+
extensions?: string[];
|
|
75
77
|
subagentOnlyExtensions?: string[];
|
|
76
78
|
completionGuard?: boolean;
|
|
77
79
|
toolBudget?: ToolBudgetConfig;
|
|
@@ -90,6 +92,7 @@ interface BuiltinAgentOverrideConfig {
|
|
|
90
92
|
systemPrompt?: string;
|
|
91
93
|
skills?: string[] | false;
|
|
92
94
|
tools?: string[] | false;
|
|
95
|
+
extensions?: string[] | false;
|
|
93
96
|
subagentOnlyExtensions?: string[] | false;
|
|
94
97
|
completionGuard?: boolean;
|
|
95
98
|
toolBudget?: ToolBudgetConfig | false;
|
|
@@ -133,6 +136,7 @@ export interface AgentConfig {
|
|
|
133
136
|
skills?: string[];
|
|
134
137
|
skillPath?: string[];
|
|
135
138
|
extensions?: string[];
|
|
139
|
+
extensionsFromDefault?: boolean;
|
|
136
140
|
subagentOnlyExtensions?: string[];
|
|
137
141
|
output?: string;
|
|
138
142
|
defaultReads?: string[];
|
|
@@ -151,6 +155,8 @@ export interface AgentConfig {
|
|
|
151
155
|
interface SubagentSettings {
|
|
152
156
|
overrides: Record<string, BuiltinAgentOverrideConfig>;
|
|
153
157
|
defaultModel?: string;
|
|
158
|
+
defaultThinking?: string;
|
|
159
|
+
defaultExtensions?: string[];
|
|
154
160
|
disableBuiltins?: boolean;
|
|
155
161
|
disableThinking?: boolean;
|
|
156
162
|
modelScope?: ModelScopeConfig;
|
|
@@ -476,7 +482,7 @@ function splitToolList(rawTools: string[] | undefined): { tools?: string[]; mcpD
|
|
|
476
482
|
}
|
|
477
483
|
}
|
|
478
484
|
return {
|
|
479
|
-
...(
|
|
485
|
+
...(rawTools !== undefined ? { tools } : {}),
|
|
480
486
|
...(mcpDirectTools.length > 0 ? { mcpDirectTools } : {}),
|
|
481
487
|
};
|
|
482
488
|
}
|
|
@@ -515,6 +521,7 @@ function cloneOverrideBase(agent: AgentConfig): BuiltinAgentOverrideBase {
|
|
|
515
521
|
skillPath: agent.skillPath ? [...agent.skillPath] : undefined,
|
|
516
522
|
tools: agent.tools ? [...agent.tools] : undefined,
|
|
517
523
|
mcpDirectTools: agent.mcpDirectTools ? [...agent.mcpDirectTools] : undefined,
|
|
524
|
+
extensions: agent.extensionsFromDefault ? undefined : agent.extensions ? [...agent.extensions] : undefined,
|
|
518
525
|
subagentOnlyExtensions: agent.subagentOnlyExtensions ? [...agent.subagentOnlyExtensions] : undefined,
|
|
519
526
|
completionGuard: agent.completionGuard,
|
|
520
527
|
toolBudget: agent.toolBudget,
|
|
@@ -537,6 +544,7 @@ function cloneOverrideValue(override: BuiltinAgentOverrideConfig): BuiltinAgentO
|
|
|
537
544
|
...(override.systemPrompt !== undefined ? { systemPrompt: override.systemPrompt } : {}),
|
|
538
545
|
...(override.skills !== undefined ? { skills: override.skills === false ? false : [...override.skills] } : {}),
|
|
539
546
|
...(override.tools !== undefined ? { tools: override.tools === false ? false : [...override.tools] } : {}),
|
|
547
|
+
...(override.extensions !== undefined ? { extensions: override.extensions === false ? false : [...override.extensions] } : {}),
|
|
540
548
|
...(override.subagentOnlyExtensions !== undefined ? { subagentOnlyExtensions: override.subagentOnlyExtensions === false ? false : [...override.subagentOnlyExtensions] } : {}),
|
|
541
549
|
...(override.completionGuard !== undefined ? { completionGuard: override.completionGuard } : {}),
|
|
542
550
|
...(override.toolBudget !== undefined ? { toolBudget: override.toolBudget === false ? false : { ...override.toolBudget, ...(Array.isArray(override.toolBudget.block) ? { block: [...override.toolBudget.block] } : {}) } } : {}),
|
|
@@ -716,6 +724,9 @@ function parseBuiltinOverrideEntry(
|
|
|
716
724
|
const tools = parseOverrideStringArrayOrFalse(input.tools, { filePath, name, field: "tools" });
|
|
717
725
|
if (tools !== undefined) override.tools = tools;
|
|
718
726
|
|
|
727
|
+
const extensions = parseOverrideStringArrayOrFalse(input.extensions, { filePath, name, field: "extensions" });
|
|
728
|
+
if (extensions !== undefined) override.extensions = extensions;
|
|
729
|
+
|
|
719
730
|
const subagentOnlyExtensions = parseOverrideStringArrayOrFalse(input.subagentOnlyExtensions, { filePath, name, field: "subagentOnlyExtensions" });
|
|
720
731
|
if (subagentOnlyExtensions !== undefined) override.subagentOnlyExtensions = subagentOnlyExtensions;
|
|
721
732
|
|
|
@@ -753,18 +764,34 @@ function readSubagentSettings(filePath: string | null): SubagentSettings {
|
|
|
753
764
|
throw new Error(`Subagent settings in '${filePath}' have invalid 'defaultModel'; expected a non-empty string.`);
|
|
754
765
|
}
|
|
755
766
|
}
|
|
767
|
+
let defaultThinking: string | undefined;
|
|
768
|
+
if ("defaultThinking" in subagentsObject) {
|
|
769
|
+
if (typeof subagentsObject.defaultThinking === "string" && subagentsObject.defaultThinking.trim()) {
|
|
770
|
+
defaultThinking = subagentsObject.defaultThinking.trim();
|
|
771
|
+
} else {
|
|
772
|
+
throw new Error(`Subagent settings in '${filePath}' have invalid 'defaultThinking'; expected a non-empty string.`);
|
|
773
|
+
}
|
|
774
|
+
}
|
|
775
|
+
let defaultExtensions: string[] | undefined;
|
|
776
|
+
if ("defaultExtensions" in subagentsObject) {
|
|
777
|
+
if (!Array.isArray(subagentsObject.defaultExtensions)
|
|
778
|
+
|| subagentsObject.defaultExtensions.some((item) => typeof item !== "string" || !item.trim())) {
|
|
779
|
+
throw new Error(`Subagent settings in '${filePath}' have invalid 'defaultExtensions'; expected an array of non-empty strings.`);
|
|
780
|
+
}
|
|
781
|
+
defaultExtensions = subagentsObject.defaultExtensions.map((item) => item.trim());
|
|
782
|
+
}
|
|
756
783
|
const modelScope = parseModelScopeConfig(subagentsObject.modelScope, { filePath });
|
|
757
784
|
|
|
758
785
|
const parsed: Record<string, BuiltinAgentOverrideConfig> = {};
|
|
759
786
|
const agentOverrides = subagentsObject.agentOverrides;
|
|
760
787
|
if (!agentOverrides || typeof agentOverrides !== "object" || Array.isArray(agentOverrides)) {
|
|
761
|
-
return { overrides: parsed, defaultModel, disableBuiltins, disableThinking, modelScope };
|
|
788
|
+
return { overrides: parsed, defaultModel, defaultThinking, defaultExtensions, disableBuiltins, disableThinking, modelScope };
|
|
762
789
|
}
|
|
763
790
|
for (const [name, value] of Object.entries(agentOverrides)) {
|
|
764
791
|
const override = parseBuiltinOverrideEntry(name, value, filePath);
|
|
765
792
|
if (override) parsed[name] = override;
|
|
766
793
|
}
|
|
767
|
-
return { overrides: parsed, defaultModel, disableBuiltins, disableThinking, modelScope };
|
|
794
|
+
return { overrides: parsed, defaultModel, defaultThinking, defaultExtensions, disableBuiltins, disableThinking, modelScope };
|
|
768
795
|
}
|
|
769
796
|
|
|
770
797
|
function resolveSubagentDefaultModel(
|
|
@@ -792,6 +819,58 @@ function applySubagentDefaultModel(agents: AgentConfig[], defaultModel: AgentMod
|
|
|
792
819
|
});
|
|
793
820
|
}
|
|
794
821
|
|
|
822
|
+
function resolveSubagentDefaultThinking(
|
|
823
|
+
userSettings: SubagentSettings,
|
|
824
|
+
projectSettings: SubagentSettings,
|
|
825
|
+
projectSettingsPath: string | null,
|
|
826
|
+
): string | undefined {
|
|
827
|
+
if (projectSettingsPath && projectSettings.defaultThinking !== undefined) return projectSettings.defaultThinking;
|
|
828
|
+
return userSettings.defaultThinking;
|
|
829
|
+
}
|
|
830
|
+
|
|
831
|
+
function applySubagentDefaultThinking(agents: AgentConfig[], defaultThinking: string | undefined): AgentConfig[] {
|
|
832
|
+
if (defaultThinking === undefined) return agents;
|
|
833
|
+
return agents.map((agent) => {
|
|
834
|
+
if (agent.thinking !== undefined) return agent;
|
|
835
|
+
const next = { ...agent, thinking: defaultThinking };
|
|
836
|
+
const frontmatterFields = agentFrontmatterFields.get(agent);
|
|
837
|
+
if (frontmatterFields) agentFrontmatterFields.set(next, frontmatterFields);
|
|
838
|
+
return next;
|
|
839
|
+
});
|
|
840
|
+
}
|
|
841
|
+
|
|
842
|
+
function resolveSubagentDefaultExtensions(
|
|
843
|
+
userSettings: SubagentSettings,
|
|
844
|
+
projectSettings: SubagentSettings,
|
|
845
|
+
projectSettingsPath: string | null,
|
|
846
|
+
): string[] | undefined {
|
|
847
|
+
if (projectSettingsPath && projectSettings.defaultExtensions !== undefined) return projectSettings.defaultExtensions;
|
|
848
|
+
return userSettings.defaultExtensions;
|
|
849
|
+
}
|
|
850
|
+
|
|
851
|
+
function applySubagentDefaultExtensions(agents: AgentConfig[], defaultExtensions: string[] | undefined): AgentConfig[] {
|
|
852
|
+
if (defaultExtensions === undefined) return agents;
|
|
853
|
+
return agents.map((agent) => {
|
|
854
|
+
if (agent.extensions !== undefined) return agent;
|
|
855
|
+
const next = { ...agent, extensions: [...defaultExtensions], extensionsFromDefault: true };
|
|
856
|
+
const frontmatterFields = agentFrontmatterFields.get(agent);
|
|
857
|
+
if (frontmatterFields) agentFrontmatterFields.set(next, frontmatterFields);
|
|
858
|
+
return next;
|
|
859
|
+
});
|
|
860
|
+
}
|
|
861
|
+
|
|
862
|
+
function applySubagentDefaults(
|
|
863
|
+
agents: AgentConfig[],
|
|
864
|
+
defaultModel: AgentModelSourceInfo | undefined,
|
|
865
|
+
defaultThinking: string | undefined,
|
|
866
|
+
defaultExtensions: string[] | undefined,
|
|
867
|
+
): AgentConfig[] {
|
|
868
|
+
return applySubagentDefaultExtensions(
|
|
869
|
+
applySubagentDefaultThinking(applySubagentDefaultModel(agents, defaultModel), defaultThinking),
|
|
870
|
+
defaultExtensions,
|
|
871
|
+
);
|
|
872
|
+
}
|
|
873
|
+
|
|
795
874
|
function applyBuiltinOverride(
|
|
796
875
|
agent: AgentConfig,
|
|
797
876
|
override: BuiltinAgentOverrideConfig,
|
|
@@ -820,6 +899,7 @@ function applyBuiltinOverride(
|
|
|
820
899
|
next.tools = tools;
|
|
821
900
|
next.mcpDirectTools = mcpDirectTools;
|
|
822
901
|
}
|
|
902
|
+
if (override.extensions !== undefined) next.extensions = override.extensions === false ? undefined : [...override.extensions];
|
|
823
903
|
if (override.subagentOnlyExtensions !== undefined) {
|
|
824
904
|
next.subagentOnlyExtensions = override.subagentOnlyExtensions === false ? undefined : [...override.subagentOnlyExtensions];
|
|
825
905
|
}
|
|
@@ -963,6 +1043,9 @@ function applyCustomAgentOverride(
|
|
|
963
1043
|
target.mcpDirectTools = mcpDirectTools;
|
|
964
1044
|
anyFilled = true;
|
|
965
1045
|
}
|
|
1046
|
+
if (override.extensions !== undefined) {
|
|
1047
|
+
fill("extensions", ["extensions"], override.extensions === false ? undefined : [...override.extensions]);
|
|
1048
|
+
}
|
|
966
1049
|
if (override.subagentOnlyExtensions !== undefined) {
|
|
967
1050
|
fill(
|
|
968
1051
|
"subagentOnlyExtensions",
|
|
@@ -1008,7 +1091,7 @@ function applyCustomAgentOverrides(
|
|
|
1008
1091
|
|
|
1009
1092
|
export function buildBuiltinOverrideConfig(
|
|
1010
1093
|
base: BuiltinAgentOverrideBase,
|
|
1011
|
-
draft: Pick<AgentConfig, "model" | "fallbackModels" | "thinking" | "systemPromptMode" | "inheritProjectContext" | "inheritSkills" | "defaultContext" | "acceptanceRole" | "disabled" | "systemPrompt" | "skills" | "tools" | "mcpDirectTools" | "subagentOnlyExtensions" | "completionGuard" | "toolBudget">,
|
|
1094
|
+
draft: Pick<AgentConfig, "model" | "fallbackModels" | "thinking" | "systemPromptMode" | "inheritProjectContext" | "inheritSkills" | "defaultContext" | "acceptanceRole" | "disabled" | "systemPrompt" | "skills" | "tools" | "mcpDirectTools" | "extensions" | "subagentOnlyExtensions" | "completionGuard" | "toolBudget">,
|
|
1012
1095
|
): BuiltinAgentOverrideConfig | undefined {
|
|
1013
1096
|
const override: BuiltinAgentOverrideConfig = {};
|
|
1014
1097
|
|
|
@@ -1027,6 +1110,7 @@ export function buildBuiltinOverrideConfig(
|
|
|
1027
1110
|
const baseTools = joinToolList(base);
|
|
1028
1111
|
const draftTools = joinToolList(draft);
|
|
1029
1112
|
if (!arraysEqual(draftTools, baseTools)) override.tools = draftTools ? [...draftTools] : false;
|
|
1113
|
+
if (!arraysEqual(draft.extensions, base.extensions)) override.extensions = draft.extensions ? [...draft.extensions] : false;
|
|
1030
1114
|
if (!arraysEqual(draft.subagentOnlyExtensions, base.subagentOnlyExtensions)) {
|
|
1031
1115
|
override.subagentOnlyExtensions = draft.subagentOnlyExtensions ? [...draft.subagentOnlyExtensions] : false;
|
|
1032
1116
|
}
|
|
@@ -1159,7 +1243,19 @@ export function removeBuiltinAgentOverrideFields(
|
|
|
1159
1243
|
return { path: filePath, removed: true };
|
|
1160
1244
|
}
|
|
1161
1245
|
|
|
1162
|
-
|
|
1246
|
+
const DISCOVERY_PRUNED_DIR_NAMES = new Set([".git", "node_modules"]);
|
|
1247
|
+
|
|
1248
|
+
function isDiscoveryNestedProjectRoot(dir: string): boolean {
|
|
1249
|
+
return isDirectory(getProjectConfigDir(dir)) || isDirectory(path.join(dir, ".agents"));
|
|
1250
|
+
}
|
|
1251
|
+
|
|
1252
|
+
function shouldPruneDiscoveryDir(rootDir: string, dir: string, dirName: string): boolean {
|
|
1253
|
+
if (DISCOVERY_PRUNED_DIR_NAMES.has(dirName)) return true;
|
|
1254
|
+
if (fs.existsSync(path.join(dir, ".git"))) return true;
|
|
1255
|
+
return path.resolve(dir) !== path.resolve(rootDir) && isDiscoveryNestedProjectRoot(dir);
|
|
1256
|
+
}
|
|
1257
|
+
|
|
1258
|
+
function listFilesRecursive(dir: string, predicate: (fileName: string) => boolean, rootDir = dir): string[] {
|
|
1163
1259
|
const files: string[] = [];
|
|
1164
1260
|
if (!fs.existsSync(dir)) return files;
|
|
1165
1261
|
|
|
@@ -1173,7 +1269,9 @@ function listFilesRecursive(dir: string, predicate: (fileName: string) => boolea
|
|
|
1173
1269
|
for (const entry of entries) {
|
|
1174
1270
|
const filePath = path.join(dir, entry.name);
|
|
1175
1271
|
if (entry.isDirectory()) {
|
|
1176
|
-
|
|
1272
|
+
if (!shouldPruneDiscoveryDir(rootDir, filePath, entry.name)) {
|
|
1273
|
+
files.push(...listFilesRecursive(filePath, predicate, rootDir));
|
|
1274
|
+
}
|
|
1177
1275
|
continue;
|
|
1178
1276
|
}
|
|
1179
1277
|
if (!entry.isFile() && !entry.isSymbolicLink()) continue;
|
|
@@ -1233,7 +1331,9 @@ function loadAgentsFromDir(dir: string, source: AgentSource): AgentConfig[] {
|
|
|
1233
1331
|
const runtimeName = buildRuntimeName(localName, packageName);
|
|
1234
1332
|
|
|
1235
1333
|
const rawTools = parseFrontmatterList(frontmatter.tools);
|
|
1236
|
-
const
|
|
1334
|
+
const parsedTools = splitToolList(rawTools);
|
|
1335
|
+
const tools = parsedTools.tools ?? [];
|
|
1336
|
+
const mcpDirectTools = parsedTools.mcpDirectTools ?? [];
|
|
1237
1337
|
const defaultReads = parseFrontmatterList(frontmatter.defaultReads);
|
|
1238
1338
|
const skillStr = frontmatter.skill || frontmatter.skills;
|
|
1239
1339
|
const skills = parseFrontmatterList(skillStr);
|
|
@@ -1315,7 +1415,7 @@ function loadAgentsFromDir(dir: string, source: AgentSource): AgentConfig[] {
|
|
|
1315
1415
|
localName,
|
|
1316
1416
|
packageName,
|
|
1317
1417
|
description: frontmatter.description,
|
|
1318
|
-
tools:
|
|
1418
|
+
tools: rawTools !== undefined ? tools : undefined,
|
|
1319
1419
|
mcpDirectTools: mcpDirectTools.length > 0 ? mcpDirectTools : undefined,
|
|
1320
1420
|
model: frontmatter.model,
|
|
1321
1421
|
fallbackModels: fallbackModels && fallbackModels.length > 0 ? fallbackModels : undefined,
|
|
@@ -1443,6 +1543,8 @@ export function discoverAgents(cwd: string, scope: AgentScope): AgentDiscoveryRe
|
|
|
1443
1543
|
const userSettings = scope === "project" ? EMPTY_SUBAGENT_SETTINGS : readSubagentSettings(userSettingsPath);
|
|
1444
1544
|
const projectSettings = scope === "user" ? EMPTY_SUBAGENT_SETTINGS : readSubagentSettings(projectSettingsPath);
|
|
1445
1545
|
const defaultModel = resolveSubagentDefaultModel(userSettings, projectSettings, userSettingsPath, projectSettingsPath);
|
|
1546
|
+
const defaultThinking = resolveSubagentDefaultThinking(userSettings, projectSettings, projectSettingsPath);
|
|
1547
|
+
const defaultExtensions = resolveSubagentDefaultExtensions(userSettings, projectSettings, projectSettingsPath);
|
|
1446
1548
|
const modelScope = projectSettings.modelScope ?? userSettings.modelScope;
|
|
1447
1549
|
const packageSubagentPaths = collectPackageSubagentPaths(cwd, {
|
|
1448
1550
|
includeUser: scope !== "project",
|
|
@@ -1450,7 +1552,7 @@ export function discoverAgents(cwd: string, scope: AgentScope): AgentDiscoveryRe
|
|
|
1450
1552
|
});
|
|
1451
1553
|
|
|
1452
1554
|
const builtinAgents = applyBuiltinOverrides(
|
|
1453
|
-
|
|
1555
|
+
applySubagentDefaults(loadAgentsFromDir(BUILTIN_AGENTS_DIR, "builtin"), defaultModel, defaultThinking, defaultExtensions),
|
|
1454
1556
|
userSettings,
|
|
1455
1557
|
projectSettings,
|
|
1456
1558
|
userSettingsPath,
|
|
@@ -1461,7 +1563,7 @@ export function discoverAgents(cwd: string, scope: AgentScope): AgentDiscoveryRe
|
|
|
1461
1563
|
const userAgentsOld = scope === "project" ? [] : loadAgentsFromDir(userDirOld, "user");
|
|
1462
1564
|
const userAgentsNew = scope === "project" ? [] : loadAgentsFromDir(userDirNew, "user");
|
|
1463
1565
|
const userAgents = applyCustomAgentOverrides(
|
|
1464
|
-
|
|
1566
|
+
applySubagentDefaults([...userAgentsExtra, ...userAgentsOld, ...userAgentsNew], defaultModel, defaultThinking, defaultExtensions),
|
|
1465
1567
|
userSettings,
|
|
1466
1568
|
projectSettings,
|
|
1467
1569
|
userSettingsPath,
|
|
@@ -1469,14 +1571,14 @@ export function discoverAgents(cwd: string, scope: AgentScope): AgentDiscoveryRe
|
|
|
1469
1571
|
);
|
|
1470
1572
|
|
|
1471
1573
|
const projectAgents = applyCustomAgentOverrides(
|
|
1472
|
-
|
|
1574
|
+
applySubagentDefaults(scope === "user" ? [] : projectAgentDirs.flatMap((dir) => loadAgentsFromDir(dir, "project")), defaultModel, defaultThinking, defaultExtensions),
|
|
1473
1575
|
userSettings,
|
|
1474
1576
|
projectSettings,
|
|
1475
1577
|
userSettingsPath,
|
|
1476
1578
|
projectSettingsPath,
|
|
1477
1579
|
);
|
|
1478
1580
|
const packageAgents = applyCustomAgentOverrides(
|
|
1479
|
-
|
|
1581
|
+
applySubagentDefaults(packageSubagentPaths.agents.flatMap((dir) => loadAgentsFromDir(dir, "package")), defaultModel, defaultThinking, defaultExtensions),
|
|
1480
1582
|
userSettings,
|
|
1481
1583
|
projectSettings,
|
|
1482
1584
|
userSettingsPath,
|
|
@@ -1512,21 +1614,23 @@ export function discoverAgentsAll(cwd: string): {
|
|
|
1512
1614
|
const userSettings = readSubagentSettings(userSettingsPath);
|
|
1513
1615
|
const projectSettings = readSubagentSettings(projectSettingsPath);
|
|
1514
1616
|
const defaultModel = resolveSubagentDefaultModel(userSettings, projectSettings, userSettingsPath, projectSettingsPath);
|
|
1617
|
+
const defaultThinking = resolveSubagentDefaultThinking(userSettings, projectSettings, projectSettingsPath);
|
|
1618
|
+
const defaultExtensions = resolveSubagentDefaultExtensions(userSettings, projectSettings, projectSettingsPath);
|
|
1515
1619
|
const packageSubagentPaths = collectPackageSubagentPaths(cwd);
|
|
1516
1620
|
|
|
1517
1621
|
const builtin = applyBuiltinOverrides(
|
|
1518
|
-
|
|
1622
|
+
applySubagentDefaults(loadAgentsFromDir(BUILTIN_AGENTS_DIR, "builtin"), defaultModel, defaultThinking, defaultExtensions),
|
|
1519
1623
|
userSettings,
|
|
1520
1624
|
projectSettings,
|
|
1521
1625
|
userSettingsPath,
|
|
1522
1626
|
projectSettingsPath,
|
|
1523
1627
|
);
|
|
1524
1628
|
const user = applyCustomAgentOverrides(
|
|
1525
|
-
|
|
1629
|
+
applySubagentDefaults([
|
|
1526
1630
|
...extraUserAgentDirs().flatMap((dir) => loadAgentsFromDir(dir, "user")),
|
|
1527
1631
|
...loadAgentsFromDir(userDirOld, "user"),
|
|
1528
1632
|
...loadAgentsFromDir(userDirNew, "user"),
|
|
1529
|
-
], defaultModel),
|
|
1633
|
+
], defaultModel, defaultThinking, defaultExtensions),
|
|
1530
1634
|
userSettings,
|
|
1531
1635
|
projectSettings,
|
|
1532
1636
|
userSettingsPath,
|
|
@@ -1539,7 +1643,7 @@ export function discoverAgentsAll(cwd: string): {
|
|
|
1539
1643
|
}
|
|
1540
1644
|
}
|
|
1541
1645
|
const packageAgents = applyCustomAgentOverrides(
|
|
1542
|
-
|
|
1646
|
+
applySubagentDefaults(Array.from(packageMap.values()), defaultModel, defaultThinking, defaultExtensions),
|
|
1543
1647
|
userSettings,
|
|
1544
1648
|
projectSettings,
|
|
1545
1649
|
userSettingsPath,
|
|
@@ -1552,7 +1656,7 @@ export function discoverAgentsAll(cwd: string): {
|
|
|
1552
1656
|
}
|
|
1553
1657
|
}
|
|
1554
1658
|
const project = applyCustomAgentOverrides(
|
|
1555
|
-
|
|
1659
|
+
applySubagentDefaults(Array.from(projectMap.values()), defaultModel, defaultThinking, defaultExtensions),
|
|
1556
1660
|
userSettings,
|
|
1557
1661
|
projectSettings,
|
|
1558
1662
|
userSettingsPath,
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export {
|
|
2
|
+
SUBAGENT_CAPABILITY_CEILING_ENV,
|
|
3
|
+
SUBAGENT_CAPABILITY_CEILING_REGISTRY_KEY,
|
|
4
|
+
SUBAGENT_CAPABILITY_CEILING_VERSION,
|
|
5
|
+
decodeSubagentCapabilityCeiling,
|
|
6
|
+
encodeSubagentCapabilityCeiling,
|
|
7
|
+
intersectSubagentCapabilityCeilings,
|
|
8
|
+
parseSubagentCapabilityCeiling,
|
|
9
|
+
registerSubagentCapabilityCeiling,
|
|
10
|
+
resolveCurrentSubagentCapabilityCeiling,
|
|
11
|
+
resolveSubagentCapabilityCeiling,
|
|
12
|
+
type RegisterSubagentCapabilityCeilingOptions,
|
|
13
|
+
type ResolvedSubagentCapabilityCeiling,
|
|
14
|
+
type SubagentCapabilityCeiling,
|
|
15
|
+
type SubagentCapabilityCeilingHandle,
|
|
16
|
+
type SubagentCapabilityAudit,
|
|
17
|
+
} from "../runs/shared/capability-ceiling.ts";
|
package/src/api/delegation.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export const SUBAGENT_DELEGATION_PROTOCOL_VERSION = 1 as const;
|
|
2
|
+
export const SUBAGENT_DELEGATION_V2_PROTOCOL_VERSION = 2 as const;
|
|
2
3
|
|
|
3
4
|
// This is the established extension-to-extension transport. The public API
|
|
4
5
|
// intentionally reuses it instead of adding a second event protocol.
|
|
@@ -19,6 +20,37 @@ export interface SubagentDelegationToolBudget {
|
|
|
19
20
|
block?: string[] | "*";
|
|
20
21
|
}
|
|
21
22
|
|
|
23
|
+
export interface SubagentDelegationAgentContract {
|
|
24
|
+
version: 1;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export type SubagentDelegationJsonSchemaObject = Record<string, unknown>;
|
|
28
|
+
|
|
29
|
+
export interface SubagentDelegationExecutionResult {
|
|
30
|
+
status: "completed" | "failed" | "paused" | "stopped" | "detached";
|
|
31
|
+
success: boolean;
|
|
32
|
+
exitCode: number;
|
|
33
|
+
error?: string;
|
|
34
|
+
interrupted?: boolean;
|
|
35
|
+
timedOut?: boolean;
|
|
36
|
+
stopped?: boolean;
|
|
37
|
+
detached?: boolean;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export interface SubagentDelegationReviewResult {
|
|
41
|
+
status: "not-requested" | "review-required" | "reviewed" | "blockers";
|
|
42
|
+
findings?: Array<{ severity: "blocker" | "non-blocking"; file?: string; issue: string; rationale: string }>;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export interface SubagentDelegationEffectsResult {
|
|
46
|
+
fileMutation?: {
|
|
47
|
+
status: "not-requested" | "not-applicable" | "observed" | "missing";
|
|
48
|
+
expected: boolean;
|
|
49
|
+
attempted: boolean;
|
|
50
|
+
message?: string;
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
|
|
22
54
|
export type SubagentDelegationAcceptanceEvidence =
|
|
23
55
|
| "changed-files"
|
|
24
56
|
| "tests-added"
|
|
@@ -87,6 +119,8 @@ export interface SubagentDelegationRequest {
|
|
|
87
119
|
skill?: string | string[] | boolean;
|
|
88
120
|
output?: string | boolean;
|
|
89
121
|
outputMode?: "inline" | "file-only";
|
|
122
|
+
outputSchema?: SubagentDelegationJsonSchemaObject;
|
|
123
|
+
agentContract?: SubagentDelegationAgentContract;
|
|
90
124
|
acceptance?: SubagentDelegationAcceptance;
|
|
91
125
|
artifacts?: boolean;
|
|
92
126
|
}
|
|
@@ -116,6 +150,7 @@ export type SubagentDelegationStatus =
|
|
|
116
150
|
| "interrupted"
|
|
117
151
|
| "turn_budget_exhausted"
|
|
118
152
|
| "tool_budget_exhausted"
|
|
153
|
+
| "structured_output_failed"
|
|
119
154
|
| "acceptance_failed"
|
|
120
155
|
| "invalid_request"
|
|
121
156
|
| "unavailable_context";
|
|
@@ -127,12 +162,14 @@ export type SubagentDelegationAcceptanceStatus =
|
|
|
127
162
|
| "attested"
|
|
128
163
|
| "checked"
|
|
129
164
|
| "verified"
|
|
165
|
+
| "review-required"
|
|
130
166
|
| "reviewed"
|
|
131
167
|
| "accepted"
|
|
132
168
|
| "rejected";
|
|
133
169
|
|
|
134
170
|
export interface SubagentDelegationAcceptanceResult {
|
|
135
171
|
status: SubagentDelegationAcceptanceStatus;
|
|
172
|
+
evidenceStatus: Exclude<SubagentDelegationAcceptanceStatus, "review-required" | "reviewed" | "accepted">;
|
|
136
173
|
explicit: boolean;
|
|
137
174
|
}
|
|
138
175
|
|
|
@@ -144,10 +181,13 @@ export interface SubagentDelegationResponse extends SubagentDelegationStarted {
|
|
|
144
181
|
agent?: string;
|
|
145
182
|
model?: string;
|
|
146
183
|
exitCode?: number;
|
|
184
|
+
execution?: SubagentDelegationExecutionResult;
|
|
147
185
|
output?: string;
|
|
148
186
|
outputPath?: string;
|
|
149
187
|
sessionFile?: string;
|
|
150
188
|
acceptance?: SubagentDelegationAcceptanceResult;
|
|
189
|
+
review?: SubagentDelegationReviewResult;
|
|
190
|
+
effects?: SubagentDelegationEffectsResult;
|
|
151
191
|
turns?: number;
|
|
152
192
|
toolCount?: number;
|
|
153
193
|
durationMs?: number;
|
|
@@ -156,3 +196,90 @@ export interface SubagentDelegationResponse extends SubagentDelegationStarted {
|
|
|
156
196
|
}
|
|
157
197
|
|
|
158
198
|
export interface SubagentDelegationCancel extends SubagentDelegationStarted {}
|
|
199
|
+
|
|
200
|
+
export type SubagentDelegationV2Thinking = "off" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max";
|
|
201
|
+
|
|
202
|
+
export type SubagentDelegationV2ResultRequest =
|
|
203
|
+
| { kind: "text" }
|
|
204
|
+
| { kind: "structured"; schema: SubagentDelegationJsonSchemaObject };
|
|
205
|
+
|
|
206
|
+
export interface SubagentDelegationV2Request {
|
|
207
|
+
version: typeof SUBAGENT_DELEGATION_V2_PROTOCOL_VERSION;
|
|
208
|
+
requestId: string;
|
|
209
|
+
ownerRunId: string;
|
|
210
|
+
nodeId: string;
|
|
211
|
+
agent: string;
|
|
212
|
+
task: string;
|
|
213
|
+
context: "fresh" | "fork";
|
|
214
|
+
cwd: string;
|
|
215
|
+
model?: string;
|
|
216
|
+
thinking?: SubagentDelegationV2Thinking;
|
|
217
|
+
timeoutMs?: number;
|
|
218
|
+
turnBudget?: SubagentDelegationTurnBudget;
|
|
219
|
+
toolBudget?: SubagentDelegationToolBudget;
|
|
220
|
+
skill?: string | string[] | boolean;
|
|
221
|
+
artifacts?: boolean;
|
|
222
|
+
result: SubagentDelegationV2ResultRequest;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
export interface SubagentDelegationV2Started {
|
|
226
|
+
version: typeof SUBAGENT_DELEGATION_V2_PROTOCOL_VERSION;
|
|
227
|
+
requestId: string;
|
|
228
|
+
ownerRunId: string;
|
|
229
|
+
nodeId: string;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
export interface SubagentDelegationV2Update extends SubagentDelegationV2Started {
|
|
233
|
+
currentTool?: string;
|
|
234
|
+
currentToolArgs?: string;
|
|
235
|
+
recentOutput?: string;
|
|
236
|
+
recentOutputLines?: string[];
|
|
237
|
+
recentTools?: Array<{ tool: string; args: string }>;
|
|
238
|
+
model?: string;
|
|
239
|
+
toolCount?: number;
|
|
240
|
+
durationMs?: number;
|
|
241
|
+
tokens?: number;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
export type SubagentDelegationV2Status = SubagentDelegationStatus | "duplicate_node";
|
|
245
|
+
|
|
246
|
+
export type SubagentDelegationV2Value =
|
|
247
|
+
| { kind: "text"; text: string }
|
|
248
|
+
| { kind: "structured"; value: unknown };
|
|
249
|
+
|
|
250
|
+
export interface SubagentDelegationV2Usage {
|
|
251
|
+
input: number;
|
|
252
|
+
output: number;
|
|
253
|
+
cacheRead: number;
|
|
254
|
+
cacheWrite: number;
|
|
255
|
+
cost: number;
|
|
256
|
+
turns: number;
|
|
257
|
+
toolCalls: number;
|
|
258
|
+
durationMs: number;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
export interface SubagentDelegationV2TerminalResponse extends SubagentDelegationV2Started {
|
|
262
|
+
status: Exclude<SubagentDelegationV2Status, "invalid_request">;
|
|
263
|
+
error?: string;
|
|
264
|
+
runId?: string;
|
|
265
|
+
agent?: string;
|
|
266
|
+
model?: string;
|
|
267
|
+
thinking?: string;
|
|
268
|
+
exitCode?: number;
|
|
269
|
+
result?: SubagentDelegationV2Value;
|
|
270
|
+
usage?: SubagentDelegationV2Usage;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
/** A malformed V2 request can only be correlated by the valid identity fields it supplied. */
|
|
274
|
+
export interface SubagentDelegationV2InvalidResponse {
|
|
275
|
+
version: typeof SUBAGENT_DELEGATION_V2_PROTOCOL_VERSION;
|
|
276
|
+
requestId: string;
|
|
277
|
+
ownerRunId?: string;
|
|
278
|
+
nodeId?: string;
|
|
279
|
+
status: "invalid_request";
|
|
280
|
+
error?: string;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
export type SubagentDelegationV2Response = SubagentDelegationV2TerminalResponse | SubagentDelegationV2InvalidResponse;
|
|
284
|
+
|
|
285
|
+
export interface SubagentDelegationV2Cancel extends SubagentDelegationV2Started {}
|