iosm-cli 0.2.13 → 0.2.14
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/.npmignore +2 -0
- package/CHANGELOG.md +31 -0
- package/README.md +12 -2
- package/dist/cli/args.d.ts +1 -1
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +9 -2
- package/dist/cli/args.js.map +1 -1
- package/dist/core/auth-storage.d.ts.map +1 -1
- package/dist/core/auth-storage.js +17 -2
- package/dist/core/auth-storage.js.map +1 -1
- package/dist/core/command-dispatcher.d.ts +16 -0
- package/dist/core/command-dispatcher.d.ts.map +1 -0
- package/dist/core/command-dispatcher.js +678 -0
- package/dist/core/command-dispatcher.js.map +1 -0
- package/dist/core/model-registry.d.ts.map +1 -1
- package/dist/core/model-registry.js +13 -1
- package/dist/core/model-registry.js.map +1 -1
- package/dist/core/model-resolver.d.ts +2 -2
- package/dist/core/model-resolver.d.ts.map +1 -1
- package/dist/core/model-resolver.js +1 -2
- package/dist/core/model-resolver.js.map +1 -1
- package/dist/core/provider-policy.d.ts +7 -0
- package/dist/core/provider-policy.d.ts.map +1 -0
- package/dist/core/provider-policy.js +19 -0
- package/dist/core/provider-policy.js.map +1 -0
- package/dist/core/settings-manager.d.ts +25 -0
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +32 -0
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/slash-commands.d.ts.map +1 -1
- package/dist/core/slash-commands.js +4 -1
- package/dist/core/slash-commands.js.map +1 -1
- package/dist/core/subagent-background-runs.d.ts +56 -0
- package/dist/core/subagent-background-runs.d.ts.map +1 -0
- package/dist/core/subagent-background-runs.js +275 -0
- package/dist/core/subagent-background-runs.js.map +1 -0
- package/dist/core/tools/task.d.ts.map +1 -1
- package/dist/core/tools/task.js +39 -35
- package/dist/core/tools/task.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +16 -2
- package/dist/main.js.map +1 -1
- package/dist/modes/index.d.ts +1 -0
- package/dist/modes/index.d.ts.map +1 -1
- package/dist/modes/index.js +1 -0
- package/dist/modes/index.js.map +1 -1
- package/dist/modes/interactive/components/login-dialog.d.ts +1 -1
- package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
- package/dist/modes/interactive/components/login-dialog.js +1 -4
- package/dist/modes/interactive/components/login-dialog.js.map +1 -1
- package/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/oauth-selector.js +1 -2
- package/dist/modes/interactive/components/oauth-selector.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +7 -0
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +253 -10
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-client.d.ts +11 -1
- package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-client.js +54 -0
- package/dist/modes/rpc/rpc-client.js.map +1 -1
- package/dist/modes/rpc/rpc-mode.d.ts +1 -1
- package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-mode.js +87 -3
- package/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-types.d.ts +69 -0
- package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-types.js.map +1 -1
- package/dist/modes/telegram/telegram-bridge-mode.d.ts +15 -0
- package/dist/modes/telegram/telegram-bridge-mode.d.ts.map +1 -0
- package/dist/modes/telegram/telegram-bridge-mode.js +2135 -0
- package/dist/modes/telegram/telegram-bridge-mode.js.map +1 -0
- package/docs/cli-reference.md +10 -1
- package/docs/configuration.md +21 -0
- package/docs/rpc-json-sdk.md +23 -0
- package/examples/extensions/README.md +1 -2
- package/package.json +4 -3
- package/examples/extensions/antigravity-image-gen.ts +0 -415
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
import { appendFileSync, existsSync, mkdirSync, readFileSync, readdirSync, rmSync, writeFileSync, } from "node:fs";
|
|
2
|
+
import { join, resolve } from "node:path";
|
|
3
|
+
const BACKGROUND_DIR_SEGMENTS = [".iosm", "subagents", "background"];
|
|
4
|
+
const runningControllers = new Map();
|
|
5
|
+
function isStatus(value) {
|
|
6
|
+
return value === "queued" || value === "running" || value === "done" || value === "error" || value === "cancelled";
|
|
7
|
+
}
|
|
8
|
+
function isTerminalStatus(status) {
|
|
9
|
+
return status === "done" || status === "error" || status === "cancelled";
|
|
10
|
+
}
|
|
11
|
+
function getRootKey(rootCwd) {
|
|
12
|
+
return resolve(rootCwd).toLowerCase();
|
|
13
|
+
}
|
|
14
|
+
function getBackgroundDir(rootCwd) {
|
|
15
|
+
return join(resolve(rootCwd), ...BACKGROUND_DIR_SEGMENTS);
|
|
16
|
+
}
|
|
17
|
+
function getMetaPath(rootCwd, runId) {
|
|
18
|
+
return join(getBackgroundDir(rootCwd), `${runId}.json`);
|
|
19
|
+
}
|
|
20
|
+
export function getSubagentBackgroundRunLogPath(rootCwd, runId) {
|
|
21
|
+
return join(getBackgroundDir(rootCwd), `${runId}.log`);
|
|
22
|
+
}
|
|
23
|
+
function parseRecord(metaPath) {
|
|
24
|
+
try {
|
|
25
|
+
const parsed = JSON.parse(readFileSync(metaPath, "utf8"));
|
|
26
|
+
if (typeof parsed.runId !== "string" ||
|
|
27
|
+
!isStatus(parsed.status) ||
|
|
28
|
+
typeof parsed.createdAt !== "string" ||
|
|
29
|
+
typeof parsed.description !== "string" ||
|
|
30
|
+
typeof parsed.profile !== "string" ||
|
|
31
|
+
typeof parsed.cwd !== "string") {
|
|
32
|
+
return undefined;
|
|
33
|
+
}
|
|
34
|
+
const runId = parsed.runId.trim();
|
|
35
|
+
if (!runId)
|
|
36
|
+
return undefined;
|
|
37
|
+
return {
|
|
38
|
+
runId,
|
|
39
|
+
status: parsed.status,
|
|
40
|
+
createdAt: parsed.createdAt,
|
|
41
|
+
startedAt: typeof parsed.startedAt === "string" ? parsed.startedAt : undefined,
|
|
42
|
+
finishedAt: typeof parsed.finishedAt === "string" ? parsed.finishedAt : undefined,
|
|
43
|
+
description: parsed.description,
|
|
44
|
+
profile: parsed.profile,
|
|
45
|
+
cwd: parsed.cwd,
|
|
46
|
+
agent: typeof parsed.agent === "string" && parsed.agent.trim().length > 0 ? parsed.agent : undefined,
|
|
47
|
+
model: typeof parsed.model === "string" && parsed.model.trim().length > 0 ? parsed.model : undefined,
|
|
48
|
+
error: typeof parsed.error === "string" && parsed.error.trim().length > 0 ? parsed.error : undefined,
|
|
49
|
+
transcriptPath: typeof parsed.transcriptPath === "string" && parsed.transcriptPath.trim().length > 0
|
|
50
|
+
? parsed.transcriptPath
|
|
51
|
+
: undefined,
|
|
52
|
+
requestedStopAt: typeof parsed.requestedStopAt === "string" && parsed.requestedStopAt.trim().length > 0
|
|
53
|
+
? parsed.requestedStopAt
|
|
54
|
+
: undefined,
|
|
55
|
+
logPath: typeof parsed.logPath === "string" && parsed.logPath.trim().length > 0
|
|
56
|
+
? parsed.logPath
|
|
57
|
+
: metaPath.replace(/\.json$/i, ".log"),
|
|
58
|
+
metaPath,
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
catch {
|
|
62
|
+
return undefined;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
export function getSubagentBackgroundRun(rootCwd, runId) {
|
|
66
|
+
const normalizedRunId = runId.trim();
|
|
67
|
+
if (!normalizedRunId)
|
|
68
|
+
return undefined;
|
|
69
|
+
const metaPath = getMetaPath(rootCwd, normalizedRunId);
|
|
70
|
+
if (!existsSync(metaPath))
|
|
71
|
+
return undefined;
|
|
72
|
+
return parseRecord(metaPath);
|
|
73
|
+
}
|
|
74
|
+
export function listSubagentBackgroundRuns(rootCwd, limit = 20) {
|
|
75
|
+
const dir = getBackgroundDir(rootCwd);
|
|
76
|
+
if (!existsSync(dir))
|
|
77
|
+
return [];
|
|
78
|
+
const files = readdirSync(dir)
|
|
79
|
+
.filter((name) => name.toLowerCase().endsWith(".json"))
|
|
80
|
+
.map((name) => join(dir, name))
|
|
81
|
+
.sort((a, b) => b.localeCompare(a))
|
|
82
|
+
.slice(0, Math.max(1, limit));
|
|
83
|
+
const records = [];
|
|
84
|
+
for (const file of files) {
|
|
85
|
+
const parsed = parseRecord(file);
|
|
86
|
+
if (parsed)
|
|
87
|
+
records.push(parsed);
|
|
88
|
+
}
|
|
89
|
+
records.sort((left, right) => {
|
|
90
|
+
const byTime = right.createdAt.localeCompare(left.createdAt);
|
|
91
|
+
if (byTime !== 0)
|
|
92
|
+
return byTime;
|
|
93
|
+
return right.runId.localeCompare(left.runId);
|
|
94
|
+
});
|
|
95
|
+
return records;
|
|
96
|
+
}
|
|
97
|
+
export function writeSubagentBackgroundRunStatus(rootCwd, input) {
|
|
98
|
+
try {
|
|
99
|
+
const normalizedRunId = input.runId.trim();
|
|
100
|
+
if (!normalizedRunId)
|
|
101
|
+
return undefined;
|
|
102
|
+
const dir = getBackgroundDir(rootCwd);
|
|
103
|
+
mkdirSync(dir, { recursive: true });
|
|
104
|
+
const existing = getSubagentBackgroundRun(rootCwd, normalizedRunId);
|
|
105
|
+
const metaPath = getMetaPath(rootCwd, normalizedRunId);
|
|
106
|
+
const logPath = (input.logPath?.trim() || existing?.logPath || getSubagentBackgroundRunLogPath(rootCwd, normalizedRunId)).trim();
|
|
107
|
+
const payload = {
|
|
108
|
+
runId: normalizedRunId,
|
|
109
|
+
status: input.status,
|
|
110
|
+
createdAt: input.createdAt,
|
|
111
|
+
startedAt: input.startedAt,
|
|
112
|
+
finishedAt: input.finishedAt,
|
|
113
|
+
description: input.description,
|
|
114
|
+
profile: input.profile,
|
|
115
|
+
cwd: input.cwd,
|
|
116
|
+
agent: input.agent,
|
|
117
|
+
model: input.model,
|
|
118
|
+
error: input.error,
|
|
119
|
+
transcriptPath: input.transcriptPath,
|
|
120
|
+
requestedStopAt: input.requestedStopAt ?? existing?.requestedStopAt,
|
|
121
|
+
logPath,
|
|
122
|
+
};
|
|
123
|
+
writeFileSync(metaPath, `${JSON.stringify(payload, null, 2)}\n`, "utf8");
|
|
124
|
+
return metaPath;
|
|
125
|
+
}
|
|
126
|
+
catch {
|
|
127
|
+
return undefined;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
export function appendSubagentBackgroundRunLog(rootCwd, runId, message) {
|
|
131
|
+
try {
|
|
132
|
+
const normalizedRunId = runId.trim();
|
|
133
|
+
if (!normalizedRunId)
|
|
134
|
+
return undefined;
|
|
135
|
+
const dir = getBackgroundDir(rootCwd);
|
|
136
|
+
mkdirSync(dir, { recursive: true });
|
|
137
|
+
const logPath = getSubagentBackgroundRunLogPath(rootCwd, normalizedRunId);
|
|
138
|
+
const line = `[${new Date().toISOString()}] ${message}\n`;
|
|
139
|
+
appendFileSync(logPath, line, "utf8");
|
|
140
|
+
return logPath;
|
|
141
|
+
}
|
|
142
|
+
catch {
|
|
143
|
+
return undefined;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
export function readSubagentBackgroundRunLogTail(rootCwd, runId, lines = 120) {
|
|
147
|
+
const record = getSubagentBackgroundRun(rootCwd, runId);
|
|
148
|
+
if (!record)
|
|
149
|
+
return undefined;
|
|
150
|
+
const maxLines = Math.max(1, Math.min(1000, Math.floor(lines)));
|
|
151
|
+
if (!existsSync(record.logPath))
|
|
152
|
+
return "";
|
|
153
|
+
try {
|
|
154
|
+
const content = readFileSync(record.logPath, "utf8");
|
|
155
|
+
const entries = content.split(/\r?\n/);
|
|
156
|
+
while (entries.length > 0 && entries[entries.length - 1] === "") {
|
|
157
|
+
entries.pop();
|
|
158
|
+
}
|
|
159
|
+
return entries.slice(-maxLines).join("\n");
|
|
160
|
+
}
|
|
161
|
+
catch {
|
|
162
|
+
return "";
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
export function registerSubagentBackgroundRunController(rootCwd, runId, controller) {
|
|
166
|
+
const normalizedRunId = runId.trim();
|
|
167
|
+
if (!normalizedRunId)
|
|
168
|
+
return;
|
|
169
|
+
const rootKey = getRootKey(rootCwd);
|
|
170
|
+
const byRun = runningControllers.get(rootKey) ?? new Map();
|
|
171
|
+
byRun.set(normalizedRunId, controller);
|
|
172
|
+
runningControllers.set(rootKey, byRun);
|
|
173
|
+
}
|
|
174
|
+
export function unregisterSubagentBackgroundRunController(rootCwd, runId) {
|
|
175
|
+
const normalizedRunId = runId.trim();
|
|
176
|
+
if (!normalizedRunId)
|
|
177
|
+
return;
|
|
178
|
+
const rootKey = getRootKey(rootCwd);
|
|
179
|
+
const byRun = runningControllers.get(rootKey);
|
|
180
|
+
if (!byRun)
|
|
181
|
+
return;
|
|
182
|
+
byRun.delete(normalizedRunId);
|
|
183
|
+
if (byRun.size === 0) {
|
|
184
|
+
runningControllers.delete(rootKey);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
function getController(rootCwd, runId) {
|
|
188
|
+
const rootKey = getRootKey(rootCwd);
|
|
189
|
+
const byRun = runningControllers.get(rootKey);
|
|
190
|
+
if (!byRun)
|
|
191
|
+
return undefined;
|
|
192
|
+
return byRun.get(runId.trim());
|
|
193
|
+
}
|
|
194
|
+
export function requestStopSubagentBackgroundRun(rootCwd, runId) {
|
|
195
|
+
const normalizedRunId = runId.trim();
|
|
196
|
+
if (!normalizedRunId)
|
|
197
|
+
return undefined;
|
|
198
|
+
const current = getSubagentBackgroundRun(rootCwd, normalizedRunId);
|
|
199
|
+
if (!current)
|
|
200
|
+
return undefined;
|
|
201
|
+
if (!isTerminalStatus(current.status)) {
|
|
202
|
+
const requestedStopAt = new Date().toISOString();
|
|
203
|
+
writeSubagentBackgroundRunStatus(rootCwd, {
|
|
204
|
+
runId: current.runId,
|
|
205
|
+
status: current.status,
|
|
206
|
+
createdAt: current.createdAt,
|
|
207
|
+
startedAt: current.startedAt,
|
|
208
|
+
finishedAt: current.finishedAt,
|
|
209
|
+
description: current.description,
|
|
210
|
+
profile: current.profile,
|
|
211
|
+
cwd: current.cwd,
|
|
212
|
+
agent: current.agent,
|
|
213
|
+
model: current.model,
|
|
214
|
+
error: current.error,
|
|
215
|
+
transcriptPath: current.transcriptPath,
|
|
216
|
+
requestedStopAt,
|
|
217
|
+
logPath: current.logPath,
|
|
218
|
+
});
|
|
219
|
+
appendSubagentBackgroundRunLog(rootCwd, normalizedRunId, "stop requested");
|
|
220
|
+
}
|
|
221
|
+
const controller = getController(rootCwd, normalizedRunId);
|
|
222
|
+
controller?.abort();
|
|
223
|
+
return getSubagentBackgroundRun(rootCwd, normalizedRunId);
|
|
224
|
+
}
|
|
225
|
+
export function requestStopAllSubagentBackgroundRuns(rootCwd) {
|
|
226
|
+
const records = listSubagentBackgroundRuns(rootCwd, 500).filter((record) => !isTerminalStatus(record.status));
|
|
227
|
+
const requestedIds = [];
|
|
228
|
+
for (const record of records) {
|
|
229
|
+
const updated = requestStopSubagentBackgroundRun(rootCwd, record.runId);
|
|
230
|
+
if (updated)
|
|
231
|
+
requestedIds.push(updated.runId);
|
|
232
|
+
}
|
|
233
|
+
return {
|
|
234
|
+
requested: requestedIds.length,
|
|
235
|
+
requestedIds,
|
|
236
|
+
};
|
|
237
|
+
}
|
|
238
|
+
export function pruneSubagentBackgroundRuns(rootCwd, olderThanHours = 24) {
|
|
239
|
+
const thresholdHours = Number.isFinite(olderThanHours) ? Math.max(1, Math.floor(olderThanHours)) : 24;
|
|
240
|
+
const thresholdMs = thresholdHours * 60 * 60 * 1000;
|
|
241
|
+
const nowMs = Date.now();
|
|
242
|
+
const records = listSubagentBackgroundRuns(rootCwd, 1000);
|
|
243
|
+
const removedIds = [];
|
|
244
|
+
let skippedRunning = 0;
|
|
245
|
+
let skippedRecent = 0;
|
|
246
|
+
for (const record of records) {
|
|
247
|
+
if (!isTerminalStatus(record.status)) {
|
|
248
|
+
skippedRunning += 1;
|
|
249
|
+
continue;
|
|
250
|
+
}
|
|
251
|
+
const anchor = Date.parse(record.finishedAt ?? record.createdAt);
|
|
252
|
+
if (!Number.isFinite(anchor) || nowMs - anchor < thresholdMs) {
|
|
253
|
+
skippedRecent += 1;
|
|
254
|
+
continue;
|
|
255
|
+
}
|
|
256
|
+
try {
|
|
257
|
+
rmSync(record.metaPath, { force: true });
|
|
258
|
+
if (record.logPath && existsSync(record.logPath)) {
|
|
259
|
+
rmSync(record.logPath, { force: true });
|
|
260
|
+
}
|
|
261
|
+
removedIds.push(record.runId);
|
|
262
|
+
}
|
|
263
|
+
catch {
|
|
264
|
+
// best effort
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
return {
|
|
268
|
+
removed: removedIds.length,
|
|
269
|
+
removedIds,
|
|
270
|
+
skippedRunning,
|
|
271
|
+
skippedRecent,
|
|
272
|
+
thresholdHours,
|
|
273
|
+
};
|
|
274
|
+
}
|
|
275
|
+
//# sourceMappingURL=subagent-background-runs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"subagent-background-runs.js","sourceRoot":"","sources":["../../src/core/subagent-background-runs.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n\tappendFileSync,\n\texistsSync,\n\tmkdirSync,\n\treadFileSync,\n\treaddirSync,\n\trmSync,\n\twriteFileSync,\n} from \"node:fs\";\nimport { join, resolve } from \"node:path\";\n\nexport type SubagentBackgroundRunStatus = \"queued\" | \"running\" | \"done\" | \"error\" | \"cancelled\";\n\nexport interface SubagentBackgroundRunRecord {\n\trunId: string;\n\tstatus: SubagentBackgroundRunStatus;\n\tcreatedAt: string;\n\tstartedAt?: string;\n\tfinishedAt?: string;\n\tdescription: string;\n\tprofile: string;\n\tcwd: string;\n\tagent?: string;\n\tmodel?: string;\n\terror?: string;\n\ttranscriptPath?: string;\n\trequestedStopAt?: string;\n\tlogPath: string;\n\tmetaPath: string;\n}\n\nexport interface WriteSubagentBackgroundRunStatusInput {\n\trunId: string;\n\tstatus: SubagentBackgroundRunStatus;\n\tcreatedAt: string;\n\tstartedAt?: string;\n\tfinishedAt?: string;\n\tdescription: string;\n\tprofile: string;\n\tcwd: string;\n\tagent?: string;\n\tmodel?: string;\n\terror?: string;\n\ttranscriptPath?: string;\n\trequestedStopAt?: string;\n\tlogPath?: string;\n}\n\nexport interface PruneSubagentBackgroundRunsResult {\n\tremoved: number;\n\tremovedIds: string[];\n\tskippedRunning: number;\n\tskippedRecent: number;\n\tthresholdHours: number;\n}\n\nconst BACKGROUND_DIR_SEGMENTS = [\".iosm\", \"subagents\", \"background\"] as const;\n\nconst runningControllers = new Map<string, Map<string, AbortController>>();\n\nfunction isStatus(value: unknown): value is SubagentBackgroundRunStatus {\n\treturn value === \"queued\" || value === \"running\" || value === \"done\" || value === \"error\" || value === \"cancelled\";\n}\n\nfunction isTerminalStatus(status: SubagentBackgroundRunStatus): boolean {\n\treturn status === \"done\" || status === \"error\" || status === \"cancelled\";\n}\n\nfunction getRootKey(rootCwd: string): string {\n\treturn resolve(rootCwd).toLowerCase();\n}\n\nfunction getBackgroundDir(rootCwd: string): string {\n\treturn join(resolve(rootCwd), ...BACKGROUND_DIR_SEGMENTS);\n}\n\nfunction getMetaPath(rootCwd: string, runId: string): string {\n\treturn join(getBackgroundDir(rootCwd), `${runId}.json`);\n}\n\nexport function getSubagentBackgroundRunLogPath(rootCwd: string, runId: string): string {\n\treturn join(getBackgroundDir(rootCwd), `${runId}.log`);\n}\n\nfunction parseRecord(metaPath: string): SubagentBackgroundRunRecord | undefined {\n\ttry {\n\t\tconst parsed = JSON.parse(readFileSync(metaPath, \"utf8\")) as Partial<SubagentBackgroundRunRecord>;\n\t\tif (\n\t\t\ttypeof parsed.runId !== \"string\" ||\n\t\t\t!isStatus(parsed.status) ||\n\t\t\ttypeof parsed.createdAt !== \"string\" ||\n\t\t\ttypeof parsed.description !== \"string\" ||\n\t\t\ttypeof parsed.profile !== \"string\" ||\n\t\t\ttypeof parsed.cwd !== \"string\"\n\t\t) {\n\t\t\treturn undefined;\n\t\t}\n\t\tconst runId = parsed.runId.trim();\n\t\tif (!runId) return undefined;\n\t\treturn {\n\t\t\trunId,\n\t\t\tstatus: parsed.status,\n\t\t\tcreatedAt: parsed.createdAt,\n\t\t\tstartedAt: typeof parsed.startedAt === \"string\" ? parsed.startedAt : undefined,\n\t\t\tfinishedAt: typeof parsed.finishedAt === \"string\" ? parsed.finishedAt : undefined,\n\t\t\tdescription: parsed.description,\n\t\t\tprofile: parsed.profile,\n\t\t\tcwd: parsed.cwd,\n\t\t\tagent: typeof parsed.agent === \"string\" && parsed.agent.trim().length > 0 ? parsed.agent : undefined,\n\t\t\tmodel: typeof parsed.model === \"string\" && parsed.model.trim().length > 0 ? parsed.model : undefined,\n\t\t\terror: typeof parsed.error === \"string\" && parsed.error.trim().length > 0 ? parsed.error : undefined,\n\t\t\ttranscriptPath:\n\t\t\t\ttypeof parsed.transcriptPath === \"string\" && parsed.transcriptPath.trim().length > 0\n\t\t\t\t\t? parsed.transcriptPath\n\t\t\t\t\t: undefined,\n\t\t\trequestedStopAt:\n\t\t\t\ttypeof parsed.requestedStopAt === \"string\" && parsed.requestedStopAt.trim().length > 0\n\t\t\t\t\t? parsed.requestedStopAt\n\t\t\t\t\t: undefined,\n\t\t\tlogPath:\n\t\t\t\ttypeof parsed.logPath === \"string\" && parsed.logPath.trim().length > 0\n\t\t\t\t\t? parsed.logPath\n\t\t\t\t\t: metaPath.replace(/\\.json$/i, \".log\"),\n\t\t\tmetaPath,\n\t\t};\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\nexport function getSubagentBackgroundRun(rootCwd: string, runId: string): SubagentBackgroundRunRecord | undefined {\n\tconst normalizedRunId = runId.trim();\n\tif (!normalizedRunId) return undefined;\n\tconst metaPath = getMetaPath(rootCwd, normalizedRunId);\n\tif (!existsSync(metaPath)) return undefined;\n\treturn parseRecord(metaPath);\n}\n\nexport function listSubagentBackgroundRuns(rootCwd: string, limit = 20): SubagentBackgroundRunRecord[] {\n\tconst dir = getBackgroundDir(rootCwd);\n\tif (!existsSync(dir)) return [];\n\tconst files = readdirSync(dir)\n\t\t.filter((name) => name.toLowerCase().endsWith(\".json\"))\n\t\t.map((name) => join(dir, name))\n\t\t.sort((a, b) => b.localeCompare(a))\n\t\t.slice(0, Math.max(1, limit));\n\n\tconst records: SubagentBackgroundRunRecord[] = [];\n\tfor (const file of files) {\n\t\tconst parsed = parseRecord(file);\n\t\tif (parsed) records.push(parsed);\n\t}\n\trecords.sort((left, right) => {\n\t\tconst byTime = right.createdAt.localeCompare(left.createdAt);\n\t\tif (byTime !== 0) return byTime;\n\t\treturn right.runId.localeCompare(left.runId);\n\t});\n\treturn records;\n}\n\nexport function writeSubagentBackgroundRunStatus(\n\trootCwd: string,\n\tinput: WriteSubagentBackgroundRunStatusInput,\n): string | undefined {\n\ttry {\n\t\tconst normalizedRunId = input.runId.trim();\n\t\tif (!normalizedRunId) return undefined;\n\t\tconst dir = getBackgroundDir(rootCwd);\n\t\tmkdirSync(dir, { recursive: true });\n\t\tconst existing = getSubagentBackgroundRun(rootCwd, normalizedRunId);\n\t\tconst metaPath = getMetaPath(rootCwd, normalizedRunId);\n\t\tconst logPath = (input.logPath?.trim() || existing?.logPath || getSubagentBackgroundRunLogPath(rootCwd, normalizedRunId)).trim();\n\t\tconst payload = {\n\t\t\trunId: normalizedRunId,\n\t\t\tstatus: input.status,\n\t\t\tcreatedAt: input.createdAt,\n\t\t\tstartedAt: input.startedAt,\n\t\t\tfinishedAt: input.finishedAt,\n\t\t\tdescription: input.description,\n\t\t\tprofile: input.profile,\n\t\t\tcwd: input.cwd,\n\t\t\tagent: input.agent,\n\t\t\tmodel: input.model,\n\t\t\terror: input.error,\n\t\t\ttranscriptPath: input.transcriptPath,\n\t\t\trequestedStopAt: input.requestedStopAt ?? existing?.requestedStopAt,\n\t\t\tlogPath,\n\t\t};\n\t\twriteFileSync(metaPath, `${JSON.stringify(payload, null, 2)}\\n`, \"utf8\");\n\t\treturn metaPath;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\nexport function appendSubagentBackgroundRunLog(rootCwd: string, runId: string, message: string): string | undefined {\n\ttry {\n\t\tconst normalizedRunId = runId.trim();\n\t\tif (!normalizedRunId) return undefined;\n\t\tconst dir = getBackgroundDir(rootCwd);\n\t\tmkdirSync(dir, { recursive: true });\n\t\tconst logPath = getSubagentBackgroundRunLogPath(rootCwd, normalizedRunId);\n\t\tconst line = `[${new Date().toISOString()}] ${message}\\n`;\n\t\tappendFileSync(logPath, line, \"utf8\");\n\t\treturn logPath;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\nexport function readSubagentBackgroundRunLogTail(rootCwd: string, runId: string, lines = 120): string | undefined {\n\tconst record = getSubagentBackgroundRun(rootCwd, runId);\n\tif (!record) return undefined;\n\tconst maxLines = Math.max(1, Math.min(1000, Math.floor(lines)));\n\tif (!existsSync(record.logPath)) return \"\";\n\ttry {\n\t\tconst content = readFileSync(record.logPath, \"utf8\");\n\t\tconst entries = content.split(/\\r?\\n/);\n\t\twhile (entries.length > 0 && entries[entries.length - 1] === \"\") {\n\t\t\tentries.pop();\n\t\t}\n\t\treturn entries.slice(-maxLines).join(\"\\n\");\n\t} catch {\n\t\treturn \"\";\n\t}\n}\n\nexport function registerSubagentBackgroundRunController(rootCwd: string, runId: string, controller: AbortController): void {\n\tconst normalizedRunId = runId.trim();\n\tif (!normalizedRunId) return;\n\tconst rootKey = getRootKey(rootCwd);\n\tconst byRun = runningControllers.get(rootKey) ?? new Map<string, AbortController>();\n\tbyRun.set(normalizedRunId, controller);\n\trunningControllers.set(rootKey, byRun);\n}\n\nexport function unregisterSubagentBackgroundRunController(rootCwd: string, runId: string): void {\n\tconst normalizedRunId = runId.trim();\n\tif (!normalizedRunId) return;\n\tconst rootKey = getRootKey(rootCwd);\n\tconst byRun = runningControllers.get(rootKey);\n\tif (!byRun) return;\n\tbyRun.delete(normalizedRunId);\n\tif (byRun.size === 0) {\n\t\trunningControllers.delete(rootKey);\n\t}\n}\n\nfunction getController(rootCwd: string, runId: string): AbortController | undefined {\n\tconst rootKey = getRootKey(rootCwd);\n\tconst byRun = runningControllers.get(rootKey);\n\tif (!byRun) return undefined;\n\treturn byRun.get(runId.trim());\n}\n\nexport function requestStopSubagentBackgroundRun(\n\trootCwd: string,\n\trunId: string,\n): SubagentBackgroundRunRecord | undefined {\n\tconst normalizedRunId = runId.trim();\n\tif (!normalizedRunId) return undefined;\n\tconst current = getSubagentBackgroundRun(rootCwd, normalizedRunId);\n\tif (!current) return undefined;\n\tif (!isTerminalStatus(current.status)) {\n\t\tconst requestedStopAt = new Date().toISOString();\n\t\twriteSubagentBackgroundRunStatus(rootCwd, {\n\t\t\trunId: current.runId,\n\t\t\tstatus: current.status,\n\t\t\tcreatedAt: current.createdAt,\n\t\t\tstartedAt: current.startedAt,\n\t\t\tfinishedAt: current.finishedAt,\n\t\t\tdescription: current.description,\n\t\t\tprofile: current.profile,\n\t\t\tcwd: current.cwd,\n\t\t\tagent: current.agent,\n\t\t\tmodel: current.model,\n\t\t\terror: current.error,\n\t\t\ttranscriptPath: current.transcriptPath,\n\t\t\trequestedStopAt,\n\t\t\tlogPath: current.logPath,\n\t\t});\n\t\tappendSubagentBackgroundRunLog(rootCwd, normalizedRunId, \"stop requested\");\n\t}\n\tconst controller = getController(rootCwd, normalizedRunId);\n\tcontroller?.abort();\n\treturn getSubagentBackgroundRun(rootCwd, normalizedRunId);\n}\n\nexport function requestStopAllSubagentBackgroundRuns(rootCwd: string): {\n\trequested: number;\n\trequestedIds: string[];\n} {\n\tconst records = listSubagentBackgroundRuns(rootCwd, 500).filter((record) => !isTerminalStatus(record.status));\n\tconst requestedIds: string[] = [];\n\tfor (const record of records) {\n\t\tconst updated = requestStopSubagentBackgroundRun(rootCwd, record.runId);\n\t\tif (updated) requestedIds.push(updated.runId);\n\t}\n\treturn {\n\t\trequested: requestedIds.length,\n\t\trequestedIds,\n\t};\n}\n\nexport function pruneSubagentBackgroundRuns(\n\trootCwd: string,\n\tolderThanHours = 24,\n): PruneSubagentBackgroundRunsResult {\n\tconst thresholdHours = Number.isFinite(olderThanHours) ? Math.max(1, Math.floor(olderThanHours)) : 24;\n\tconst thresholdMs = thresholdHours * 60 * 60 * 1000;\n\tconst nowMs = Date.now();\n\tconst records = listSubagentBackgroundRuns(rootCwd, 1000);\n\tconst removedIds: string[] = [];\n\tlet skippedRunning = 0;\n\tlet skippedRecent = 0;\n\n\tfor (const record of records) {\n\t\tif (!isTerminalStatus(record.status)) {\n\t\t\tskippedRunning += 1;\n\t\t\tcontinue;\n\t\t}\n\t\tconst anchor = Date.parse(record.finishedAt ?? record.createdAt);\n\t\tif (!Number.isFinite(anchor) || nowMs - anchor < thresholdMs) {\n\t\t\tskippedRecent += 1;\n\t\t\tcontinue;\n\t\t}\n\t\ttry {\n\t\t\trmSync(record.metaPath, { force: true });\n\t\t\tif (record.logPath && existsSync(record.logPath)) {\n\t\t\t\trmSync(record.logPath, { force: true });\n\t\t\t}\n\t\t\tremovedIds.push(record.runId);\n\t\t} catch {\n\t\t\t// best effort\n\t\t}\n\t}\n\n\treturn {\n\t\tremoved: removedIds.length,\n\t\tremovedIds,\n\t\tskippedRunning,\n\t\tskippedRecent,\n\t\tthresholdHours,\n\t};\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"task.d.ts","sourceRoot":"","sources":["../../../src/core/tools/task.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,EAAE,KAAK,MAAM,EAAQ,MAAM,mBAAmB,CAAC;AAEtD,OAAO,EAKN,KAAK,YAAY,EACjB,MAAM,6BAA6B,CAAC;AAcrC,OAAO,EAEN,KAAK,mBAAmB,EAGxB,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"task.d.ts","sourceRoot":"","sources":["../../../src/core/tools/task.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,EAAE,KAAK,MAAM,EAAQ,MAAM,mBAAmB,CAAC;AAEtD,OAAO,EAKN,KAAK,YAAY,EACjB,MAAM,6BAA6B,CAAC;AAcrC,OAAO,EAEN,KAAK,mBAAmB,EAGxB,MAAM,qBAAqB,CAAC;AAO7B,OAAO,EAAkD,KAAK,wBAAwB,EAAE,MAAM,iBAAiB,CAAC;AAEhH;;;GAGG;AACH,MAAM,MAAM,iBAAiB,GAAG;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE;QACP,gBAAgB,EAAE,MAAM,CAAC;QACzB,kBAAkB,EAAE,MAAM,CAAC;QAC3B,iBAAiB,EAAE,MAAM,CAAC;KAC1B,CAAC;CACF,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG,QAAQ,GAAG,UAAU,GAAG,SAAS,GAAG,YAAY,CAAC;AAErF,MAAM,MAAM,0BAA0B,GAAG,SAAS,GAAG,SAAS,GAAG,MAAM,GAAG,QAAQ,CAAC;AAEnF,MAAM,WAAW,wBAAwB;IACxC,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,0BAA0B,CAAC;CACnC;AAED,MAAM,WAAW,gBAAgB;IAChC,IAAI,EAAE,mBAAmB,CAAC;IAC1B,KAAK,EAAE,qBAAqB,CAAC;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,aAAa,CAAC,EAAE,wBAAwB,EAAE,CAAC;CAC3C;AAED,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,EAAE;IACtC,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,mBAAmB,CAAC,EAAE,mBAAmB,CAAC;IAC1C,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,gBAAgB,KAAK,IAAI,CAAC;CAClD,KAAK,OAAO,CAAC,MAAM,GAAG,iBAAiB,CAAC,CAAC;AAE1C,QAAA,MAAM,UAAU;;;;;;;;;;;;;;;EAsFd,CAAC;AAEH,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC,OAAO,UAAU,CAAC,CAAC;AAEtD,yDAAyD;AACzD,MAAM,WAAW,eAAe;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,GAAG,UAAU,CAAC;IAChC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,aAAa,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC,CAAC;IACtD,YAAY,CAAC,EAAE;QACd,kBAAkB,CAAC,EAAE,MAAM,CAAC;QAC5B,iBAAiB,CAAC,EAAE,MAAM,CAAC;QAC3B,yBAAyB,CAAC,EAAE,MAAM,CAAC;QACnC,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,kBAAkB,CAAC,EAAE,MAAM,CAAC;QAC5B,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAC1B,eAAe,CAAC,EAAE,MAAM,CAAC;KACzB,CAAC;IACF,sBAAsB,CAAC,EAAE,MAAM,CAAC;CAChC;AAED,MAAM,WAAW,eAAe;IAC/B,qBAAqB,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,wBAAwB,GAAG,SAAS,CAAC;IAC/E,wBAAwB,CAAC,EAAE,MAAM,EAAE,CAAC;IACpC,4BAA4B,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC5E,2GAA2G;IAC3G,qBAAqB,CAAC,EAAE,MAAM,SAAS,MAAM,EAAE,CAAC;IAChD,sEAAsE;IACtE,eAAe,CAAC,EAAE,MAAM,SAAS,MAAM,EAAE,CAAC;IAC1C,2FAA2F;IAC3F,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,6GAA6G;IAC7G,kBAAkB,CAAC,EAAE,MAAM,MAAM,GAAG,SAAS,CAAC;CAC9C;AA2mCD;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAC7B,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,cAAc,EACtB,OAAO,CAAC,EAAE,eAAe,GACvB,SAAS,CAAC,OAAO,UAAU,CAAC,CAsqE9B"}
|
package/dist/core/tools/task.js
CHANGED
|
@@ -7,6 +7,7 @@ import { buildRetrospectiveDirective, classifyFailureCause, formatFailureCauseCo
|
|
|
7
7
|
import { MAX_ORCHESTRATION_AGENTS, MAX_ORCHESTRATION_PARALLEL, MAX_SUBAGENT_DELEGATE_PARALLEL, MAX_SUBAGENT_DELEGATION_DEPTH, MAX_SUBAGENT_DELEGATIONS_PER_TASK, } from "../orchestration-limits.js";
|
|
8
8
|
import { AGENT_PROFILES, isReadOnlyProfileName, isValidProfileName, } from "../agent-profiles.js";
|
|
9
9
|
import { readSharedMemory, summarizeSharedMemoryUsage, writeSharedMemory, } from "../shared-memory.js";
|
|
10
|
+
import { appendSubagentBackgroundRunLog, registerSubagentBackgroundRunController, unregisterSubagentBackgroundRunController, writeSubagentBackgroundRunStatus, } from "../subagent-background-runs.js";
|
|
10
11
|
import { normalizeAndFilterToolNames, normalizeToolName } from "../subagents.js";
|
|
11
12
|
const taskSchema = Type.Object({
|
|
12
13
|
description: Type.Optional(Type.String({
|
|
@@ -959,18 +960,6 @@ function persistSubagentTranscript(input) {
|
|
|
959
960
|
return undefined;
|
|
960
961
|
}
|
|
961
962
|
}
|
|
962
|
-
function writeBackgroundRunStatus(rootCwd, status) {
|
|
963
|
-
try {
|
|
964
|
-
const dir = path.join(rootCwd, ".iosm", "subagents", "background");
|
|
965
|
-
mkdirSync(dir, { recursive: true });
|
|
966
|
-
const filePath = path.join(dir, `${status.runId}.json`);
|
|
967
|
-
writeFileSync(filePath, `${JSON.stringify(status, null, 2)}\n`, "utf8");
|
|
968
|
-
return filePath;
|
|
969
|
-
}
|
|
970
|
-
catch {
|
|
971
|
-
return undefined;
|
|
972
|
-
}
|
|
973
|
-
}
|
|
974
963
|
function gitResult(args, cwd) {
|
|
975
964
|
const result = spawnSync("git", args, {
|
|
976
965
|
cwd,
|
|
@@ -1048,6 +1037,7 @@ export function createTaskTool(cwd, runner, options) {
|
|
|
1048
1037
|
customAgentsSnippet,
|
|
1049
1038
|
parameters: taskSchema,
|
|
1050
1039
|
execute: async (_toolCallId, { description: rawDescription, task: rawTask, args: rawArgs, prompt: rawPrompt, agent: agentName, profile, cwd: targetCwd, lock_key: lockKey, run_id: orchestrationRunId, task_id: orchestrationTaskId, model: requestedModel, background, isolation, delegate_parallel_hint: delegateParallelHint, }, _signal, onUpdate) => {
|
|
1040
|
+
let runtimeAbortSignal = _signal;
|
|
1051
1041
|
const updateTrackedTaskStatus = (status) => {
|
|
1052
1042
|
if (!orchestrationRunId || !orchestrationTaskId)
|
|
1053
1043
|
return;
|
|
@@ -1059,7 +1049,7 @@ export function createTaskTool(cwd, runner, options) {
|
|
|
1059
1049
|
});
|
|
1060
1050
|
};
|
|
1061
1051
|
const throwIfAborted = () => {
|
|
1062
|
-
if (
|
|
1052
|
+
if (runtimeAbortSignal?.aborted) {
|
|
1063
1053
|
updateTrackedTaskStatus("cancelled");
|
|
1064
1054
|
throw new Error("Operation aborted");
|
|
1065
1055
|
}
|
|
@@ -1281,7 +1271,7 @@ export function createTaskTool(cwd, runner, options) {
|
|
|
1281
1271
|
cwd,
|
|
1282
1272
|
runId: orchestrationRunId,
|
|
1283
1273
|
taskId: orchestrationTaskId,
|
|
1284
|
-
signal:
|
|
1274
|
+
signal: runtimeAbortSignal,
|
|
1285
1275
|
onWaiting: (waiting) => {
|
|
1286
1276
|
emitProgress({
|
|
1287
1277
|
kind: "subagent_progress",
|
|
@@ -1294,7 +1284,7 @@ export function createTaskTool(cwd, runner, options) {
|
|
|
1294
1284
|
});
|
|
1295
1285
|
}
|
|
1296
1286
|
catch (error) {
|
|
1297
|
-
if (
|
|
1287
|
+
if (runtimeAbortSignal?.aborted || isAbortError(error)) {
|
|
1298
1288
|
updateTrackedTaskStatus("cancelled");
|
|
1299
1289
|
throw new Error("Operation aborted");
|
|
1300
1290
|
}
|
|
@@ -1388,7 +1378,7 @@ export function createTaskTool(cwd, runner, options) {
|
|
|
1388
1378
|
value: payload,
|
|
1389
1379
|
scope: "run",
|
|
1390
1380
|
mode: "set",
|
|
1391
|
-
},
|
|
1381
|
+
}, runtimeAbortSignal);
|
|
1392
1382
|
}
|
|
1393
1383
|
catch (error) {
|
|
1394
1384
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -1417,7 +1407,7 @@ export function createTaskTool(cwd, runner, options) {
|
|
|
1417
1407
|
value: payload,
|
|
1418
1408
|
scope: "run",
|
|
1419
1409
|
mode: "set",
|
|
1420
|
-
},
|
|
1410
|
+
}, runtimeAbortSignal);
|
|
1421
1411
|
}
|
|
1422
1412
|
catch (error) {
|
|
1423
1413
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -1437,7 +1427,7 @@ export function createTaskTool(cwd, runner, options) {
|
|
|
1437
1427
|
scope: "run",
|
|
1438
1428
|
key,
|
|
1439
1429
|
includeValues: true,
|
|
1440
|
-
},
|
|
1430
|
+
}, runtimeAbortSignal);
|
|
1441
1431
|
const current = snapshot.items[0];
|
|
1442
1432
|
if (!current) {
|
|
1443
1433
|
await writeSharedMemory(rootSharedMemoryContext, {
|
|
@@ -1449,7 +1439,7 @@ export function createTaskTool(cwd, runner, options) {
|
|
|
1449
1439
|
}),
|
|
1450
1440
|
scope: "run",
|
|
1451
1441
|
mode: "set",
|
|
1452
|
-
},
|
|
1442
|
+
}, runtimeAbortSignal);
|
|
1453
1443
|
lastError = undefined;
|
|
1454
1444
|
break;
|
|
1455
1445
|
}
|
|
@@ -1482,7 +1472,7 @@ export function createTaskTool(cwd, runner, options) {
|
|
|
1482
1472
|
scope: "run",
|
|
1483
1473
|
mode: "set",
|
|
1484
1474
|
ifVersion: current.version,
|
|
1485
|
-
},
|
|
1475
|
+
}, runtimeAbortSignal);
|
|
1486
1476
|
lastError = undefined;
|
|
1487
1477
|
break;
|
|
1488
1478
|
}
|
|
@@ -1516,7 +1506,7 @@ export function createTaskTool(cwd, runner, options) {
|
|
|
1516
1506
|
cwd: subagentCwd,
|
|
1517
1507
|
modelOverride: effectiveModelOverride,
|
|
1518
1508
|
sharedMemoryContext: rootSharedMemoryContext,
|
|
1519
|
-
signal:
|
|
1509
|
+
signal: runtimeAbortSignal,
|
|
1520
1510
|
onProgress: (progress) => emitProgress(progress),
|
|
1521
1511
|
});
|
|
1522
1512
|
throwIfAborted();
|
|
@@ -1555,7 +1545,7 @@ export function createTaskTool(cwd, runner, options) {
|
|
|
1555
1545
|
});
|
|
1556
1546
|
}
|
|
1557
1547
|
catch (error) {
|
|
1558
|
-
if (
|
|
1548
|
+
if (runtimeAbortSignal?.aborted || isAbortError(error)) {
|
|
1559
1549
|
throw new Error("Operation aborted");
|
|
1560
1550
|
}
|
|
1561
1551
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -1857,7 +1847,7 @@ export function createTaskTool(cwd, runner, options) {
|
|
|
1857
1847
|
cwd: nestedCwd,
|
|
1858
1848
|
modelOverride: nestedModelOverride,
|
|
1859
1849
|
sharedMemoryContext: nestedSharedMemoryContext,
|
|
1860
|
-
signal:
|
|
1850
|
+
signal: runtimeAbortSignal,
|
|
1861
1851
|
onProgress: (progress) => {
|
|
1862
1852
|
emitProgress({
|
|
1863
1853
|
kind: "subagent_progress",
|
|
@@ -2105,7 +2095,7 @@ export function createTaskTool(cwd, runner, options) {
|
|
|
2105
2095
|
cwd: childCwd,
|
|
2106
2096
|
modelOverride: childModelOverride,
|
|
2107
2097
|
sharedMemoryContext: childSharedMemoryContext,
|
|
2108
|
-
signal:
|
|
2098
|
+
signal: runtimeAbortSignal,
|
|
2109
2099
|
onProgress: (progress) => {
|
|
2110
2100
|
emitProgress({
|
|
2111
2101
|
kind: "subagent_progress",
|
|
@@ -2157,7 +2147,7 @@ export function createTaskTool(cwd, runner, options) {
|
|
|
2157
2147
|
});
|
|
2158
2148
|
}
|
|
2159
2149
|
catch (error) {
|
|
2160
|
-
if (
|
|
2150
|
+
if (runtimeAbortSignal?.aborted || isAbortError(error)) {
|
|
2161
2151
|
throw new Error("Operation aborted");
|
|
2162
2152
|
}
|
|
2163
2153
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -2299,7 +2289,7 @@ export function createTaskTool(cwd, runner, options) {
|
|
|
2299
2289
|
}
|
|
2300
2290
|
catch (error) {
|
|
2301
2291
|
const message = error instanceof Error ? error.message : String(error);
|
|
2302
|
-
if (
|
|
2292
|
+
if (runtimeAbortSignal?.aborted || isAbortError(error)) {
|
|
2303
2293
|
throw new Error("Operation aborted");
|
|
2304
2294
|
}
|
|
2305
2295
|
const classified = error && typeof error === "object" && "failureCause" in error
|
|
@@ -2375,7 +2365,7 @@ export function createTaskTool(cwd, runner, options) {
|
|
|
2375
2365
|
}
|
|
2376
2366
|
catch (error) {
|
|
2377
2367
|
const message = error instanceof Error ? error.message : String(error);
|
|
2378
|
-
if (
|
|
2368
|
+
if (runtimeAbortSignal?.aborted || isAbortError(error)) {
|
|
2379
2369
|
recordFailureCause("aborted");
|
|
2380
2370
|
const hasFailureCauses = Object.keys(failureCauses).length > 0;
|
|
2381
2371
|
const details = {
|
|
@@ -2494,7 +2484,7 @@ export function createTaskTool(cwd, runner, options) {
|
|
|
2494
2484
|
value: summaryPayload,
|
|
2495
2485
|
scope: "run",
|
|
2496
2486
|
mode: "set",
|
|
2497
|
-
},
|
|
2487
|
+
}, runtimeAbortSignal);
|
|
2498
2488
|
sharedMemorySummaryKey = summaryWrite.key;
|
|
2499
2489
|
}
|
|
2500
2490
|
catch (error) {
|
|
@@ -2511,7 +2501,7 @@ export function createTaskTool(cwd, runner, options) {
|
|
|
2511
2501
|
rootCwd: cwd,
|
|
2512
2502
|
runId: sharedMemoryRunId,
|
|
2513
2503
|
taskId: sharedMemoryTaskId,
|
|
2514
|
-
},
|
|
2504
|
+
}, runtimeAbortSignal);
|
|
2515
2505
|
if (delegatedTasks > 1 && usage.currentTaskDelegateWrites === 0) {
|
|
2516
2506
|
delegationWarnings.push("No shared_memory writes detected from delegates in this task. Cross-stream coordination may be weak; use stable keys (findings/<stream>, risks/<stream>, plan/<stream>).");
|
|
2517
2507
|
}
|
|
@@ -2541,7 +2531,7 @@ export function createTaskTool(cwd, runner, options) {
|
|
|
2541
2531
|
prefix: "claims/",
|
|
2542
2532
|
includeValues: true,
|
|
2543
2533
|
limit: Math.max(40, delegatedTasks * 8),
|
|
2544
|
-
},
|
|
2534
|
+
}, runtimeAbortSignal);
|
|
2545
2535
|
const collisions = [];
|
|
2546
2536
|
for (const item of claims.items) {
|
|
2547
2537
|
if (!item.value)
|
|
@@ -2587,7 +2577,7 @@ export function createTaskTool(cwd, runner, options) {
|
|
|
2587
2577
|
prefix: findingsPrefix,
|
|
2588
2578
|
includeValues: true,
|
|
2589
2579
|
limit: Math.max(20, delegatedTasks * 4),
|
|
2590
|
-
},
|
|
2580
|
+
}, runtimeAbortSignal);
|
|
2591
2581
|
const examples = findings.items.slice(0, 6).map((item) => {
|
|
2592
2582
|
let excerpt = "";
|
|
2593
2583
|
if (item.value) {
|
|
@@ -2742,7 +2732,11 @@ export function createTaskTool(cwd, runner, options) {
|
|
|
2742
2732
|
};
|
|
2743
2733
|
if (runInBackground) {
|
|
2744
2734
|
const now = new Date().toISOString();
|
|
2745
|
-
const
|
|
2735
|
+
const backgroundAbortController = new AbortController();
|
|
2736
|
+
runtimeAbortSignal = backgroundAbortController.signal;
|
|
2737
|
+
registerSubagentBackgroundRunController(cwd, runId, backgroundAbortController);
|
|
2738
|
+
const logPath = appendSubagentBackgroundRunLog(cwd, runId, `queued · profile=${effectiveProfile} · cwd=${requestedSubagentCwd}`);
|
|
2739
|
+
const queuedStatusPath = writeSubagentBackgroundRunStatus(cwd, {
|
|
2746
2740
|
runId,
|
|
2747
2741
|
status: "queued",
|
|
2748
2742
|
createdAt: now,
|
|
@@ -2751,9 +2745,10 @@ export function createTaskTool(cwd, runner, options) {
|
|
|
2751
2745
|
cwd: requestedSubagentCwd,
|
|
2752
2746
|
agent: customSubagent?.name,
|
|
2753
2747
|
model: effectiveModelOverride,
|
|
2748
|
+
logPath,
|
|
2754
2749
|
});
|
|
2755
2750
|
void (async () => {
|
|
2756
|
-
|
|
2751
|
+
writeSubagentBackgroundRunStatus(cwd, {
|
|
2757
2752
|
runId,
|
|
2758
2753
|
status: "running",
|
|
2759
2754
|
createdAt: now,
|
|
@@ -2763,10 +2758,12 @@ export function createTaskTool(cwd, runner, options) {
|
|
|
2763
2758
|
cwd: requestedSubagentCwd,
|
|
2764
2759
|
agent: customSubagent?.name,
|
|
2765
2760
|
model: effectiveModelOverride,
|
|
2761
|
+
logPath,
|
|
2766
2762
|
});
|
|
2763
|
+
appendSubagentBackgroundRunLog(cwd, runId, "running");
|
|
2767
2764
|
try {
|
|
2768
2765
|
const result = await executeSubagent();
|
|
2769
|
-
|
|
2766
|
+
writeSubagentBackgroundRunStatus(cwd, {
|
|
2770
2767
|
runId,
|
|
2771
2768
|
status: "done",
|
|
2772
2769
|
createdAt: now,
|
|
@@ -2777,11 +2774,13 @@ export function createTaskTool(cwd, runner, options) {
|
|
|
2777
2774
|
agent: customSubagent?.name,
|
|
2778
2775
|
model: effectiveModelOverride,
|
|
2779
2776
|
transcriptPath: result.details.transcriptPath,
|
|
2777
|
+
logPath,
|
|
2780
2778
|
});
|
|
2779
|
+
appendSubagentBackgroundRunLog(cwd, runId, `done · transcript=${result.details.transcriptPath ?? "-"}`);
|
|
2781
2780
|
}
|
|
2782
2781
|
catch (error) {
|
|
2783
2782
|
const aborted = isAbortError(error);
|
|
2784
|
-
|
|
2783
|
+
writeSubagentBackgroundRunStatus(cwd, {
|
|
2785
2784
|
runId,
|
|
2786
2785
|
status: aborted ? "cancelled" : "error",
|
|
2787
2786
|
createdAt: now,
|
|
@@ -2792,7 +2791,12 @@ export function createTaskTool(cwd, runner, options) {
|
|
|
2792
2791
|
agent: customSubagent?.name,
|
|
2793
2792
|
model: effectiveModelOverride,
|
|
2794
2793
|
error: error instanceof Error ? error.message : String(error),
|
|
2794
|
+
logPath,
|
|
2795
2795
|
});
|
|
2796
|
+
appendSubagentBackgroundRunLog(cwd, runId, `${aborted ? "cancelled" : "error"} · ${error instanceof Error ? error.message : String(error)}`);
|
|
2797
|
+
}
|
|
2798
|
+
finally {
|
|
2799
|
+
unregisterSubagentBackgroundRunController(cwd, runId);
|
|
2796
2800
|
}
|
|
2797
2801
|
})();
|
|
2798
2802
|
return {
|