openfox 2.0.146 → 2.0.147
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 +16 -0
- package/dist/CHANGELOG.md +16 -0
- package/dist/{auto-continue-IENGLXVQ.js → auto-continue-FGQ63HHR.js} +2 -2
- package/dist/{chat-handler-RJUJHVOX.js → chat-handler-VCED3JYF.js} +4 -4
- package/dist/{chunk-7BIGFGU5.js → chunk-2V6QL6IW.js} +285 -115
- package/dist/chunk-65KDNVRA.js +7 -0
- package/dist/{chunk-5D4MQG7P.js → chunk-ABXERHIY.js} +4 -4
- package/dist/{chunk-QR6FIHIP.js → chunk-AJMBQMJH.js} +16 -12
- package/dist/{chunk-L43S7FJM.js → chunk-ESHP42KO.js} +2 -2
- package/dist/{chunk-EZEFBLPY.js → chunk-QHFJRUJV.js} +3 -3
- package/dist/{chunk-OS4P2KQJ.js → chunk-UOBJP4GN.js} +7 -7
- package/dist/{chunk-7IETJ4D4.js → chunk-YQJ6HEFS.js} +29 -29
- package/dist/cli/dev.js +1 -1
- package/dist/cli/index.js +1 -1
- package/dist/{dynamic-context-IQUBKUCX.js → dynamic-context-YLRA34WJ.js} +2 -2
- package/dist/{export-import-NAQDPRET.js → export-import-R4E5BUQS.js} +2 -2
- package/dist/{launch-EUU25RFE.js → launch-QP2BI3PB.js} +5 -5
- package/dist/{orchestrator-PPAIE2UH.js → orchestrator-7T62RLDL.js} +4 -4
- package/dist/package.json +1 -1
- package/dist/{processor-7XMJPNCD.js → processor-LDLRELLS.js} +3 -3
- package/dist/{serve-3GNQNYG6.js → serve-A4AJAH2N.js} +8 -8
- package/dist/server/index.js +7 -7
- package/dist/{server-C4LB436R.js → server-A3EGJ6MD.js} +6 -6
- package/dist/skill-defaults/workflows/SKILL.md +149 -16
- package/dist/{tools-OH3WW6Q4.js → tools-MRC27SZG.js} +2 -2
- package/dist/{update-PG63SDV3.js → update-MLDVVG3D.js} +2 -2
- package/dist/web/assets/{index-jXXIgPm-.js → index-CkVmYTBd.js} +82 -82
- package/dist/web/index.html +1 -1
- package/dist/web/sw.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-EABIZXTG.js +0 -7
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 2.0.147 - 2026-09-14
|
|
4
|
+
|
|
5
|
+
### Features
|
|
6
|
+
|
|
7
|
+
- **Parallel workflow steps** — run sub-agent and shell steps concurrently inside one workflow step, capped by max concurrency, with per-child output keys to branch on.
|
|
8
|
+
- **Parallel step editor** — build parallel steps in the workflow UI with a child list, per-child sub-agent/shell configuration, and slug-safe child ids.
|
|
9
|
+
- **Project dropdown on session rows** — switch projects, start sessions, or open tasks directly from the home session list.
|
|
10
|
+
|
|
11
|
+
### Enhancements
|
|
12
|
+
|
|
13
|
+
- **Agent steps honor per-agent model overrides** — workflow steps pinned to a specific model (e.g. builder on Qwen) now actually run on it, matching the existing sub-agent behavior.
|
|
14
|
+
|
|
15
|
+
### Bug Fixes
|
|
16
|
+
|
|
17
|
+
- **Background process logs stream live** — the log viewer shows new output as it arrives without reopening the panel.
|
|
18
|
+
|
|
3
19
|
## 2.0.146 - 2026-09-12
|
|
4
20
|
|
|
5
21
|
### Bug Fixes
|
package/dist/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 2.0.147 - 2026-09-14
|
|
4
|
+
|
|
5
|
+
### Features
|
|
6
|
+
|
|
7
|
+
- **Parallel workflow steps** — run sub-agent and shell steps concurrently inside one workflow step, capped by max concurrency, with per-child output keys to branch on.
|
|
8
|
+
- **Parallel step editor** — build parallel steps in the workflow UI with a child list, per-child sub-agent/shell configuration, and slug-safe child ids.
|
|
9
|
+
- **Project dropdown on session rows** — switch projects, start sessions, or open tasks directly from the home session list.
|
|
10
|
+
|
|
11
|
+
### Enhancements
|
|
12
|
+
|
|
13
|
+
- **Agent steps honor per-agent model overrides** — workflow steps pinned to a specific model (e.g. builder on Qwen) now actually run on it, matching the existing sub-agent behavior.
|
|
14
|
+
|
|
15
|
+
### Bug Fixes
|
|
16
|
+
|
|
17
|
+
- **Background process logs stream live** — the log viewer shows new output as it arrives without reopening the panel.
|
|
18
|
+
|
|
3
19
|
## 2.0.146 - 2026-09-12
|
|
4
20
|
|
|
5
21
|
### Bug Fixes
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import "./chunk-
|
|
1
|
+
import "./chunk-AJMBQMJH.js";
|
|
2
2
|
import "./chunk-OAN4BXEW.js";
|
|
3
3
|
import "./chunk-DJH6LMBT.js";
|
|
4
4
|
import "./chunk-PHR64A6U.js";
|
|
@@ -108,4 +108,4 @@ export {
|
|
|
108
108
|
planBootContinuation,
|
|
109
109
|
runBootAutoContinuations
|
|
110
110
|
};
|
|
111
|
-
//# sourceMappingURL=auto-continue-
|
|
111
|
+
//# sourceMappingURL=auto-continue-FGQ63HHR.js.map
|
|
@@ -5,9 +5,9 @@ import {
|
|
|
5
5
|
} from "./chunk-ORIPUMOQ.js";
|
|
6
6
|
import {
|
|
7
7
|
runChatTurn
|
|
8
|
-
} from "./chunk-
|
|
9
|
-
import "./chunk-
|
|
10
|
-
import "./chunk-
|
|
8
|
+
} from "./chunk-ABXERHIY.js";
|
|
9
|
+
import "./chunk-ESHP42KO.js";
|
|
10
|
+
import "./chunk-AJMBQMJH.js";
|
|
11
11
|
import "./chunk-OAN4BXEW.js";
|
|
12
12
|
import "./chunk-DJH6LMBT.js";
|
|
13
13
|
import "./chunk-PHR64A6U.js";
|
|
@@ -181,4 +181,4 @@ export {
|
|
|
181
181
|
startChatSession,
|
|
182
182
|
stopSessionExecution
|
|
183
183
|
};
|
|
184
|
-
//# sourceMappingURL=chat-handler-
|
|
184
|
+
//# sourceMappingURL=chat-handler-VCED3JYF.js.map
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
runAgentTurn
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-ABXERHIY.js";
|
|
4
4
|
import {
|
|
5
|
+
buildAgentOverrideStatsIdentity,
|
|
5
6
|
executeSubAgent,
|
|
6
|
-
getToolRegistryForAgent
|
|
7
|
-
|
|
7
|
+
getToolRegistryForAgent,
|
|
8
|
+
resolveLLMClientForAgent
|
|
9
|
+
} from "./chunk-AJMBQMJH.js";
|
|
8
10
|
import {
|
|
9
11
|
gitSpawnEnv
|
|
10
12
|
} from "./chunk-J7GAZGZT.js";
|
|
@@ -204,13 +206,13 @@ function executeShellCommand(command, cwd, timeout, signal) {
|
|
|
204
206
|
});
|
|
205
207
|
}
|
|
206
208
|
|
|
207
|
-
// src/server/workflows/
|
|
209
|
+
// src/server/workflows/template.ts
|
|
208
210
|
var TEMPLATE_VARIABLES = [
|
|
209
211
|
{ name: "workdir", description: "Working directory of the session" },
|
|
210
212
|
{ name: "reason", description: 'Human-readable reason (e.g. "2 criteria remaining")' },
|
|
211
213
|
{
|
|
212
214
|
name: "stepOutput",
|
|
213
|
-
description: "Structured output from the previous step (content, stdout, stderr, exitCode, etc.)"
|
|
215
|
+
description: "Structured output from the previous step (content, stdout, stderr, exitCode, etc.); parallel steps expose per-child keys <childId>.<key> and a summary"
|
|
214
216
|
},
|
|
215
217
|
{
|
|
216
218
|
name: "verifierFindings",
|
|
@@ -225,16 +227,6 @@ var TEMPLATE_VARIABLES = [
|
|
|
225
227
|
{ name: "criteriaList", description: "Formatted list of all criteria with status" },
|
|
226
228
|
{ name: "modifiedFiles", description: "List of modified files" }
|
|
227
229
|
];
|
|
228
|
-
function formatCriteriaList(entries) {
|
|
229
|
-
if (entries.length === 0) return "(none)";
|
|
230
|
-
return entries.map((e) => {
|
|
231
|
-
const status = e.status === "passed" ? "[PASSED]" : e.status === "completed" ? "[NEEDS VERIFICATION]" : e.status === "failed" ? "[FAILED]" : "[NOT COMPLETED]";
|
|
232
|
-
return `- **${e.id}** ${status}: ${e.description}`;
|
|
233
|
-
}).join("\n");
|
|
234
|
-
}
|
|
235
|
-
async function formatModifiedFiles(workdir) {
|
|
236
|
-
return formatGitDiffFiles(workdir);
|
|
237
|
-
}
|
|
238
230
|
function resolveTemplate(template, ctx) {
|
|
239
231
|
let result = template;
|
|
240
232
|
for (const { name } of TEMPLATE_VARIABLES) {
|
|
@@ -242,7 +234,7 @@ function resolveTemplate(template, ctx) {
|
|
|
242
234
|
const value = String(ctx[name]);
|
|
243
235
|
result = result.replace(new RegExp(`\\{\\{${name}\\}\\}`, "g"), value);
|
|
244
236
|
}
|
|
245
|
-
result = result.replace(/\{\{stepOutput\.(\w+)\}\}/g, (_, key) => ctx.stepOutput[key] ?? "");
|
|
237
|
+
result = result.replace(/\{\{stepOutput\.([\w.-]+)\}\}/g, (_, key) => ctx.stepOutput[key] ?? "");
|
|
246
238
|
result = result.replace(/\{\{verifierFindings\}\}/g, ctx.stepOutput["content"] ?? "");
|
|
247
239
|
result = result.replace(/\{\{previousStepOutput\}\}/g, ctx.stepOutput["stdout"] ?? "");
|
|
248
240
|
for (const [key, value] of Object.entries(ctx.params)) {
|
|
@@ -250,6 +242,196 @@ function resolveTemplate(template, ctx) {
|
|
|
250
242
|
}
|
|
251
243
|
return result;
|
|
252
244
|
}
|
|
245
|
+
|
|
246
|
+
// src/server/workflows/parallel.ts
|
|
247
|
+
async function mapPool(items, limit, task) {
|
|
248
|
+
const results = new Array(items.length);
|
|
249
|
+
let firstError = null;
|
|
250
|
+
let next = 0;
|
|
251
|
+
const workers = Array.from({ length: Math.min(Math.max(limit, 1), items.length) }, async () => {
|
|
252
|
+
while (next < items.length) {
|
|
253
|
+
const index = next++;
|
|
254
|
+
try {
|
|
255
|
+
results[index] = await task(items[index]);
|
|
256
|
+
} catch (error) {
|
|
257
|
+
if (firstError === null) {
|
|
258
|
+
firstError = error;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
});
|
|
263
|
+
await Promise.all(workers);
|
|
264
|
+
if (firstError !== null) {
|
|
265
|
+
throw firstError;
|
|
266
|
+
}
|
|
267
|
+
return results;
|
|
268
|
+
}
|
|
269
|
+
function aggregateParallel(outcomes) {
|
|
270
|
+
const successCount = outcomes.filter((o) => o.result === "success").length;
|
|
271
|
+
const result = outcomes.length === 0 ? "failure" : successCount === outcomes.length ? "success" : successCount === 0 ? "failure" : "partial";
|
|
272
|
+
const output = {
|
|
273
|
+
result,
|
|
274
|
+
summary: outcomes.map((o) => `- ${o.id}: ${o.result}`).join("\n")
|
|
275
|
+
};
|
|
276
|
+
for (const o of outcomes) {
|
|
277
|
+
output[`${o.id}.result`] = o.result;
|
|
278
|
+
for (const [key, value] of Object.entries(o.output)) {
|
|
279
|
+
output[`${o.id}.${key}`] = value;
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
return { result, output };
|
|
283
|
+
}
|
|
284
|
+
function isAbortError(error) {
|
|
285
|
+
return error instanceof Error && error.message === "Aborted";
|
|
286
|
+
}
|
|
287
|
+
function failureOutcome(id, error) {
|
|
288
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
289
|
+
logger.warn("Workflow child step failed", { child: id, error: message });
|
|
290
|
+
return { id, result: "failure", output: { error: message } };
|
|
291
|
+
}
|
|
292
|
+
async function runSubAgentChild(child, deps) {
|
|
293
|
+
const { sessionManager, sessionId, llmClient, ctx, signal, onMessage } = deps;
|
|
294
|
+
try {
|
|
295
|
+
const turnMetrics = new TurnMetrics();
|
|
296
|
+
const promptTemplate = child.prompt ?? "Perform your task.";
|
|
297
|
+
const resolvedPrompt = resolveTemplate(promptTemplate, ctx);
|
|
298
|
+
const allAgents = deps.agents ?? await loadAllAgentsDefault(sessionManager.getProjectWorkdir(sessionId));
|
|
299
|
+
const agentDef = findAgentById(child.subAgentType, allAgents);
|
|
300
|
+
if (!agentDef) {
|
|
301
|
+
logger.error("Sub-agent definition not found", { subAgentType: child.subAgentType });
|
|
302
|
+
return { id: child.id, result: "error", output: { error: `Unknown sub-agent type: ${child.subAgentType}` } };
|
|
303
|
+
}
|
|
304
|
+
const toolRegistry = getToolRegistryForAgent(agentDef);
|
|
305
|
+
const filteredToolRegistry = {
|
|
306
|
+
tools: toolRegistry.tools.filter((t) => t.name !== "step_done"),
|
|
307
|
+
definitions: toolRegistry.definitions.filter((d) => d.type === "function" && d.function.name !== "step_done"),
|
|
308
|
+
execute: toolRegistry.execute
|
|
309
|
+
};
|
|
310
|
+
const result = await executeSubAgent({
|
|
311
|
+
subAgentType: child.subAgentType,
|
|
312
|
+
prompt: resolvedPrompt,
|
|
313
|
+
sessionManager,
|
|
314
|
+
sessionId,
|
|
315
|
+
llmClient,
|
|
316
|
+
toolRegistry: filteredToolRegistry,
|
|
317
|
+
turnMetrics,
|
|
318
|
+
providerManager: sessionManager.getProviderManager?.(),
|
|
319
|
+
statsIdentity: deps.statsIdentity ?? {
|
|
320
|
+
providerId: "",
|
|
321
|
+
providerName: "",
|
|
322
|
+
backend: "unknown",
|
|
323
|
+
model: llmClient.getModel()
|
|
324
|
+
},
|
|
325
|
+
...signal ? { signal } : {},
|
|
326
|
+
...onMessage ? { onMessage } : {}
|
|
327
|
+
});
|
|
328
|
+
return {
|
|
329
|
+
id: child.id,
|
|
330
|
+
result: result.result ?? "success",
|
|
331
|
+
output: { content: result.content ?? "", ...result.result ? { result: result.result } : {} }
|
|
332
|
+
};
|
|
333
|
+
} catch (error) {
|
|
334
|
+
if (isAbortError(error)) {
|
|
335
|
+
throw error;
|
|
336
|
+
}
|
|
337
|
+
return failureOutcome(child.id, error);
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
async function runShellChild(child, deps) {
|
|
341
|
+
const { sessionManager, sessionId, ctx, label, signal, onMessage, eventStore, windowOptions } = deps;
|
|
342
|
+
if (child.command === void 0) {
|
|
343
|
+
logger.warn("Shell child has no command", { child: child.id });
|
|
344
|
+
return { id: child.id, result: "error", output: { error: "Missing command" } };
|
|
345
|
+
}
|
|
346
|
+
const command = resolveTemplate(child.command, ctx);
|
|
347
|
+
const timeout = child.timeout ?? 6e4;
|
|
348
|
+
const successCodes = child.successExitCodes ?? [0];
|
|
349
|
+
const runningContent = label ? serverT(
|
|
350
|
+
{ en: "Running ({{label}}): `{{command}}`", fr: "Ex\xE9cution ({{label}}) : `{{command}}`" },
|
|
351
|
+
{ label, command }
|
|
352
|
+
) : serverT({ en: "Running: `{{command}}`", fr: "Ex\xE9cution : `{{command}}`" }, { command });
|
|
353
|
+
const shellMsgId = crypto.randomUUID();
|
|
354
|
+
eventStore.append(
|
|
355
|
+
sessionId,
|
|
356
|
+
createMessageStartEvent(shellMsgId, "user", runningContent, {
|
|
357
|
+
...windowOptions ?? {},
|
|
358
|
+
isSystemGenerated: true,
|
|
359
|
+
messageKind: "auto-prompt",
|
|
360
|
+
metadata: { type: "workflow", name: "Workflow", color: "#f59e0b" }
|
|
361
|
+
})
|
|
362
|
+
);
|
|
363
|
+
if (onMessage) {
|
|
364
|
+
onMessage(
|
|
365
|
+
createChatMessageMessage({
|
|
366
|
+
id: shellMsgId,
|
|
367
|
+
role: "user",
|
|
368
|
+
content: runningContent,
|
|
369
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
370
|
+
isSystemGenerated: true,
|
|
371
|
+
messageKind: "auto-prompt",
|
|
372
|
+
metadata: { type: "workflow", name: "Workflow", color: "#f59e0b" }
|
|
373
|
+
})
|
|
374
|
+
);
|
|
375
|
+
}
|
|
376
|
+
const result = await executeShellCommand(command, sessionManager.getEffectiveWorkdir(sessionId), timeout, signal);
|
|
377
|
+
const output = [result.stdout, result.stderr].filter(Boolean).join("\n").trim();
|
|
378
|
+
const outputContent = output ? label ? serverT(
|
|
379
|
+
{
|
|
380
|
+
en: "Exit code ({{label}}): {{code}}\n```\n{{output}}\n```",
|
|
381
|
+
fr: "Code de sortie ({{label}}) : {{code}}\n```\n{{output}}\n```"
|
|
382
|
+
},
|
|
383
|
+
{ label, code: result.exitCode, output: output.slice(0, 1e4) }
|
|
384
|
+
) : serverT(
|
|
385
|
+
{ en: "Exit code: {{code}}\n```\n{{output}}\n```", fr: "Code de sortie : {{code}}\n```\n{{output}}\n```" },
|
|
386
|
+
{ code: result.exitCode, output: output.slice(0, 1e4) }
|
|
387
|
+
) : label ? serverT(
|
|
388
|
+
{ en: "Exit code ({{label}}): {{code}}", fr: "Code de sortie ({{label}}) : {{code}}" },
|
|
389
|
+
{ label, code: result.exitCode }
|
|
390
|
+
) : serverT({ en: "Exit code: {{code}}", fr: "Code de sortie : {{code}}" }, { code: result.exitCode });
|
|
391
|
+
eventStore.append(sessionId, { type: "message.done", data: { messageId: shellMsgId } });
|
|
392
|
+
const outputMsgId = crypto.randomUUID();
|
|
393
|
+
eventStore.append(
|
|
394
|
+
sessionId,
|
|
395
|
+
createMessageStartEvent(outputMsgId, "user", outputContent, {
|
|
396
|
+
...windowOptions ?? {},
|
|
397
|
+
isSystemGenerated: true,
|
|
398
|
+
messageKind: "correction"
|
|
399
|
+
})
|
|
400
|
+
);
|
|
401
|
+
eventStore.append(sessionId, { type: "message.done", data: { messageId: outputMsgId } });
|
|
402
|
+
if (onMessage) {
|
|
403
|
+
onMessage(
|
|
404
|
+
createChatMessageMessage({
|
|
405
|
+
id: outputMsgId,
|
|
406
|
+
role: "user",
|
|
407
|
+
content: outputContent,
|
|
408
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
409
|
+
isSystemGenerated: true,
|
|
410
|
+
messageKind: "correction"
|
|
411
|
+
})
|
|
412
|
+
);
|
|
413
|
+
}
|
|
414
|
+
return {
|
|
415
|
+
id: child.id,
|
|
416
|
+
result: successCodes.includes(result.exitCode) ? "success" : "failure",
|
|
417
|
+
output: { stdout: result.stdout ?? "", stderr: result.stderr ?? "", exitCode: String(result.exitCode) }
|
|
418
|
+
};
|
|
419
|
+
}
|
|
420
|
+
async function runChild(child, deps) {
|
|
421
|
+
return child.type === "sub_agent" ? runSubAgentChild(child, deps) : runShellChild(child, deps);
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
// src/server/workflows/executor.ts
|
|
425
|
+
function formatCriteriaList(entries) {
|
|
426
|
+
if (entries.length === 0) return "(none)";
|
|
427
|
+
return entries.map((e) => {
|
|
428
|
+
const status = e.status === "passed" ? "[PASSED]" : e.status === "completed" ? "[NEEDS VERIFICATION]" : e.status === "failed" ? "[FAILED]" : "[NOT COMPLETED]";
|
|
429
|
+
return `- **${e.id}** ${status}: ${e.description}`;
|
|
430
|
+
}).join("\n");
|
|
431
|
+
}
|
|
432
|
+
async function formatModifiedFiles(workdir) {
|
|
433
|
+
return formatGitDiffFiles(workdir);
|
|
434
|
+
}
|
|
253
435
|
function evaluateCondition(condition, stepOutcome, metadataEntries) {
|
|
254
436
|
switch (condition.type) {
|
|
255
437
|
case "step_result":
|
|
@@ -364,6 +546,20 @@ function buildReason(metadataEntries) {
|
|
|
364
546
|
const remaining = entries.filter((e) => e.status !== "passed");
|
|
365
547
|
return `${remaining.length} criteria remaining`;
|
|
366
548
|
}
|
|
549
|
+
function buildStepChildDeps(options, templateCtx, eventStore, windowOptions) {
|
|
550
|
+
const { sessionManager, sessionId, llmClient, statsIdentity, signal, onMessage } = options;
|
|
551
|
+
return {
|
|
552
|
+
sessionManager,
|
|
553
|
+
sessionId,
|
|
554
|
+
llmClient,
|
|
555
|
+
ctx: templateCtx,
|
|
556
|
+
...signal ? { signal } : {},
|
|
557
|
+
...onMessage ? { onMessage } : {},
|
|
558
|
+
...statsIdentity !== void 0 ? { statsIdentity } : {},
|
|
559
|
+
eventStore,
|
|
560
|
+
windowOptions
|
|
561
|
+
};
|
|
562
|
+
}
|
|
367
563
|
async function executeWorkflow(workflow, options, subGroup) {
|
|
368
564
|
const { sessionManager, sessionId, llmClient, signal, onMessage } = options;
|
|
369
565
|
const eventStore = getEventStore();
|
|
@@ -582,22 +778,45 @@ async function executeWorkflow(workflow, options, subGroup) {
|
|
|
582
778
|
const es = getEventStore();
|
|
583
779
|
const append = (event) => es.append(sessionId, event);
|
|
584
780
|
let stepDoneCalled = false;
|
|
781
|
+
const stepAgentId = agentStep.agentId ?? resolveDefaultAgentId();
|
|
782
|
+
const effectiveProviderManager = sessionManager.getProviderManager?.();
|
|
783
|
+
let stepLlmClient = llmClient;
|
|
784
|
+
let stepStatsIdentity = options.statsIdentity;
|
|
785
|
+
let stepGetSessionLLMClient = options.getSessionLLMClient;
|
|
786
|
+
if (effectiveProviderManager) {
|
|
787
|
+
const pinnedEffort = session.providerPinnedEffort ?? void 0;
|
|
788
|
+
const resolved = resolveLLMClientForAgent(stepAgentId, llmClient, effectiveProviderManager, pinnedEffort);
|
|
789
|
+
if (resolved.usedOverride && resolved.override) {
|
|
790
|
+
stepLlmClient = resolved.client;
|
|
791
|
+
stepStatsIdentity = buildAgentOverrideStatsIdentity(
|
|
792
|
+
effectiveProviderManager,
|
|
793
|
+
resolved.client,
|
|
794
|
+
resolved.override
|
|
795
|
+
);
|
|
796
|
+
stepGetSessionLLMClient = void 0;
|
|
797
|
+
} else if (resolved.warning) {
|
|
798
|
+
logger.warn("Agent step model override unavailable, falling back", {
|
|
799
|
+
agentId: stepAgentId,
|
|
800
|
+
warning: resolved.warning
|
|
801
|
+
});
|
|
802
|
+
}
|
|
803
|
+
}
|
|
585
804
|
let agentResult;
|
|
586
805
|
try {
|
|
587
806
|
agentResult = await runAgentTurn(
|
|
588
807
|
{
|
|
589
808
|
sessionManager,
|
|
590
809
|
sessionId,
|
|
591
|
-
llmClient,
|
|
592
|
-
...
|
|
593
|
-
...
|
|
810
|
+
llmClient: stepLlmClient,
|
|
811
|
+
...stepGetSessionLLMClient ? { getSessionLLMClient: stepGetSessionLLMClient } : {},
|
|
812
|
+
...stepStatsIdentity ? { statsIdentity: stepStatsIdentity } : {},
|
|
594
813
|
...signal ? { signal } : {},
|
|
595
814
|
...onMessage ? { onMessage } : {},
|
|
596
815
|
...options.llmRetryPolicy ? { llmRetryPolicy: options.llmRetryPolicy } : {},
|
|
597
816
|
...isResumingCurrentStep ? { skipAgentReminder: true } : {}
|
|
598
817
|
},
|
|
599
818
|
turnMetrics,
|
|
600
|
-
|
|
819
|
+
stepAgentId,
|
|
601
820
|
append,
|
|
602
821
|
{
|
|
603
822
|
...!firstEntryForStep.has(step.id) && !agentStep.prompt && !isResumingCurrentStep ? { injectKickoff: () => injectGenericKickoff(sessionId) } : {},
|
|
@@ -641,112 +860,63 @@ async function executeWorkflow(workflow, options, subGroup) {
|
|
|
641
860
|
}
|
|
642
861
|
case "sub_agent": {
|
|
643
862
|
const subStep = step;
|
|
644
|
-
const
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
863
|
+
const outcome = await runSubAgentChild(
|
|
864
|
+
subStep,
|
|
865
|
+
buildStepChildDeps(options, templateCtx, eventStore, currentWindowMessageOptions)
|
|
866
|
+
);
|
|
867
|
+
lastStepOutput = outcome.output;
|
|
868
|
+
stepOutcome = { result: outcome.result, output: lastStepOutput };
|
|
869
|
+
break;
|
|
870
|
+
}
|
|
871
|
+
case "shell": {
|
|
872
|
+
const shellStep = step;
|
|
873
|
+
const outcome = await runShellChild(
|
|
874
|
+
shellStep,
|
|
875
|
+
buildStepChildDeps(options, templateCtx, eventStore, currentWindowMessageOptions)
|
|
876
|
+
);
|
|
877
|
+
lastStepOutput = outcome.output;
|
|
878
|
+
stepOutcome = { result: outcome.result, output: lastStepOutput };
|
|
879
|
+
break;
|
|
880
|
+
}
|
|
881
|
+
case "parallel": {
|
|
882
|
+
const parallelStep = step;
|
|
883
|
+
if (parallelStep.children.length === 0) {
|
|
884
|
+
logger.warn("Parallel step has no children", { sessionId, stepId: step.id });
|
|
653
885
|
}
|
|
654
|
-
const
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
const result = await executeSubAgent({
|
|
661
|
-
subAgentType: subStep.subAgentType,
|
|
662
|
-
prompt: resolvedPrompt,
|
|
886
|
+
const childIds = parallelStep.children.map((c) => c.id);
|
|
887
|
+
if (new Set(childIds).size !== childIds.length) {
|
|
888
|
+
logger.warn("Parallel step has duplicate child ids", { sessionId, stepId: step.id, ids: childIds });
|
|
889
|
+
}
|
|
890
|
+
const allAgents = await loadAllAgentsDefault(sessionManager.getProjectWorkdir(sessionId));
|
|
891
|
+
const baseDeps = {
|
|
663
892
|
sessionManager,
|
|
664
893
|
sessionId,
|
|
665
894
|
llmClient,
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
895
|
+
ctx: templateCtx,
|
|
896
|
+
...signal ? { signal } : {},
|
|
897
|
+
...onMessage ? { onMessage } : {},
|
|
898
|
+
eventStore,
|
|
899
|
+
windowOptions: currentWindowMessageOptions,
|
|
669
900
|
statsIdentity: options.statsIdentity ?? {
|
|
670
901
|
providerId: "",
|
|
671
902
|
providerName: "",
|
|
672
903
|
backend: "unknown",
|
|
673
904
|
model: llmClient.getModel()
|
|
674
905
|
},
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
break;
|
|
681
|
-
}
|
|
682
|
-
case "shell": {
|
|
683
|
-
const shellStep = step;
|
|
684
|
-
const command = resolveTemplate(shellStep.command, templateCtx);
|
|
685
|
-
const timeout = shellStep.timeout ?? 6e4;
|
|
686
|
-
const successCodes = shellStep.successExitCodes ?? [0];
|
|
687
|
-
const shellMsgId = crypto.randomUUID();
|
|
688
|
-
const runningContent = serverT({ en: "Running: `{{command}}`", fr: "Ex\xE9cution : `{{command}}`" }, { command });
|
|
689
|
-
eventStore.append(
|
|
690
|
-
sessionId,
|
|
691
|
-
createMessageStartEvent(shellMsgId, "user", runningContent, {
|
|
692
|
-
...currentWindowMessageOptions ?? {},
|
|
693
|
-
isSystemGenerated: true,
|
|
694
|
-
messageKind: "auto-prompt",
|
|
695
|
-
metadata: { type: "workflow", name: "Workflow", color: "#f59e0b" }
|
|
696
|
-
})
|
|
697
|
-
);
|
|
698
|
-
if (onMessage) {
|
|
699
|
-
onMessage(
|
|
700
|
-
createChatMessageMessage({
|
|
701
|
-
id: shellMsgId,
|
|
702
|
-
role: "user",
|
|
703
|
-
content: runningContent,
|
|
704
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
705
|
-
isSystemGenerated: true,
|
|
706
|
-
messageKind: "auto-prompt",
|
|
707
|
-
metadata: { type: "workflow", name: "Workflow", color: "#f59e0b" }
|
|
708
|
-
})
|
|
709
|
-
);
|
|
710
|
-
}
|
|
711
|
-
const result = await executeShellCommand(
|
|
712
|
-
command,
|
|
713
|
-
sessionManager.getEffectiveWorkdir(sessionId),
|
|
714
|
-
timeout,
|
|
715
|
-
signal
|
|
906
|
+
agents: allAgents
|
|
907
|
+
};
|
|
908
|
+
const limit = Math.min(
|
|
909
|
+
Math.max(Math.floor(parallelStep.maxConcurrency ?? parallelStep.children.length), 1),
|
|
910
|
+
parallelStep.children.length
|
|
716
911
|
);
|
|
717
|
-
const
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
{
|
|
721
|
-
en: "Exit code: {{code}}\n```\n{{output}}\n```",
|
|
722
|
-
fr: "Code de sortie : {{code}}\n```\n{{output}}\n```"
|
|
723
|
-
},
|
|
724
|
-
{ code: result.exitCode, output: output.slice(0, 1e4) }
|
|
725
|
-
) : serverT({ en: "Exit code: {{code}}", fr: "Code de sortie : {{code}}" }, { code: result.exitCode });
|
|
726
|
-
eventStore.append(sessionId, { type: "message.done", data: { messageId: shellMsgId } });
|
|
727
|
-
const outputMsgId = crypto.randomUUID();
|
|
728
|
-
eventStore.append(
|
|
729
|
-
sessionId,
|
|
730
|
-
createMessageStartEvent(outputMsgId, "user", outputContent, {
|
|
731
|
-
...currentWindowMessageOptions ?? {},
|
|
732
|
-
isSystemGenerated: true,
|
|
733
|
-
messageKind: "correction"
|
|
734
|
-
})
|
|
912
|
+
const outcomes = await mapPool(
|
|
913
|
+
parallelStep.children,
|
|
914
|
+
limit,
|
|
915
|
+
(child) => runChild(child, { ...baseDeps, label: child.id })
|
|
735
916
|
);
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
createChatMessageMessage({
|
|
740
|
-
id: outputMsgId,
|
|
741
|
-
role: "user",
|
|
742
|
-
content: outputContent,
|
|
743
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
744
|
-
isSystemGenerated: true,
|
|
745
|
-
messageKind: "correction"
|
|
746
|
-
})
|
|
747
|
-
);
|
|
748
|
-
}
|
|
749
|
-
stepOutcome = { result: successCodes.includes(result.exitCode) ? "success" : "failure", output: lastStepOutput };
|
|
917
|
+
const aggregate = aggregateParallel(outcomes);
|
|
918
|
+
lastStepOutput = aggregate.output;
|
|
919
|
+
stepOutcome = { result: aggregate.result, output: lastStepOutput };
|
|
750
920
|
break;
|
|
751
921
|
}
|
|
752
922
|
case "user": {
|
|
@@ -1026,4 +1196,4 @@ export {
|
|
|
1026
1196
|
abortRunnerRun,
|
|
1027
1197
|
launchWorkflowRun
|
|
1028
1198
|
};
|
|
1029
|
-
//# sourceMappingURL=chunk-
|
|
1199
|
+
//# sourceMappingURL=chunk-2V6QL6IW.js.map
|
|
@@ -3,14 +3,14 @@ import {
|
|
|
3
3
|
checkToolChangesAndInject,
|
|
4
4
|
computeDynamicContextHash,
|
|
5
5
|
getToolFingerprint
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-ESHP42KO.js";
|
|
7
7
|
import {
|
|
8
8
|
createAssemblyResult,
|
|
9
9
|
getConversationMessages,
|
|
10
10
|
getToolRegistryForAgent,
|
|
11
11
|
processEventsForConversation,
|
|
12
12
|
runTopLevelAgentLoop
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-AJMBQMJH.js";
|
|
14
14
|
import {
|
|
15
15
|
getAllInstructions,
|
|
16
16
|
getEnabledSkillMetadata
|
|
@@ -357,7 +357,7 @@ async function runAgentTurn(options, turnMetrics, agentId, append, callbacks) {
|
|
|
357
357
|
getConversationMessages: buildGetConversationMessages(options.sessionId, resolveAgentClient, append),
|
|
358
358
|
injectAgentReminder: () => injectAgentReminder(options.sessionId, agentDef),
|
|
359
359
|
rebuildCachedContext: async () => {
|
|
360
|
-
const { applyDynamicContext } = await import("./dynamic-context-
|
|
360
|
+
const { applyDynamicContext } = await import("./dynamic-context-YLRA34WJ.js");
|
|
361
361
|
await applyDynamicContext(options.sessionManager, options.sessionId, agentLlmClient.getModel());
|
|
362
362
|
},
|
|
363
363
|
...options.initialCompacting ? { initialCompacting: true } : {},
|
|
@@ -387,4 +387,4 @@ export {
|
|
|
387
387
|
runChatTurn,
|
|
388
388
|
runAgentTurn
|
|
389
389
|
};
|
|
390
|
-
//# sourceMappingURL=chunk-
|
|
390
|
+
//# sourceMappingURL=chunk-ABXERHIY.js.map
|
|
@@ -1162,6 +1162,16 @@ function resolveLLMClientForAgent(agentId, fallbackClient, providerManager, pinn
|
|
|
1162
1162
|
override: effectiveEffort ? { ...override, reasoningEffort: effectiveEffort } : override
|
|
1163
1163
|
};
|
|
1164
1164
|
}
|
|
1165
|
+
function buildAgentOverrideStatsIdentity(providerManager, client, override) {
|
|
1166
|
+
const provider = providerManager.getProviders().find((p) => p.id === override.providerId);
|
|
1167
|
+
return {
|
|
1168
|
+
providerId: override.providerId,
|
|
1169
|
+
providerName: provider?.name ?? override.providerId,
|
|
1170
|
+
backend: provider?.backend ?? client.getBackend(),
|
|
1171
|
+
model: override.model,
|
|
1172
|
+
...override.reasoningEffort ? { reasoningEffort: override.reasoningEffort } : {}
|
|
1173
|
+
};
|
|
1174
|
+
}
|
|
1165
1175
|
|
|
1166
1176
|
// src/server/chat/tool-streaming.ts
|
|
1167
1177
|
function parseProgressMessage(message) {
|
|
@@ -2241,14 +2251,7 @@ async function executeSubAgent(options) {
|
|
|
2241
2251
|
if (resolved.usedOverride && resolved.override) {
|
|
2242
2252
|
hasOverride = true;
|
|
2243
2253
|
llmClient = resolved.client;
|
|
2244
|
-
|
|
2245
|
-
statsIdentity = {
|
|
2246
|
-
providerId: resolved.override.providerId,
|
|
2247
|
-
providerName: provider?.name ?? resolved.override.providerId,
|
|
2248
|
-
backend: provider?.backend ?? resolved.client.getBackend(),
|
|
2249
|
-
model: resolved.override.model,
|
|
2250
|
-
...resolved.override.reasoningEffort ? { reasoningEffort: resolved.override.reasoningEffort } : {}
|
|
2251
|
-
};
|
|
2254
|
+
statsIdentity = buildAgentOverrideStatsIdentity(effectiveProviderManager, resolved.client, resolved.override);
|
|
2252
2255
|
const overrideEffort = effectiveProviderManager.resolveModelEffort(
|
|
2253
2256
|
resolved.override.providerId,
|
|
2254
2257
|
resolved.override.model,
|
|
@@ -2475,7 +2478,7 @@ var callSubAgentTool = {
|
|
|
2475
2478
|
};
|
|
2476
2479
|
}
|
|
2477
2480
|
try {
|
|
2478
|
-
const { getToolRegistryForAgent: getToolRegistryForAgent2 } = await import("./tools-
|
|
2481
|
+
const { getToolRegistryForAgent: getToolRegistryForAgent2 } = await import("./tools-MRC27SZG.js");
|
|
2479
2482
|
const toolRegistry = getToolRegistryForAgent2(agentDef);
|
|
2480
2483
|
const turnMetrics = new TurnMetrics();
|
|
2481
2484
|
const result = await executeSubAgent({
|
|
@@ -3579,11 +3582,11 @@ var mcpConfigTool = createTool(
|
|
|
3579
3582
|
async function notifyContextChanged(sessionId) {
|
|
3580
3583
|
context.sessionManager.setDynamicContextChanged(sessionId, true);
|
|
3581
3584
|
mcpNotifyChanged?.(sessionId);
|
|
3582
|
-
const { injectContextDriftReminders } = await import("./dynamic-context-
|
|
3585
|
+
const { injectContextDriftReminders } = await import("./dynamic-context-YLRA34WJ.js");
|
|
3583
3586
|
await injectContextDriftReminders(context.sessionManager, sessionId);
|
|
3584
3587
|
}
|
|
3585
3588
|
async function rebuildTools() {
|
|
3586
|
-
const { setMcpTools: setMcpTools2 } = await import("./tools-
|
|
3589
|
+
const { setMcpTools: setMcpTools2 } = await import("./tools-MRC27SZG.js");
|
|
3587
3590
|
const mcpTools = createMcpTools(mcpManagerForTools);
|
|
3588
3591
|
setMcpTools2(mcpTools);
|
|
3589
3592
|
}
|
|
@@ -4702,6 +4705,7 @@ export {
|
|
|
4702
4705
|
getAgentModelOverride,
|
|
4703
4706
|
setAgentModelOverride,
|
|
4704
4707
|
resolveLLMClientForAgent,
|
|
4708
|
+
buildAgentOverrideStatsIdentity,
|
|
4705
4709
|
runTopLevelAgentLoop,
|
|
4706
4710
|
createAssemblyResult,
|
|
4707
4711
|
getConversationMessages,
|
|
@@ -4725,4 +4729,4 @@ export {
|
|
|
4725
4729
|
getToolRegistryForAgent,
|
|
4726
4730
|
createToolRegistry
|
|
4727
4731
|
};
|
|
4728
|
-
//# sourceMappingURL=chunk-
|
|
4732
|
+
//# sourceMappingURL=chunk-AJMBQMJH.js.map
|