@marcoscale98/pi-extensible-workflows 5.17.0-fork.1 → 6.2.1-fork.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 +145 -0
- package/README.md +2 -2
- package/dist/src/agent-execution.d.ts +43 -10
- package/dist/src/agent-execution.js +442 -162
- package/dist/src/background-widget.d.ts +5 -1
- package/dist/src/background-widget.js +5 -10
- package/dist/src/decoders.d.ts +2 -3
- package/dist/src/decoders.js +59 -37
- package/dist/src/execution.d.ts +6 -2
- package/dist/src/execution.js +48 -7
- package/dist/src/host-delivery.js +5 -8
- package/dist/src/host-navigator.js +5 -2
- package/dist/src/host-phases.d.ts +1 -0
- package/dist/src/host-recovery.d.ts +11 -8
- package/dist/src/host-recovery.js +14 -22
- package/dist/src/host-runtime.js +56 -5
- package/dist/src/host-view.d.ts +6 -1
- package/dist/src/host-view.js +46 -20
- package/dist/src/host.d.ts +2 -2
- package/dist/src/host.js +246 -118
- package/dist/src/index.d.ts +1 -2
- package/dist/src/index.js +1985 -1690
- package/dist/src/index.js.map +3 -3
- package/dist/src/paths.d.ts +8 -5
- package/dist/src/paths.js +24 -13
- package/dist/src/persistence.d.ts +1 -0
- package/dist/src/persistence.js +1 -0
- package/dist/src/pi-runtime-runner.js +4 -1
- package/dist/src/registry.d.ts +9 -7
- package/dist/src/registry.js +29 -71
- package/dist/src/runtime/agent-runner.d.ts +2 -0
- package/dist/src/script-tools.d.ts +27 -0
- package/dist/src/script-tools.js +87 -0
- package/dist/src/session-lease.d.ts +1 -1
- package/dist/src/session-lease.js +45 -11
- package/dist/src/settings.d.ts +19 -3
- package/dist/src/settings.js +63 -50
- package/dist/src/store.d.ts +3 -1
- package/dist/src/store.js +17 -1
- package/dist/src/trajectory.d.ts +12 -3
- package/dist/src/trajectory.js +32 -11
- package/dist/src/types.d.ts +129 -45
- package/dist/src/types.js +5 -8
- package/dist/src/utils.d.ts +21 -1
- package/dist/src/utils.js +46 -6
- package/dist/src/validation.d.ts +14 -3
- package/dist/src/validation.js +143 -87
- package/dist/starter/index.js +8 -11
- package/dist/starter/index.js.map +1 -1
- package/dist/starter/review-loop.d.ts +0 -13
- package/dist/starter/review-loop.js +8 -9
- package/dist/subagents/index.js +904 -956
- package/dist/subagents/index.js.map +3 -3
- package/dist/subagents/src/contracts.d.ts +48 -31
- package/dist/subagents/src/contracts.js +20 -9
- package/dist/subagents/src/index.d.ts +1 -1
- package/dist/subagents/src/index.js +14 -8
- package/dist/subagents/src/manager.js +52 -73
- package/dist/subagents/src/navigator.js +3 -14
- package/dist/subagents/src/view.d.ts +1 -1
- package/dist/subagents/src/view.js +15 -68
- package/dist/subagents/src/worktree.js +1 -1
- package/dist/trajectory/assets/index.html +35 -13
- package/dist/trajectory/index.js +576 -932
- package/dist/trajectory/index.js.map +3 -3
- package/dist/trajectory/src/assets/index.html +35 -13
- package/dist/trajectory/src/index.js +134 -104
- package/dist/trajectory/src/server.js +268 -27
- package/dist/trajectory/src/server.js.map +3 -3
- package/dist/trajectory/src/startup-mutex.d.ts +17 -0
- package/dist/trajectory/src/startup-mutex.js +172 -0
- package/examples/workflow-extension-template/README.md +4 -7
- package/examples/workflow-extension-template/extension.test.mjs +4 -8
- package/examples/workflow-extension-template/index.js +0 -3
- package/package.json +10 -10
- package/skills/pi-extensible-workflows/SKILL.md +12 -8
- package/src/agent-execution.ts +412 -164
- package/src/background-widget.ts +5 -11
- package/src/decoders.ts +51 -37
- package/src/execution.ts +46 -9
- package/src/host-delivery.ts +5 -8
- package/src/host-navigator.ts +4 -2
- package/src/host-phases.ts +1 -1
- package/src/host-recovery.ts +23 -28
- package/src/host-runtime.ts +44 -6
- package/src/host-view.ts +41 -16
- package/src/host.ts +229 -142
- package/src/index.ts +1 -2
- package/src/paths.ts +18 -9
- package/src/persistence.ts +1 -0
- package/src/pi-runtime-runner.ts +3 -1
- package/src/registry.ts +28 -64
- package/src/runtime/agent-runner.ts +2 -0
- package/src/script-tools.ts +76 -0
- package/src/session-lease.ts +34 -6
- package/src/settings.ts +56 -50
- package/src/store.ts +18 -2
- package/src/trajectory.ts +32 -15
- package/src/types.ts +82 -34
- package/src/utils.ts +42 -5
- package/src/validation.ts +121 -80
- package/starter/index.ts +0 -1
- package/starter/review-loop.ts +8 -9
- package/starter/roles/developer.md +0 -1
- package/starter/roles/oracle.md +0 -1
- package/starter/roles/researcher.md +0 -1
- package/starter/roles/reviewer.md +0 -1
- package/starter/roles/scout.md +0 -1
- package/subagents/README.md +10 -16
- package/subagents/src/contracts.ts +21 -11
- package/subagents/src/index.ts +17 -8
- package/subagents/src/manager.ts +48 -128
- package/subagents/src/navigator.ts +4 -13
- package/subagents/src/view.ts +16 -63
- package/subagents/src/worktree.ts +1 -1
- package/trajectory/src/assets/index.html +35 -13
- package/trajectory/src/index.ts +112 -91
- package/trajectory/src/server.ts +46 -10
- package/trajectory/src/startup-mutex.ts +127 -0
- package/dist/src/roles.d.ts +0 -70
- package/dist/src/roles.js +0 -325
- package/dist/starter/roles/developer.md +0 -6
- package/dist/starter/roles/oracle.md +0 -18
- package/dist/starter/roles/researcher.md +0 -20
- package/dist/starter/roles/reviewer.md +0 -19
- package/dist/starter/roles/scout.md +0 -18
- package/examples/workflow-extension-template/roles/reviewer.md +0 -4
- package/src/roles.ts +0 -326
package/subagents/src/index.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { join } from "node:path";
|
|
2
2
|
import { defineTool, getAgentDir, type AgentToolResult, type ExtensionAPI, type ExtensionContext, type ToolDefinition } from "@earendil-works/pi-coding-agent";
|
|
3
3
|
import { Value } from "typebox/value";
|
|
4
|
-
import { WorkflowError, loadingRegistry } from "../../src/index.js";
|
|
4
|
+
import { WorkflowError, loadCodemodeToolsSetting, loadingRegistry, reachableTools, workflowToolExposure, type JsonValue } from "../../src/index.js";
|
|
5
5
|
import { clearSubagentManager, setSubagentManager } from "../../src/subagent-manager-handle.js";
|
|
6
6
|
import type { SubagentIdRequest, SubagentInspectRequest, SubagentManager, SubagentManagerContext, SubagentNotification, SubagentsExtension, SubagentsExtensionOptions, SubagentRunRequest, SubagentStatus, SubagentSteerRequest } from "./contracts.js";
|
|
7
7
|
import { createSubagentManager } from "./manager.js";
|
|
@@ -9,10 +9,13 @@ import { registerSubagentNavigator } from "./navigator.js";
|
|
|
9
9
|
import { createSubagentBackgroundWidget, renderSubagentCall, renderSubagentControlCall, renderSubagentControlResult, renderSubagentInspectCall, renderSubagentInspectResult, renderSubagentResult } from "./view.js";
|
|
10
10
|
import {
|
|
11
11
|
normalizeSubagentRunRequest,
|
|
12
|
+
SUBAGENT_STATUS_OUTPUT,
|
|
12
13
|
SUBAGENTS_ID_PARAMETERS,
|
|
14
|
+
SUBAGENTS_INSPECT_OUTPUT,
|
|
13
15
|
SUBAGENTS_INSPECT_PARAMETERS,
|
|
14
16
|
SUBAGENTS_RETRY_PARAMETERS,
|
|
15
17
|
SUBAGENTS_RUN_PARAMETERS,
|
|
18
|
+
SUBAGENTS_STEER_OUTPUT,
|
|
16
19
|
SUBAGENTS_STEER_PARAMETERS,
|
|
17
20
|
SUBAGENTS_STOP_PARAMETERS,
|
|
18
21
|
} from "./contracts.js";
|
|
@@ -23,7 +26,7 @@ export { createSubagentManager, createUnavailableSubagentManager } from "./manag
|
|
|
23
26
|
export { createRunStoreWorktreeAdapter, defaultWorktreeHome } from "./worktree.js";
|
|
24
27
|
export type { SubagentWorktreeAdapter, SubagentWorktreeContext, SubagentWorktreeHandle, SubagentWorktreeRunStore } from "./worktree.js";
|
|
25
28
|
|
|
26
|
-
type SubagentsExtensionAPI = Pick<ExtensionAPI, "registerTool"> & Partial<Pick<ExtensionAPI, "getActiveTools" | "on" | "sendMessage" | "registerCommand" | "appendEntry" | "registerEntryRenderer">>;
|
|
29
|
+
type SubagentsExtensionAPI = Pick<ExtensionAPI, "registerTool"> & Partial<Pick<ExtensionAPI, "events" | "getActiveTools" | "getAllTools" | "on" | "sendMessage" | "registerCommand" | "appendEntry" | "registerEntryRenderer">>;
|
|
27
30
|
|
|
28
31
|
function validateSubagentRunRequest(value: unknown): SubagentRunRequest {
|
|
29
32
|
return normalizeSubagentRunRequest(value);
|
|
@@ -55,7 +58,7 @@ function serialize(value: unknown): string {
|
|
|
55
58
|
}
|
|
56
59
|
|
|
57
60
|
function toolResult(value: unknown): AgentToolResult<unknown> {
|
|
58
|
-
return { content: [{ type: "text", text: serialize(value) }], details: value };
|
|
61
|
+
return { content: [{ type: "text", text: serialize(value) }], details: value, structuredContent: value as JsonValue };
|
|
59
62
|
}
|
|
60
63
|
|
|
61
64
|
function managerContext(toolCallId: string, signal: AbortSignal | undefined, onUpdate: ((value: AgentToolResult<unknown>) => void) | undefined, context: ExtensionContext): SubagentManagerContext {
|
|
@@ -78,6 +81,7 @@ export function createSubagentTools(manager: SubagentManager): readonly ToolDefi
|
|
|
78
81
|
"Do not poll a running ID; use subagents_inspect({ id }) when you need its current status or terminal result.",
|
|
79
82
|
],
|
|
80
83
|
parameters: SUBAGENTS_RUN_PARAMETERS,
|
|
84
|
+
outputSchema: SUBAGENT_STATUS_OUTPUT,
|
|
81
85
|
async execute(toolCallId, params, signal, onUpdate, context) {
|
|
82
86
|
return toolResult(await manager.run(validateSubagentRunRequest(params), managerContext(toolCallId, signal, onUpdate, context)));
|
|
83
87
|
},
|
|
@@ -87,8 +91,9 @@ export function createSubagentTools(manager: SubagentManager): readonly ToolDefi
|
|
|
87
91
|
defineTool({
|
|
88
92
|
name: "subagents_inspect",
|
|
89
93
|
label: "Subagents Inspect",
|
|
90
|
-
description: "Inspect durable subagent runs. Omit id for ordered run summaries, or provide id for detailed status, progress, activity, accounting, tool calls, timestamps, worktree metadata, and a terminal value or error when available.",
|
|
94
|
+
description: "Inspect durable subagent runs. Omit id for ordered run summaries of the current session (scope all for every session), or provide id for detailed status, progress, activity, accounting, tool calls, timestamps, worktree metadata, and a terminal value or error when available.",
|
|
91
95
|
parameters: SUBAGENTS_INSPECT_PARAMETERS,
|
|
96
|
+
outputSchema: SUBAGENTS_INSPECT_OUTPUT,
|
|
92
97
|
async execute(toolCallId, params, signal, onUpdate, context) {
|
|
93
98
|
return toolResult(await manager.inspect(validateSubagentInspectRequest(params), managerContext(toolCallId, signal, onUpdate, context)));
|
|
94
99
|
},
|
|
@@ -100,6 +105,7 @@ export function createSubagentTools(manager: SubagentManager): readonly ToolDefi
|
|
|
100
105
|
label: "Subagents Steer",
|
|
101
106
|
description: "Send a message to a running subagent. The message is queued safely if its steering handler is not ready; settled runs cannot be steered.",
|
|
102
107
|
parameters: SUBAGENTS_STEER_PARAMETERS,
|
|
108
|
+
outputSchema: SUBAGENTS_STEER_OUTPUT,
|
|
103
109
|
async execute(toolCallId, params, signal, onUpdate, context) {
|
|
104
110
|
return toolResult(await manager.steer(validateSubagentSteerRequest(params), managerContext(toolCallId, signal, onUpdate, context)));
|
|
105
111
|
},
|
|
@@ -111,6 +117,7 @@ export function createSubagentTools(manager: SubagentManager): readonly ToolDefi
|
|
|
111
117
|
label: "Subagents Stop",
|
|
112
118
|
description: "Stop one running subagent, abort its active session, persist state \"stopped\", and clean its worktree without affecting sibling runs.",
|
|
113
119
|
parameters: SUBAGENTS_STOP_PARAMETERS,
|
|
120
|
+
outputSchema: SUBAGENT_STATUS_OUTPUT,
|
|
114
121
|
async execute(toolCallId, params, signal, onUpdate, context) {
|
|
115
122
|
return toolResult(await manager.stop(validateSubagentIdRequest(params, "subagents_stop"), managerContext(toolCallId, signal, onUpdate, context)));
|
|
116
123
|
},
|
|
@@ -122,6 +129,7 @@ export function createSubagentTools(manager: SubagentManager): readonly ToolDefi
|
|
|
122
129
|
label: "Subagents Retry",
|
|
123
130
|
description: "Start a fresh run from a failed or stopped subagent's persisted request. The new run gets a new ID and preserves its original background or foreground mode.",
|
|
124
131
|
parameters: SUBAGENTS_RETRY_PARAMETERS,
|
|
132
|
+
outputSchema: SUBAGENT_STATUS_OUTPUT,
|
|
125
133
|
async execute(toolCallId, params, signal, onUpdate, context) {
|
|
126
134
|
return toolResult(await manager.retry(validateSubagentIdRequest(params, "subagents_retry"), managerContext(toolCallId, signal, onUpdate, context)));
|
|
127
135
|
},
|
|
@@ -133,8 +141,7 @@ export function createSubagentTools(manager: SubagentManager): readonly ToolDefi
|
|
|
133
141
|
|
|
134
142
|
function notificationContent(notification: SubagentNotification): string {
|
|
135
143
|
const label = notification.label?.trim();
|
|
136
|
-
const
|
|
137
|
-
const identity = label ? `${label} role=${role} (${notification.id})` : `${notification.id} role=${role}`;
|
|
144
|
+
const identity = label ? `${label} (${notification.id})` : notification.id;
|
|
138
145
|
if (notification.state === "completed") return `Subagent ${identity} completed. Inspect it with subagents_inspect({ id: "${notification.id}" }).`;
|
|
139
146
|
return `Subagent ${identity} failed: ${notification.error?.message ?? "unknown error"}. Inspect it with subagents_inspect({ id: "${notification.id}" }).`;
|
|
140
147
|
}
|
|
@@ -162,7 +169,8 @@ export function createSubagentsExtension(options: SubagentsExtensionOptions = {}
|
|
|
162
169
|
|
|
163
170
|
export function registerSubagentsExtension(pi: SubagentsExtensionAPI, options: SubagentsExtensionOptions = {}): SubagentsExtension {
|
|
164
171
|
const getActiveTools = pi.getActiveTools;
|
|
165
|
-
const
|
|
172
|
+
const getAllTools = pi.getAllTools;
|
|
173
|
+
const activeTools = getActiveTools === undefined ? undefined : () => reachableTools({ getActiveTools: () => getActiveTools.call(pi), ...(getAllTools === undefined ? {} : { getAllTools: () => getAllTools.call(pi) }) });
|
|
166
174
|
const sendMessage = pi.sendMessage;
|
|
167
175
|
const notify = sendMessage === undefined ? undefined : (notification: SubagentNotification): void => {
|
|
168
176
|
sendMessage.call(pi, { customType: "subagents", content: notificationContent(notification), display: true, details: notification }, { deliverAs: "steer", triggerTurn: true });
|
|
@@ -173,7 +181,8 @@ export function registerSubagentsExtension(pi: SubagentsExtensionAPI, options: S
|
|
|
173
181
|
const appendEntry = pi.appendEntry;
|
|
174
182
|
const widget = createSubagentBackgroundWidget({ ...(appendEntry === undefined ? {} : { appendEntry: (customType, data) => { appendEntry.call(pi, customType, data); } }), ...(pi.registerEntryRenderer === undefined ? {} : { registerEntryRenderer: pi.registerEntryRenderer.bind(pi) }) });
|
|
175
183
|
const extension = createSubagentsExtension(options, activeTools, notify, (status, request) => { widget.update(status, request); const registry = loadingRegistry(); if (typeof registry.observeSubagentStatus === "function") registry.observeSubagentStatus(status, request); }, onResourceWarning);
|
|
176
|
-
|
|
184
|
+
const codemodeTools = loadCodemodeToolsSetting(options.managerDependencies?.agentDir);
|
|
185
|
+
for (const tool of extension.tools) pi.registerTool({ ...tool, ...workflowToolExposure(tool.name, codemodeTools) });
|
|
177
186
|
if (pi.registerCommand !== undefined) registerSubagentNavigator(pi.registerCommand.bind(pi), extension.manager, storageDirectory(options), options.clipboard);
|
|
178
187
|
if (pi.on !== undefined) {
|
|
179
188
|
setSubagentManager(extension.manager);
|
package/subagents/src/manager.ts
CHANGED
|
@@ -2,67 +2,11 @@ import { randomUUID } from "node:crypto";
|
|
|
2
2
|
import { chmod, link, mkdir, open, readFile, readdir, rename, rm, stat } from "node:fs/promises";
|
|
3
3
|
import { join } from "node:path";
|
|
4
4
|
import { getAgentDir } from "@earendil-works/pi-coding-agent";
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
deepFreeze,
|
|
8
|
-
errorCode,
|
|
9
|
-
errorText,
|
|
10
|
-
finiteNumber,
|
|
11
|
-
isNodeError,
|
|
12
|
-
isThinkingLevel,
|
|
13
|
-
jsonValue,
|
|
14
|
-
object,
|
|
15
|
-
loadingRegistry,
|
|
16
|
-
localAgentTransport,
|
|
17
|
-
resolveAgentResourcePolicy,
|
|
18
|
-
resolveWorkflowSettings,
|
|
19
|
-
roleNameOf,
|
|
20
|
-
sanitizeDisplayText,
|
|
21
|
-
sumAccounting,
|
|
22
|
-
structuralPath,
|
|
23
|
-
validateModelAliasAvailability,
|
|
24
|
-
WorkflowAgentExecutor,
|
|
25
|
-
WorkflowError,
|
|
26
|
-
workflowProjectSettingsPath,
|
|
27
|
-
workflowSettingsPath,
|
|
28
|
-
type AgentAccounting,
|
|
29
|
-
type AgentAttempt,
|
|
30
|
-
type AgentAttemptSummary,
|
|
31
|
-
type AgentDefinition,
|
|
32
|
-
type AgentExecutionOptions,
|
|
33
|
-
type AgentExecutionRoot,
|
|
34
|
-
type AgentProgress,
|
|
35
|
-
type AgentToolCallProgress,
|
|
36
|
-
type JsonSchema,
|
|
37
|
-
type JsonValue,
|
|
38
|
-
type ModelSpec,
|
|
39
|
-
type WorkflowAgentSessionState,
|
|
40
|
-
type WorkflowExtensionSettings,
|
|
41
|
-
type WorkflowRunContext,
|
|
42
|
-
SerialLane,
|
|
43
|
-
} from "../../src/index.js";
|
|
44
|
-
import { decodeAgentDefinition, decodeWorkflowExtensions } from "../../src/decoders.js";
|
|
45
|
-
import { loadAgentDefinitions } from "../../src/roles.js";
|
|
5
|
+
import { addAccounting, errorCode, errorText, finiteNumber, isNodeError, isThinkingLevel, jsonValue, object, loadingRegistry, localAgentTransport, resolveAgentResourcePolicy, resolveWorkflowSettings, sanitizeDisplayText, sumAccounting, structuralPath, validateModelAliasAvailability, WorkflowAgentExecutor, WorkflowError, workflowSettingsPath, type AgentAccounting, type AgentAttempt, type AgentAttemptSummary, type PreparedAgentConfiguration, type AgentExecutionOptions, type AgentExecutionRoot, type AgentProgress, type AgentToolCallProgress, type JsonSchema, type JsonValue, type ModelSpec, type WorkflowAgentSessionState, type WorkflowRunContext, SerialLane } from "../../src/index.js";
|
|
6
|
+
import { decodePreparedAgentConfiguration } from "../../src/decoders.js";
|
|
46
7
|
import { atomicJson, json as readJson, processAlive } from "../../src/persistence.js";
|
|
47
8
|
import { accountingValue, activityValue, legacyAccountingValue, worktreeValue } from "./decode.js";
|
|
48
|
-
import {
|
|
49
|
-
SUBAGENT_ATTEMPT_DETAILS_LIMIT,
|
|
50
|
-
SUBAGENT_MAX_RETRIES,
|
|
51
|
-
SUBAGENT_SYSTEM_PROMPT_LIMIT,
|
|
52
|
-
SUBAGENTS_TOOL_NAMES,
|
|
53
|
-
normalizeSubagentRunRequest,
|
|
54
|
-
type SubagentInspectRequest,
|
|
55
|
-
type SubagentLiveness,
|
|
56
|
-
type SubagentAttemptActionData,
|
|
57
|
-
type SubagentManager,
|
|
58
|
-
type SubagentManagerContext,
|
|
59
|
-
type SubagentManagerDependencies,
|
|
60
|
-
type SubagentNotification,
|
|
61
|
-
type SubagentOwnerMarker,
|
|
62
|
-
type SubagentProgress,
|
|
63
|
-
type SubagentRunRequest,
|
|
64
|
-
type SubagentStatus,
|
|
65
|
-
} from "./contracts.js";
|
|
9
|
+
import { SUBAGENT_ATTEMPT_DETAILS_LIMIT, SUBAGENT_MAX_RETRIES, SUBAGENT_SYSTEM_PROMPT_LIMIT, SUBAGENTS_TOOL_NAMES, normalizeSubagentRunRequest, type SubagentInspectRequest, type SubagentLiveness, type SubagentAttemptActionData, type SubagentManager, type SubagentManagerContext, type SubagentManagerDependencies, type SubagentNotification, type SubagentOwnerMarker, type SubagentProgress, type SubagentRunRequest, type SubagentStatus } from "./contracts.js";
|
|
66
10
|
import { createRunStoreWorktreeAdapter, defaultWorktreeHome, type SubagentWorktreeContext, type SubagentWorktreeHandle } from "./worktree.js";
|
|
67
11
|
|
|
68
12
|
const WORKFLOW_NAME = "subagents";
|
|
@@ -77,12 +21,7 @@ const MAX_PERSISTED_ATTEMPT_ARRAY_ITEMS = SUBAGENT_MAX_RETRIES + 1;
|
|
|
77
21
|
const MAX_PERSISTED_ATTEMPT_STRING_CHARS = 4096;
|
|
78
22
|
const MAX_PERSISTED_ATTEMPT_LOCATOR_CHARS = 16 * 1024;
|
|
79
23
|
const SUBAGENT_ID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
80
|
-
type StandaloneExternalConfiguration = Readonly<
|
|
81
|
-
projectTrusted: boolean;
|
|
82
|
-
globalExtensionSettings?: Readonly<WorkflowExtensionSettings>;
|
|
83
|
-
projectExtensionSettings?: Readonly<WorkflowExtensionSettings>;
|
|
84
|
-
agentDefinitions: Readonly<Record<string, AgentDefinition>>;
|
|
85
|
-
}>;
|
|
24
|
+
type StandaloneExternalConfiguration = Readonly<PreparedAgentConfiguration>;
|
|
86
25
|
class InvalidPersistedSubagentStatusError extends WorkflowError {
|
|
87
26
|
constructor() { super("INTERNAL_ERROR", "Persisted subagent status is invalid"); }
|
|
88
27
|
}
|
|
@@ -169,22 +108,11 @@ function rootModel(context: Readonly<SubagentManagerContext>): ModelSpec {
|
|
|
169
108
|
const thinking = context.extensionContext.thinkingLevel;
|
|
170
109
|
return { provider: model.provider, model: model.id, ...(thinking === undefined ? {} : { thinking }) };
|
|
171
110
|
}
|
|
172
|
-
function
|
|
173
|
-
return trustedProject && external.projectExtensionSettings !== undefined ? workflowProjectSettingsPath(cwd) : workflowSettingsPath(agentDir);
|
|
174
|
-
}
|
|
175
|
-
function validateStandaloneExtensionSources(context: Readonly<SubagentManagerContext>, external: StandaloneExternalConfiguration, registry: ReturnType<typeof loadingRegistry>, agentDir: string): void {
|
|
176
|
-
const cwd = context.extensionContext.cwd;
|
|
177
|
-
const globalSettingsPath = workflowSettingsPath(agentDir);
|
|
178
|
-
const trustedProject = context.extensionContext.isProjectTrusted();
|
|
179
|
-
if (external.globalExtensionSettings !== undefined) registry.validateExtensionSettings(external.globalExtensionSettings, { source: "global", cwd, projectTrusted: trustedProject, settingsPath: globalSettingsPath });
|
|
180
|
-
if (trustedProject && external.projectExtensionSettings !== undefined) registry.validateExtensionSettings(external.projectExtensionSettings, { source: "project", cwd, projectTrusted: true, settingsPath: workflowProjectSettingsPath(cwd) });
|
|
181
|
-
}
|
|
182
|
-
function executionRoot(context: Readonly<SubagentManagerContext>, dependencies: Readonly<SubagentManagerDependencies>, signal: AbortSignal, runId: string, worktree: SubagentWorktreeHandle | undefined, external: StandaloneExternalConfiguration): AgentExecutionRoot {
|
|
111
|
+
function executionRoot(context: Readonly<SubagentManagerContext>, dependencies: Readonly<SubagentManagerDependencies>, signal: AbortSignal, runId: string, worktree: SubagentWorktreeHandle | undefined): AgentExecutionRoot {
|
|
183
112
|
const extensionContext = context.extensionContext;
|
|
184
113
|
const model = rootModel(context);
|
|
185
114
|
const agentDir = dependencies.agentDir ?? getAgentDir();
|
|
186
115
|
const currentTrustedProject = extensionContext.isProjectTrusted();
|
|
187
|
-
if (external.projectTrusted && !currentTrustedProject) throw new WorkflowError("RESUME_INCOMPATIBLE", "Cannot retry standalone configuration from an untrusted project");
|
|
188
116
|
const trustedProject = currentTrustedProject;
|
|
189
117
|
const settingsPath = workflowSettingsPath(agentDir);
|
|
190
118
|
const settings = resolveWorkflowSettings(extensionContext.cwd, trustedProject, settingsPath);
|
|
@@ -207,11 +135,13 @@ function executionRoot(context: Readonly<SubagentManagerContext>, dependencies:
|
|
|
207
135
|
signal,
|
|
208
136
|
};
|
|
209
137
|
const registry = loadingRegistry();
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
const
|
|
138
|
+
if (settings.global.extensionSettings !== undefined) registry.validateExtensionSettings(settings.global.extensionSettings, { source: "global", cwd: extensionContext.cwd, projectTrusted: trustedProject, settingsPath: settings.globalSettingsPath });
|
|
139
|
+
if (trustedProject && settings.project.extensionSettings !== undefined) registry.validateExtensionSettings(settings.project.extensionSettings, { source: "project", cwd: extensionContext.cwd, projectTrusted: true, settingsPath: settings.projectSettingsPath });
|
|
140
|
+
const extensionSettings = settings.effective.extensionSettings;
|
|
141
|
+
const extensionSettingsPath = settings.sources.extensionSettings ?? settingsPath;
|
|
213
142
|
return {
|
|
214
143
|
cwd: extensionContext.cwd,
|
|
144
|
+
projectTrusted: trustedProject,
|
|
215
145
|
model,
|
|
216
146
|
tools,
|
|
217
147
|
resourceSelectors: resourcePolicy.effective,
|
|
@@ -221,9 +151,10 @@ function executionRoot(context: Readonly<SubagentManagerContext>, dependencies:
|
|
|
221
151
|
availableModels,
|
|
222
152
|
knownModels,
|
|
223
153
|
...(Object.keys(staticAliases).length ? { modelAliases: staticAliases } : {}),
|
|
154
|
+
dynamicModelAliasNames: [],
|
|
224
155
|
settingsPath: settings.sources.modelAliases,
|
|
225
156
|
extensionSettingsPath,
|
|
226
|
-
|
|
157
|
+
agentPreparationHooks: registry.agentPreparationHooks(),
|
|
227
158
|
agentSetupHooks: registry.agentSetupHooks(),
|
|
228
159
|
validateExtensionSettings: registry.validateExtensionSettings,
|
|
229
160
|
agentResourcePolicy: () => structuredClone(resourcePolicy),
|
|
@@ -240,12 +171,11 @@ async function addDynamicAliases(context: Readonly<SubagentManagerContext>, sign
|
|
|
240
171
|
const trustedProject = resourcePolicy?.projectTrusted ?? context.extensionContext.isProjectTrusted();
|
|
241
172
|
const dynamicAliases = await registry.resolveModelAliases({ cwd: context.extensionContext.cwd, projectTrusted: trustedProject, rootModel: root.model, knownModels: root.knownModels ?? new Set(), availableModels: root.availableModels ?? new Set(), signal }, new Set(Object.keys(staticAliases)));
|
|
242
173
|
validateModelAliasAvailability(dynamicAliases, Object.keys(dynamicAliases), root.availableModels ?? new Set(), root.knownModels ?? new Set(), root.settingsPath);
|
|
243
|
-
return { ...root, modelAliases: { ...dynamicAliases, ...staticAliases } };
|
|
174
|
+
return { ...root, modelAliases: { ...dynamicAliases, ...staticAliases }, dynamicModelAliasNames: Object.keys(dynamicAliases) };
|
|
244
175
|
}
|
|
245
176
|
|
|
246
177
|
function executionOptions(request: Readonly<SubagentRunRequest>, onAttempt: NonNullable<AgentExecutionOptions["onAttempt"]>, onProgress: NonNullable<AgentExecutionOptions["onProgress"]>): AgentExecutionOptions {
|
|
247
|
-
const
|
|
248
|
-
const label = request.label ?? roleNameOf(role) ?? "subagent";
|
|
178
|
+
const label = request.label ?? "subagent";
|
|
249
179
|
return {
|
|
250
180
|
label,
|
|
251
181
|
workflowName: WORKFLOW_NAME,
|
|
@@ -254,11 +184,11 @@ function executionOptions(request: Readonly<SubagentRunRequest>, onAttempt: NonN
|
|
|
254
184
|
...(request.skills === undefined ? {} : { skills: request.skills }),
|
|
255
185
|
...(request.extensions === undefined ? {} : { extensions: request.extensions }),
|
|
256
186
|
...(request.contextFiles === undefined ? {} : { contextFiles: request.contextFiles as NonNullable<AgentExecutionOptions["contextFiles"]> }),
|
|
257
|
-
...(role === undefined ? {} : { role }),
|
|
258
187
|
...(request.worktree === undefined ? {} : { worktreeOwner: structuralPath("worktree", "named", request.worktree) }),
|
|
259
188
|
...(request.outputSchema === undefined ? {} : { schema: request.outputSchema as JsonSchema }),
|
|
260
189
|
...(request.retries === undefined ? {} : { retries: request.retries }),
|
|
261
190
|
...(request.timeoutMs === undefined ? {} : { timeoutMs: request.timeoutMs }),
|
|
191
|
+
agentOptions: Object.fromEntries(Object.entries(request).filter(([key]) => !["prompt", "mode", "worktree"].includes(key))) as Record<string, JsonValue>,
|
|
262
192
|
onAttempt,
|
|
263
193
|
onProgress,
|
|
264
194
|
};
|
|
@@ -398,32 +328,8 @@ function checkedRequest(request: unknown): SubagentRunRequest {
|
|
|
398
328
|
return normalizeSubagentRunRequest(request);
|
|
399
329
|
}
|
|
400
330
|
function decodePersistedStandaloneExternalConfiguration(value: unknown): StandaloneExternalConfiguration | undefined {
|
|
401
|
-
if (!object(value) ||
|
|
402
|
-
|
|
403
|
-
const projectExtensionSettings = value.projectExtensionSettings === undefined ? undefined : decodeWorkflowExtensions(value.projectExtensionSettings);
|
|
404
|
-
if (value.globalExtensionSettings !== undefined && globalExtensionSettings === undefined || value.projectExtensionSettings !== undefined && projectExtensionSettings === undefined) return undefined;
|
|
405
|
-
if (!object(value.agentDefinitions)) return undefined;
|
|
406
|
-
const agentDefinitions = Object.create(null) as Record<string, AgentDefinition>;
|
|
407
|
-
for (const [name, definition] of Object.entries(value.agentDefinitions)) {
|
|
408
|
-
const decoded = decodeAgentDefinition(definition);
|
|
409
|
-
if (decoded === undefined) return undefined;
|
|
410
|
-
agentDefinitions[name] = decoded;
|
|
411
|
-
}
|
|
412
|
-
return deepFreeze({ projectTrusted: value.projectTrusted, ...(globalExtensionSettings === undefined ? {} : { globalExtensionSettings }), ...(projectExtensionSettings === undefined ? {} : { projectExtensionSettings }), agentDefinitions });
|
|
413
|
-
}
|
|
414
|
-
function standaloneExternalConfiguration(context: Readonly<SubagentManagerContext>, dependencies: Readonly<SubagentManagerDependencies>): StandaloneExternalConfiguration {
|
|
415
|
-
const cwd = context.extensionContext.cwd;
|
|
416
|
-
const trustedProject = context.extensionContext.isProjectTrusted();
|
|
417
|
-
const agentDir = dependencies.agentDir ?? getAgentDir();
|
|
418
|
-
const resolution = resolveWorkflowSettings(cwd, trustedProject, workflowSettingsPath(agentDir));
|
|
419
|
-
const globalExtensionSettings = resolution.global.extensionSettings;
|
|
420
|
-
const projectExtensionSettings = resolution.project.extensionSettings;
|
|
421
|
-
return deepFreeze({
|
|
422
|
-
projectTrusted: trustedProject,
|
|
423
|
-
...(globalExtensionSettings === undefined ? {} : { globalExtensionSettings: structuredClone(globalExtensionSettings) }),
|
|
424
|
-
...(projectExtensionSettings === undefined ? {} : { projectExtensionSettings: structuredClone(projectExtensionSettings) }),
|
|
425
|
-
agentDefinitions: structuredClone(loadAgentDefinitions(cwd, agentDir, trustedProject)),
|
|
426
|
-
});
|
|
331
|
+
if (!object(value) || value.version !== 1) return undefined;
|
|
332
|
+
return decodePreparedAgentConfiguration(value.configuration);
|
|
427
333
|
}
|
|
428
334
|
|
|
429
335
|
function checkedId(request: Readonly<{ id: string }>): string {
|
|
@@ -719,7 +625,7 @@ function emitUpdate(run: LiveRun): void {
|
|
|
719
625
|
try { run.observe?.(publicStatus(live, true, true)); } catch { /* A widget failure is display-only. */ }
|
|
720
626
|
}
|
|
721
627
|
|
|
722
|
-
async function createRunStorage(root: string, id: string, request: Readonly<SubagentRunRequest>, status: PersistedSubagentStatus, external: StandaloneExternalConfiguration): Promise<string> {
|
|
628
|
+
async function createRunStorage(root: string, id: string, request: Readonly<SubagentRunRequest>, status: PersistedSubagentStatus, external: StandaloneExternalConfiguration | undefined): Promise<string> {
|
|
723
629
|
await secureDirectory(root);
|
|
724
630
|
const directory = runDirectory(root, id);
|
|
725
631
|
let created = false;
|
|
@@ -728,7 +634,7 @@ async function createRunStorage(root: string, id: string, request: Readonly<Suba
|
|
|
728
634
|
created = true;
|
|
729
635
|
await chmod(directory, 0o700);
|
|
730
636
|
await atomicJson(requestPath(directory), request);
|
|
731
|
-
await atomicJson(configurationPath(directory), external);
|
|
637
|
+
if (external !== undefined) await atomicJson(configurationPath(directory), { version: 1, configuration: external });
|
|
732
638
|
await atomicJson(statusPath(directory), status);
|
|
733
639
|
return directory;
|
|
734
640
|
} catch (error) {
|
|
@@ -918,6 +824,7 @@ function unavailable(operation: string): { ok: false; error: { code: "SUBAGENTS_
|
|
|
918
824
|
|
|
919
825
|
class PersistentSubagentManager implements SubagentManager {
|
|
920
826
|
private readonly activeRuns = new Map<string, LiveRun>();
|
|
827
|
+
private readonly pendingStarts = new Set<Promise<void>>();
|
|
921
828
|
private activeRunCount = 0;
|
|
922
829
|
private readonly terminalSummaries = new Map<string, TerminalSummary>();
|
|
923
830
|
private readonly reconciliationErrors = new Map<string, WorkflowError>();
|
|
@@ -968,8 +875,8 @@ class PersistentSubagentManager implements SubagentManager {
|
|
|
968
875
|
await this.ensureInitialized();
|
|
969
876
|
if (this.disposed) throw new WorkflowError("CANCELLED", "Subagent manager is disposed");
|
|
970
877
|
if (context.signal?.aborted) throw new WorkflowError("CANCELLED", "Subagent cancelled");
|
|
971
|
-
const external = frozenExternal
|
|
972
|
-
if (external
|
|
878
|
+
const external = frozenExternal;
|
|
879
|
+
if (external?.projectTrusted && !context.extensionContext.isProjectTrusted()) throw new WorkflowError("RESUME_INCOMPATIBLE", "Cannot retry standalone configuration from an untrusted project");
|
|
973
880
|
const id = randomUUID();
|
|
974
881
|
const startedAt = Date.now();
|
|
975
882
|
const sessionId = context.extensionContext.sessionManager.getSessionId();
|
|
@@ -982,13 +889,23 @@ class PersistentSubagentManager implements SubagentManager {
|
|
|
982
889
|
this.activeRunCount += 1;
|
|
983
890
|
const controller = new AbortController();
|
|
984
891
|
const initialStatus: PersistedSubagentStatus = { id, sessionId, state: "running", startedAt, owner: { ...owner } };
|
|
892
|
+
let finishStart!: () => void;
|
|
893
|
+
const pendingStart = new Promise<void>((resolve) => { finishStart = resolve; });
|
|
894
|
+
this.pendingStarts.add(pendingStart);
|
|
985
895
|
let directory: string;
|
|
986
896
|
try {
|
|
987
897
|
directory = await createRunStorage(storageDirectory(this.dependencies), id, snapshot, initialStatus, external);
|
|
898
|
+
if (this.disposePromise !== undefined || context.signal?.aborted) {
|
|
899
|
+
await atomicJson(statusPath(directory), reconciledStatus(initialStatus, "stopped", Date.now()));
|
|
900
|
+
throw new WorkflowError("CANCELLED", "Subagent cancelled");
|
|
901
|
+
}
|
|
988
902
|
} catch (error) {
|
|
989
903
|
this.activeRunCount -= 1;
|
|
990
904
|
if (error instanceof WorkflowError) throw error;
|
|
991
905
|
throw internalStorageError(error, `Unable to start subagent ${id}`);
|
|
906
|
+
} finally {
|
|
907
|
+
this.pendingStarts.delete(pendingStart);
|
|
908
|
+
finishStart();
|
|
992
909
|
}
|
|
993
910
|
const current: { run?: LiveRun } = {};
|
|
994
911
|
let resolveTerminal!: (result: ForegroundResult) => void;
|
|
@@ -1019,12 +936,9 @@ class PersistentSubagentManager implements SubagentManager {
|
|
|
1019
936
|
throw new WorkflowError("CANCELLED", "Subagent cancelled");
|
|
1020
937
|
}
|
|
1021
938
|
}
|
|
1022
|
-
const baseRoot = executionRoot(context, this.dependencies, controller.signal, id, worktree
|
|
1023
|
-
const root = loadingRegistry().modelAliases().length === 0 ? baseRoot : await addDynamicAliases(context, controller.signal, baseRoot);
|
|
939
|
+
const baseRoot = executionRoot(context, this.dependencies, controller.signal, id, worktree);
|
|
940
|
+
const root = external !== undefined || loadingRegistry().modelAliases().length === 0 ? baseRoot : await addDynamicAliases(context, controller.signal, baseRoot);
|
|
1024
941
|
const transport = this.dependencies.transport ?? localAgentTransport;
|
|
1025
|
-
const injectedExecutor = this.dependencies.createExecutor?.(root, transport);
|
|
1026
|
-
executorOwnership.default = injectedExecutor === undefined;
|
|
1027
|
-
if (current.run) current.run.executorOwnsSession = executorOwnership.default;
|
|
1028
942
|
const setSteer = (handler: SteerHandler): void => {
|
|
1029
943
|
const run = current.run;
|
|
1030
944
|
if (run) this.registerSteerHandler(run, handler);
|
|
@@ -1066,6 +980,13 @@ class PersistentSubagentManager implements SubagentManager {
|
|
|
1066
980
|
if (run.state !== "running") return;
|
|
1067
981
|
emitUpdate(run);
|
|
1068
982
|
}, (progress) => this.recordProgress(current.run, progress));
|
|
983
|
+
if (external !== undefined) options.configuration = structuredClone(external);
|
|
984
|
+
options.onConfiguration = (configuration) => atomicJson(configurationPath(directory), { version: 1, configuration });
|
|
985
|
+
const cwd = worktree?.cwd ?? root.cwd;
|
|
986
|
+
options.configuration = await new WorkflowAgentExecutor(root, transport).prepare(options, cwd, controller.signal);
|
|
987
|
+
const injectedExecutor = this.dependencies.createExecutor?.({ ...root, extensionSettings: options.configuration.settings }, transport);
|
|
988
|
+
executorOwnership.default = injectedExecutor === undefined;
|
|
989
|
+
if (current.run) current.run.executorOwnsSession = executorOwnership.default;
|
|
1069
990
|
if (injectedExecutor) return injectedExecutor.execute(snapshot.prompt, options, controller.signal, setSteer);
|
|
1070
991
|
return new WorkflowAgentExecutor(root, transport).execute(snapshot.prompt, options, controller.signal, [], setSteer);
|
|
1071
992
|
});
|
|
@@ -1113,9 +1034,9 @@ class PersistentSubagentManager implements SubagentManager {
|
|
|
1113
1034
|
}
|
|
1114
1035
|
return inspection;
|
|
1115
1036
|
}
|
|
1116
|
-
return this.inspectList();
|
|
1037
|
+
return this.inspectList(request.scope === "all" ? undefined : context.extensionContext.sessionManager.getSessionId());
|
|
1117
1038
|
}
|
|
1118
|
-
private async inspectList(): Promise<unknown> {
|
|
1039
|
+
private async inspectList(sessionId: string | undefined): Promise<unknown> {
|
|
1119
1040
|
const root = storageDirectory(this.dependencies);
|
|
1120
1041
|
await secureDirectory(root);
|
|
1121
1042
|
const entries = await readdir(root, { withFileTypes: true });
|
|
@@ -1127,7 +1048,7 @@ class PersistentSubagentManager implements SubagentManager {
|
|
|
1127
1048
|
try {
|
|
1128
1049
|
const active = this.activeRuns.get(entry.name);
|
|
1129
1050
|
const status = publicStatus(active ? persistedStatus(active) : this.terminalSummaries.get(entry.name) ?? await loadPersistedStatus(root, entry.name, false));
|
|
1130
|
-
if (status.startedAt === undefined) continue;
|
|
1051
|
+
if (status.startedAt === undefined || (sessionId !== undefined && status.sessionId !== sessionId)) continue;
|
|
1131
1052
|
statuses.push({ status, startedAt: status.startedAt });
|
|
1132
1053
|
} catch (error) {
|
|
1133
1054
|
if (error instanceof WorkflowError && (error.code === "RUN_NOT_FOUND" || error instanceof InvalidPersistedSubagentStatusError)) continue;
|
|
@@ -1176,11 +1097,11 @@ class PersistentSubagentManager implements SubagentManager {
|
|
|
1176
1097
|
|
|
1177
1098
|
async dispose(): Promise<void> {
|
|
1178
1099
|
if (this.disposePromise) return this.disposePromise;
|
|
1100
|
+
this.disposed = true;
|
|
1179
1101
|
this.disposePromise = (async () => {
|
|
1180
1102
|
await this.initialization;
|
|
1181
|
-
this.disposed = true;
|
|
1182
1103
|
const runs = [...this.activeRuns.values()];
|
|
1183
|
-
await Promise.allSettled(runs.map((run) => this.stopRun(run, true)));
|
|
1104
|
+
await Promise.allSettled([...this.pendingStarts, ...runs.map((run) => this.stopRun(run, true))]);
|
|
1184
1105
|
await Promise.allSettled([...this.notificationPromises]);
|
|
1185
1106
|
const owner = this.storageOwner;
|
|
1186
1107
|
this.storageOwner = undefined;
|
|
@@ -1533,9 +1454,8 @@ class PersistentSubagentManager implements SubagentManager {
|
|
|
1533
1454
|
const notify = this.dependencies.notify;
|
|
1534
1455
|
if (!notify || run.notificationSent || run.disposed) return;
|
|
1535
1456
|
run.notificationSent = true;
|
|
1536
|
-
const
|
|
1537
|
-
const
|
|
1538
|
-
const notification: SubagentNotification = { id: run.id, label, role, state: run.state as "completed" | "failed", ...(run.error === undefined ? {} : { error: run.error }) };
|
|
1457
|
+
const label = run.request.label?.trim() || "subagent";
|
|
1458
|
+
const notification: SubagentNotification = { id: run.id, label, state: run.state as "completed" | "failed", ...(run.error === undefined ? {} : { error: run.error }) };
|
|
1539
1459
|
const pending = Promise.resolve().then(() => notify(notification));
|
|
1540
1460
|
this.notificationPromises.add(pending);
|
|
1541
1461
|
void pending.then(() => { this.notificationPromises.delete(pending); }, () => { this.notificationPromises.delete(pending); });
|
|
@@ -71,16 +71,10 @@ async function inspectEntry(manager: SubagentManager, storageDirectory: string,
|
|
|
71
71
|
};
|
|
72
72
|
}
|
|
73
73
|
|
|
74
|
-
|
|
75
|
-
const role: unknown = request?.role;
|
|
76
|
-
if (typeof role === "string" && role.trim()) return role.trim();
|
|
77
|
-
const override = objectValue(role);
|
|
78
|
-
return typeof override?.name === "string" && override.name.trim() ? override.name.trim() : "none";
|
|
79
|
-
}
|
|
74
|
+
|
|
80
75
|
function shortId(id: string): string { return id.length > 12 ? id.slice(0, 8) : id; }
|
|
81
76
|
function entryName(entry: NavigatorEntry): string {
|
|
82
|
-
|
|
83
|
-
return boundedText(entry.request?.label?.trim() || (role === "none" ? shortId(entry.status.id) : role), 256);
|
|
77
|
+
return boundedText(entry.request?.label?.trim() || shortId(entry.status.id), 256);
|
|
84
78
|
}
|
|
85
79
|
/** Names for a list of runs; a repeated name carries its short ID, as in the `/workflow` picker, so every row stays unique. */
|
|
86
80
|
function listNames(entries: readonly NavigatorEntry[]): string[] {
|
|
@@ -113,7 +107,7 @@ function usageAccounting(status: SubagentStatus): SubagentProgress["accounting"]
|
|
|
113
107
|
return status.progress?.accounting;
|
|
114
108
|
}
|
|
115
109
|
function detailPresentation(inspection: Inspection): AgentDetailPresentation {
|
|
116
|
-
const { status
|
|
110
|
+
const { status } = inspection.entry;
|
|
117
111
|
const attempt = latestAttempt(status);
|
|
118
112
|
const state = status.progress?.state;
|
|
119
113
|
const activity = status.progress?.activity;
|
|
@@ -122,14 +116,12 @@ function detailPresentation(inspection: Inspection): AgentDetailPresentation {
|
|
|
122
116
|
const lastEventAt = status.progress?.lastEventAt;
|
|
123
117
|
const attempts = status.attempts ?? attempt?.attempt;
|
|
124
118
|
const accounting = usageAccounting(status);
|
|
125
|
-
const role = requestRole(request);
|
|
126
119
|
const error = status.error ?? attempt?.error;
|
|
127
120
|
return {
|
|
128
121
|
state: status.state,
|
|
129
122
|
...(activity === undefined ? {} : { activity: { kind: activity.kind, text: boundedText(activity.text) } }),
|
|
130
123
|
...(lastEventAt === undefined ? {} : { lastEventAt }),
|
|
131
124
|
...(model === undefined ? {} : { model: { provider: boundedText(model.provider, 256), model: boundedText(model.model, 256), ...(model.thinking === undefined ? {} : { thinking: model.thinking }) } }),
|
|
132
|
-
...(role === "none" ? {} : { role: boundedText(role, 256) }),
|
|
133
125
|
...(tools === undefined ? {} : { tools: tools.slice(0, 256).map((tool) => boundedText(tool, 256)) }),
|
|
134
126
|
...(attempts === undefined ? {} : { attempts }),
|
|
135
127
|
...(status.startedAt === undefined ? {} : { startedAt: status.startedAt }),
|
|
@@ -186,8 +178,7 @@ function standaloneActionContext(manager: SubagentManager, inspection: Inspectio
|
|
|
186
178
|
const session = attempt.session;
|
|
187
179
|
const live = liveData?.liveSession && session && liveData.liveSession.reference.transport === session.transport && liveData.liveSession.reference.sessionId === session.sessionId ? liveData.liveSession : undefined;
|
|
188
180
|
const label = request?.label?.trim();
|
|
189
|
-
const
|
|
190
|
-
const name = label || (role === "none" ? "subagent" : role);
|
|
181
|
+
const name = label || "subagent";
|
|
191
182
|
const ui = {
|
|
192
183
|
notify: (message: string, level: "info" | "warning" | "error" = "info") => { context.ui.notify(message, level); },
|
|
193
184
|
confirm: (title: string, message: string) => context.ui.confirm(title, message),
|