pi-agent-flow 2.2.14 → 2.2.16
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/README.md +12 -0
- package/dist/batch/apply-patch.d.ts +2 -1
- package/dist/batch/apply-patch.d.ts.map +1 -1
- package/dist/batch/batch-bash.d.ts.map +1 -1
- package/dist/batch/batch-bash.js +9 -43
- package/dist/batch/batch-bash.js.map +1 -1
- package/dist/batch/constants.d.ts +9 -1
- package/dist/batch/constants.d.ts.map +1 -1
- package/dist/batch/constants.js +7 -0
- package/dist/batch/constants.js.map +1 -1
- package/dist/batch/execute.d.ts +1 -13
- package/dist/batch/execute.d.ts.map +1 -1
- package/dist/batch/execute.js +87 -28
- package/dist/batch/execute.js.map +1 -1
- package/dist/batch/index.d.ts.map +1 -1
- package/dist/batch/index.js +16 -14
- package/dist/batch/index.js.map +1 -1
- package/dist/batch/render.d.ts.map +1 -1
- package/dist/batch/render.js.map +1 -1
- package/dist/batch/summary.d.ts +0 -6
- package/dist/batch/summary.d.ts.map +1 -1
- package/dist/batch/summary.js +3 -3
- package/dist/batch/summary.js.map +1 -1
- package/dist/batch/symbols.d.ts.map +1 -1
- package/dist/batch/symbols.js +3 -1
- package/dist/batch/symbols.js.map +1 -1
- package/dist/batch/truncate-output.d.ts +31 -0
- package/dist/batch/truncate-output.d.ts.map +1 -0
- package/dist/batch/truncate-output.js +120 -0
- package/dist/batch/truncate-output.js.map +1 -0
- package/dist/config/config.d.ts +2 -1
- package/dist/config/config.d.ts.map +1 -1
- package/dist/config/config.js +10 -24
- package/dist/config/config.js.map +1 -1
- package/dist/config/models.d.ts.map +1 -1
- package/dist/config/models.js +7 -5
- package/dist/config/models.js.map +1 -1
- package/dist/config/paths.d.ts +3 -0
- package/dist/config/paths.d.ts.map +1 -0
- package/dist/config/paths.js +9 -0
- package/dist/config/paths.js.map +1 -0
- package/dist/config/resolver-helpers.d.ts +44 -0
- package/dist/config/resolver-helpers.d.ts.map +1 -0
- package/dist/config/resolver-helpers.js +135 -0
- package/dist/config/resolver-helpers.js.map +1 -0
- package/dist/config/settings-resolver.d.ts +0 -6
- package/dist/config/settings-resolver.d.ts.map +1 -1
- package/dist/config/settings-resolver.js +27 -256
- package/dist/config/settings-resolver.js.map +1 -1
- package/dist/core2/snapshot.d.ts +0 -2
- package/dist/core2/snapshot.d.ts.map +1 -1
- package/dist/core2/snapshot.js +91 -24
- package/dist/core2/snapshot.js.map +1 -1
- package/dist/flow/agents.d.ts +1 -1
- package/dist/flow/agents.d.ts.map +1 -1
- package/dist/flow/agents.js +18 -9
- package/dist/flow/agents.js.map +1 -1
- package/dist/flow/audit-formatters.d.ts +20 -0
- package/dist/flow/audit-formatters.d.ts.map +1 -0
- package/dist/flow/audit-formatters.js +123 -0
- package/dist/flow/audit-formatters.js.map +1 -0
- package/dist/flow/complexity.d.ts +3 -2
- package/dist/flow/complexity.d.ts.map +1 -1
- package/dist/flow/complexity.js +1 -1
- package/dist/flow/complexity.js.map +1 -1
- package/dist/flow/continuation.d.ts.map +1 -1
- package/dist/flow/continuation.js +6 -4
- package/dist/flow/continuation.js.map +1 -1
- package/dist/flow/cycle-guard.d.ts +20 -0
- package/dist/flow/cycle-guard.d.ts.map +1 -0
- package/dist/flow/cycle-guard.js +56 -0
- package/dist/flow/cycle-guard.js.map +1 -0
- package/dist/flow/depth.d.ts +0 -1
- package/dist/flow/depth.d.ts.map +1 -1
- package/dist/flow/depth.js +3 -2
- package/dist/flow/depth.js.map +1 -1
- package/dist/flow/dump-io.d.ts +15 -0
- package/dist/flow/dump-io.d.ts.map +1 -0
- package/dist/flow/dump-io.js +169 -0
- package/dist/flow/dump-io.js.map +1 -0
- package/dist/flow/execute-single.d.ts +8 -0
- package/dist/flow/execute-single.d.ts.map +1 -0
- package/dist/flow/execute-single.js +132 -0
- package/dist/flow/execute-single.js.map +1 -0
- package/dist/flow/executor.d.ts +3 -62
- package/dist/flow/executor.d.ts.map +1 -1
- package/dist/flow/executor.js +36 -342
- package/dist/flow/executor.js.map +1 -1
- package/dist/flow/flow-args.d.ts +14 -0
- package/dist/flow/flow-args.d.ts.map +1 -0
- package/dist/flow/flow-args.js +119 -0
- package/dist/flow/flow-args.js.map +1 -0
- package/dist/flow/flow-live.d.ts +18 -0
- package/dist/flow/flow-live.d.ts.map +1 -0
- package/dist/flow/flow-live.js +46 -0
- package/dist/flow/flow-live.js.map +1 -0
- package/dist/flow/process-lifecycle.d.ts +28 -0
- package/dist/flow/process-lifecycle.d.ts.map +1 -0
- package/dist/flow/process-lifecycle.js +114 -0
- package/dist/flow/process-lifecycle.js.map +1 -0
- package/dist/flow/runner.d.ts +4 -54
- package/dist/flow/runner.d.ts.map +1 -1
- package/dist/flow/runner.js +55 -517
- package/dist/flow/runner.js.map +1 -1
- package/dist/flow/settings-command.d.ts +2 -24
- package/dist/flow/settings-command.d.ts.map +1 -1
- package/dist/flow/settings-command.js +14 -716
- package/dist/flow/settings-command.js.map +1 -1
- package/dist/flow/settings-handler.d.ts +9 -0
- package/dist/flow/settings-handler.d.ts.map +1 -0
- package/dist/flow/settings-handler.js +377 -0
- package/dist/flow/settings-handler.js.map +1 -0
- package/dist/flow/settings-items.d.ts +42 -0
- package/dist/flow/settings-items.d.ts.map +1 -0
- package/dist/flow/settings-items.js +380 -0
- package/dist/flow/settings-items.js.map +1 -0
- package/dist/flow/spawn-utils.d.ts +17 -0
- package/dist/flow/spawn-utils.d.ts.map +1 -0
- package/dist/flow/spawn-utils.js +40 -0
- package/dist/flow/spawn-utils.js.map +1 -0
- package/dist/flow/store.d.ts.map +1 -1
- package/dist/flow/store.js +2 -8
- package/dist/flow/store.js.map +1 -1
- package/dist/flow/transition.d.ts +0 -1
- package/dist/flow/transition.d.ts.map +1 -1
- package/dist/flow/transition.js +0 -3
- package/dist/flow/transition.js.map +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +94 -57
- package/dist/index.js.map +1 -1
- package/dist/io/atomic-write.d.ts +10 -0
- package/dist/io/atomic-write.d.ts.map +1 -0
- package/dist/io/atomic-write.js +30 -0
- package/dist/io/atomic-write.js.map +1 -0
- package/dist/notify/notify.d.ts.map +1 -1
- package/dist/notify/notify.js +1 -4
- package/dist/notify/notify.js.map +1 -1
- package/dist/snapshot/cli-args.d.ts +1 -2
- package/dist/snapshot/cli-args.d.ts.map +1 -1
- package/dist/snapshot/runner-events.d.ts +10 -0
- package/dist/snapshot/runner-events.d.ts.map +1 -1
- package/dist/snapshot/runner-events.js +112 -30
- package/dist/snapshot/runner-events.js.map +1 -1
- package/dist/snapshot/structured-output.d.ts.map +1 -1
- package/dist/snapshot/structured-output.js +3 -1
- package/dist/snapshot/structured-output.js.map +1 -1
- package/dist/snapshot/trace-output.d.ts.map +1 -1
- package/dist/snapshot/trace-output.js +8 -4
- package/dist/snapshot/trace-output.js.map +1 -1
- package/dist/steering/sliding-prompt.d.ts.map +1 -1
- package/dist/steering/sliding-prompt.js +12 -15
- package/dist/steering/sliding-prompt.js.map +1 -1
- package/dist/steering/tool-utils.d.ts +3 -3
- package/dist/steering/tool-utils.d.ts.map +1 -1
- package/dist/steering/tool-utils.js +3 -3
- package/dist/steering/tool-utils.js.map +1 -1
- package/dist/tools/ask-user.js.map +1 -1
- package/dist/tools/timed-bash.d.ts.map +1 -1
- package/dist/tools/timed-bash.js +8 -3
- package/dist/tools/timed-bash.js.map +1 -1
- package/dist/tools/trace.d.ts +0 -1
- package/dist/tools/trace.d.ts.map +1 -1
- package/dist/tools/trace.js +79 -62
- package/dist/tools/trace.js.map +1 -1
- package/dist/tools/web-ops.d.ts +0 -49
- package/dist/tools/web-ops.d.ts.map +1 -1
- package/dist/tools/web-ops.js +9 -9
- package/dist/tools/web-ops.js.map +1 -1
- package/dist/tui/body-render.d.ts +31 -0
- package/dist/tui/body-render.d.ts.map +1 -0
- package/dist/tui/body-render.js +589 -0
- package/dist/tui/body-render.js.map +1 -0
- package/dist/tui/context-display.d.ts +18 -0
- package/dist/tui/context-display.d.ts.map +1 -0
- package/dist/tui/context-display.js +29 -0
- package/dist/tui/context-display.js.map +1 -0
- package/dist/tui/flow-colors.d.ts +6 -1
- package/dist/tui/flow-colors.d.ts.map +1 -1
- package/dist/tui/flow-colors.js +1 -0
- package/dist/tui/flow-colors.js.map +1 -1
- package/dist/tui/flow-live-state.d.ts +36 -0
- package/dist/tui/flow-live-state.d.ts.map +1 -0
- package/dist/tui/flow-live-state.js +53 -0
- package/dist/tui/flow-live-state.js.map +1 -0
- package/dist/tui/grouping.d.ts +27 -0
- package/dist/tui/grouping.d.ts.map +1 -0
- package/dist/tui/grouping.js +191 -0
- package/dist/tui/grouping.js.map +1 -0
- package/dist/tui/header.d.ts +25 -0
- package/dist/tui/header.d.ts.map +1 -0
- package/dist/tui/header.js +95 -0
- package/dist/tui/header.js.map +1 -0
- package/dist/tui/render-utils.d.ts +1 -0
- package/dist/tui/render-utils.d.ts.map +1 -1
- package/dist/tui/render-utils.js +4 -5
- package/dist/tui/render-utils.js.map +1 -1
- package/dist/tui/render.d.ts +19 -33
- package/dist/tui/render.d.ts.map +1 -1
- package/dist/tui/render.js +112 -1014
- package/dist/tui/render.js.map +1 -1
- package/dist/tui/scramble/animation-status.d.ts +5 -0
- package/dist/tui/scramble/animation-status.d.ts.map +1 -0
- package/dist/tui/scramble/animation-status.js +93 -0
- package/dist/tui/scramble/animation-status.js.map +1 -0
- package/dist/tui/scramble/constants.d.ts +0 -4
- package/dist/tui/scramble/constants.d.ts.map +1 -1
- package/dist/tui/scramble/constants.js +3 -3
- package/dist/tui/scramble/constants.js.map +1 -1
- package/dist/tui/scramble/dynamic-text.d.ts +10 -0
- package/dist/tui/scramble/dynamic-text.d.ts.map +1 -0
- package/dist/tui/scramble/dynamic-text.js +19 -0
- package/dist/tui/scramble/dynamic-text.js.map +1 -0
- package/dist/tui/scramble/index.d.ts +8 -2
- package/dist/tui/scramble/index.d.ts.map +1 -1
- package/dist/tui/scramble/index.js +8 -1
- package/dist/tui/scramble/index.js.map +1 -1
- package/dist/tui/scramble/lifecycle.d.ts +4 -0
- package/dist/tui/scramble/lifecycle.d.ts.map +1 -0
- package/dist/tui/scramble/lifecycle.js +75 -0
- package/dist/tui/scramble/lifecycle.js.map +1 -0
- package/dist/tui/scramble/line-state.d.ts +5 -0
- package/dist/tui/scramble/line-state.d.ts.map +1 -0
- package/dist/tui/scramble/line-state.js +99 -0
- package/dist/tui/scramble/line-state.js.map +1 -0
- package/dist/tui/scramble/manager.d.ts +3 -14
- package/dist/tui/scramble/manager.d.ts.map +1 -1
- package/dist/tui/scramble/manager.js +22 -405
- package/dist/tui/scramble/manager.js.map +1 -1
- package/dist/tui/scramble/singleton.d.ts +3 -0
- package/dist/tui/scramble/singleton.d.ts.map +1 -0
- package/dist/tui/scramble/singleton.js +3 -0
- package/dist/tui/scramble/singleton.js.map +1 -0
- package/dist/tui/scramble/timer.d.ts +6 -0
- package/dist/tui/scramble/timer.d.ts.map +1 -0
- package/dist/tui/scramble/timer.js +28 -0
- package/dist/tui/scramble/timer.js.map +1 -0
- package/dist/tui/scramble/utils.d.ts +0 -2
- package/dist/tui/scramble/utils.d.ts.map +1 -1
- package/dist/tui/scramble/utils.js +0 -9
- package/dist/tui/scramble/utils.js.map +1 -1
- package/dist/tui/scramble/value-flash.d.ts +6 -0
- package/dist/tui/scramble/value-flash.d.ts.map +1 -0
- package/dist/tui/scramble/value-flash.js +141 -0
- package/dist/tui/scramble/value-flash.js.map +1 -0
- package/dist/tui/traces.d.ts +13 -0
- package/dist/tui/traces.d.ts.map +1 -0
- package/dist/tui/traces.js +97 -0
- package/dist/tui/traces.js.map +1 -0
- package/dist/types/ui.d.ts +0 -4
- package/dist/types/ui.d.ts.map +1 -1
- package/dist/types/ui.js +1 -30
- package/dist/types/ui.js.map +1 -1
- package/package.json +5 -1
package/dist/flow/executor.js
CHANGED
|
@@ -5,43 +5,24 @@
|
|
|
5
5
|
* project-flow confirmation, parallel execution with failover, caching,
|
|
6
6
|
* and telemetry.
|
|
7
7
|
*/
|
|
8
|
-
import { isFlowSuccess, isFlowError,
|
|
9
|
-
|
|
10
|
-
const MAX_AUDIT_OUTPUT_SLICE = 6000;
|
|
11
|
-
import { mapFlowConcurrent, runFlow } from "./runner.js";
|
|
8
|
+
import { isFlowSuccess, isFlowError, emptyFlowUsage } from "../types/flow.js";
|
|
9
|
+
import { mapFlowConcurrent } from "./runner.js";
|
|
12
10
|
import { getFlowSummaryText } from "../snapshot/runner-events.js";
|
|
13
|
-
import { normalizeFlowModeName,
|
|
14
|
-
import {
|
|
11
|
+
import { normalizeFlowModeName, selectFlowModelStrategy } from "../config/config.js";
|
|
12
|
+
import { getImpliedAuditLoop } from "./complexity.js";
|
|
15
13
|
import { setFlowComplete } from "../notify/notify-state.js";
|
|
16
14
|
import { setLiveText, clearLiveText } from '../tui/scramble/index.js';
|
|
15
|
+
import { publishFlowLiveText, publishFlowLiveTextAtIndex } from './flow-live.js';
|
|
17
16
|
import { logWarn } from '../config/log.js';
|
|
18
17
|
import { markFlowCompleted } from '../flow/index.js';
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
*/
|
|
25
|
-
export function preserveMetadata(target, source) {
|
|
26
|
-
if (source?.pingPongMeta) {
|
|
27
|
-
target.pingPongMeta = source.pingPongMeta;
|
|
28
|
-
}
|
|
29
|
-
if (source?.auditParentType) {
|
|
30
|
-
target.auditParentType = source.auditParentType;
|
|
31
|
-
}
|
|
32
|
-
if (source?.auditLoopGroupId !== undefined) {
|
|
33
|
-
target.auditLoopGroupId = source.auditLoopGroupId;
|
|
34
|
-
}
|
|
35
|
-
}
|
|
18
|
+
import { preserveMetadata, getFlowCycleViolations, createGhostResult, } from "./cycle-guard.js";
|
|
19
|
+
import { resolveAuditModel, buildReworkIntent, buildGroupAuditIntent, } from "./audit-formatters.js";
|
|
20
|
+
import { executeSingleFlow } from "./execute-single.js";
|
|
21
|
+
export { preserveMetadata, createGhostResult, shouldFailover } from "./cycle-guard.js";
|
|
22
|
+
export { buildReworkIntent, buildGroupAuditIntent, formatPriorAuditHistory, formatPriorBuildOutputs } from "./audit-formatters.js";
|
|
36
23
|
// ---------------------------------------------------------------------------
|
|
37
24
|
// Helpers
|
|
38
25
|
// ---------------------------------------------------------------------------
|
|
39
|
-
function getFlowCycleViolations(requestedNames, ancestorFlowStack) {
|
|
40
|
-
if (requestedNames.size === 0 || ancestorFlowStack.length === 0)
|
|
41
|
-
return [];
|
|
42
|
-
const stackSet = new Set(ancestorFlowStack);
|
|
43
|
-
return Array.from(requestedNames).filter((name) => stackSet.has(name));
|
|
44
|
-
}
|
|
45
26
|
function getRequestedProjectFlows(flows, requestedNames) {
|
|
46
27
|
return Array.from(requestedNames)
|
|
47
28
|
.map((name) => flows.find((f) => f.name === name.toLowerCase()))
|
|
@@ -61,274 +42,6 @@ async function confirmProjectFlowsIfNeeded(projectFlows, projectFlowsDir, hasUI,
|
|
|
61
42
|
blocked: `Blocked: project-local flow confirmation required in non-UI mode.\nFlows: ${names}\nRe-run with confirmProjectFlows: false if trusted.`,
|
|
62
43
|
};
|
|
63
44
|
}
|
|
64
|
-
function shouldFailover(result) {
|
|
65
|
-
if (result.stopReason === "aborted")
|
|
66
|
-
return false;
|
|
67
|
-
const text = `${result.errorMessage ?? ""}\n${result.stderr ?? ""}`.toLowerCase();
|
|
68
|
-
if (!text.trim())
|
|
69
|
-
return false;
|
|
70
|
-
if (text.includes("permission") || text.includes("invalid tool") || text.includes("bad settings")) {
|
|
71
|
-
return false;
|
|
72
|
-
}
|
|
73
|
-
if (result.exitCode > 0)
|
|
74
|
-
return true;
|
|
75
|
-
// Some child runs log HTTP 400 / "Param Incorrect" to stderr while exiting 0
|
|
76
|
-
// without completing a turn — treat as retryable for model failover.
|
|
77
|
-
if (!isFlowComplete(result) && (text.includes("400") && text.includes("param"))) {
|
|
78
|
-
return true;
|
|
79
|
-
}
|
|
80
|
-
return false;
|
|
81
|
-
}
|
|
82
|
-
export function createGhostResult(type, intent, aim, model, maxContextTokens) {
|
|
83
|
-
return {
|
|
84
|
-
type,
|
|
85
|
-
agentSource: "unknown",
|
|
86
|
-
intent,
|
|
87
|
-
aim,
|
|
88
|
-
exitCode: -1,
|
|
89
|
-
messages: [],
|
|
90
|
-
stderr: "",
|
|
91
|
-
usage: emptyFlowUsage(),
|
|
92
|
-
...(model ? { model } : {}),
|
|
93
|
-
...(maxContextTokens !== undefined ? { maxContextTokens } : {}),
|
|
94
|
-
};
|
|
95
|
-
}
|
|
96
|
-
export function resolveAuditModel(flows, tierOverrideResolver, strategy, fallbackModel) {
|
|
97
|
-
const auditFlow = flows.find((f) => f.name === "audit");
|
|
98
|
-
const tier = auditFlow?.tier ?? "flash";
|
|
99
|
-
const { candidates } = resolveFlowModelCandidates({
|
|
100
|
-
tier,
|
|
101
|
-
flowModel: auditFlow?.model,
|
|
102
|
-
cliTierOverride: tierOverrideResolver(tier),
|
|
103
|
-
strategy,
|
|
104
|
-
fallbackModel,
|
|
105
|
-
});
|
|
106
|
-
const model = candidates[0];
|
|
107
|
-
const maxContextTokens = resolveModelContextWindow(model);
|
|
108
|
-
return { model, maxContextTokens };
|
|
109
|
-
}
|
|
110
|
-
export function buildReworkIntent(originalIntent, buildAim, acceptance, auditFeedback, cycleHistory) {
|
|
111
|
-
const parts = [
|
|
112
|
-
`## Original Intent`,
|
|
113
|
-
originalIntent,
|
|
114
|
-
``,
|
|
115
|
-
`## Build Aim`,
|
|
116
|
-
buildAim,
|
|
117
|
-
``,
|
|
118
|
-
];
|
|
119
|
-
if (acceptance) {
|
|
120
|
-
parts.push(`## Acceptance Criteria`, acceptance, ``);
|
|
121
|
-
}
|
|
122
|
-
parts.push(`## Audit Feedback`, auditFeedback, ``);
|
|
123
|
-
if (cycleHistory && cycleHistory.length > 0) {
|
|
124
|
-
// Show all prior build outputs (deep-loop: every cycle, not just latest)
|
|
125
|
-
const buildOutputs = formatPriorBuildOutputs(cycleHistory);
|
|
126
|
-
if (buildOutputs) {
|
|
127
|
-
parts.push(buildOutputs, ``);
|
|
128
|
-
}
|
|
129
|
-
// Show all prior audit verdicts/feedbacks
|
|
130
|
-
const auditHistory = formatPriorAuditHistory(cycleHistory);
|
|
131
|
-
if (auditHistory) {
|
|
132
|
-
parts.push(auditHistory, ``);
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
parts.push(`Fix the above issues, preserving the Original Intent and incorporating all prior cycle feedback.`);
|
|
136
|
-
return parts.join("\n");
|
|
137
|
-
}
|
|
138
|
-
async function executeSingleFlow(deps, item, allResults, resultIndex, toolCallId, emitProgress, selectedFlowModelConfig) {
|
|
139
|
-
const { flows, currentDepth, maxDepth, ancestorFlowStack, preventCycles, toolOptimize, structuredOutput, cwd, defaultComplexity, signal, makeDetails, tierOverrideResolver, fallbackModel, forkSessionSnapshotJsonl, onFlowMetrics, goalContext, } = deps;
|
|
140
|
-
const normalizedType = item.type.toLowerCase();
|
|
141
|
-
const complexity = resolveComplexity(item.complexity, defaultComplexity);
|
|
142
|
-
const lookupName = normalizedType;
|
|
143
|
-
const targetFlow = flows.find((f) => f.name === lookupName);
|
|
144
|
-
const effectiveMaxDepth = targetFlow?.maxDepth !== undefined ? targetFlow.maxDepth : maxDepth;
|
|
145
|
-
const shouldInheritContext = targetFlow?.inheritContext !== false;
|
|
146
|
-
const tier = targetFlow?.tier ?? "flash";
|
|
147
|
-
const { candidates } = resolveFlowModelCandidates({
|
|
148
|
-
tier,
|
|
149
|
-
flowModel: targetFlow?.model,
|
|
150
|
-
cliTierOverride: tierOverrideResolver(tier),
|
|
151
|
-
strategy: selectedFlowModelConfig.strategy,
|
|
152
|
-
fallbackModel,
|
|
153
|
-
});
|
|
154
|
-
const attemptModels = candidates.length > 0 ? candidates : [undefined];
|
|
155
|
-
const attemptedModels = [];
|
|
156
|
-
let result = allResults[resultIndex];
|
|
157
|
-
const flowStart = Date.now();
|
|
158
|
-
for (let attempt = 0; attempt < attemptModels.length; attempt++) {
|
|
159
|
-
const candidateModel = attemptModels[attempt];
|
|
160
|
-
if (candidateModel)
|
|
161
|
-
attemptedModels.push(candidateModel);
|
|
162
|
-
const attemptStartMs = Date.now();
|
|
163
|
-
const attemptTimeoutMs = getComplexityTimeoutMs(complexity);
|
|
164
|
-
const maxContextTokens = resolveModelContextWindow(candidateModel);
|
|
165
|
-
const previous = allResults[resultIndex];
|
|
166
|
-
allResults[resultIndex] = {
|
|
167
|
-
type: normalizedType,
|
|
168
|
-
agentSource: targetFlow?.source ?? "unknown",
|
|
169
|
-
intent: item.intent,
|
|
170
|
-
aim: item.aim,
|
|
171
|
-
exitCode: -1,
|
|
172
|
-
messages: [],
|
|
173
|
-
stderr: "",
|
|
174
|
-
usage: emptyFlowUsage(),
|
|
175
|
-
model: candidateModel,
|
|
176
|
-
startedAtMs: attemptStartMs,
|
|
177
|
-
deadlineAtMs: attemptStartMs + attemptTimeoutMs,
|
|
178
|
-
...(maxContextTokens !== undefined ? { maxContextTokens } : {}),
|
|
179
|
-
};
|
|
180
|
-
preserveMetadata(allResults[resultIndex], previous);
|
|
181
|
-
emitProgress();
|
|
182
|
-
result = await runFlow({
|
|
183
|
-
cwd,
|
|
184
|
-
flows,
|
|
185
|
-
flowName: lookupName,
|
|
186
|
-
intent: item.intent,
|
|
187
|
-
aim: item.aim,
|
|
188
|
-
acceptance: item.acceptance,
|
|
189
|
-
taskCwd: item.cwd,
|
|
190
|
-
forkSessionSnapshotJsonl: shouldInheritContext ? forkSessionSnapshotJsonl : null,
|
|
191
|
-
parentDepth: currentDepth,
|
|
192
|
-
parentFlowStack: ancestorFlowStack,
|
|
193
|
-
maxDepth: effectiveMaxDepth,
|
|
194
|
-
preventCycles,
|
|
195
|
-
toolOptimize,
|
|
196
|
-
structuredOutput,
|
|
197
|
-
complexity,
|
|
198
|
-
model: candidateModel,
|
|
199
|
-
maxContextTokens,
|
|
200
|
-
goalContext,
|
|
201
|
-
debugMode: deps.debugMode,
|
|
202
|
-
tools: item._childTools,
|
|
203
|
-
preDispatchResults: item.preDispatchResults,
|
|
204
|
-
signal,
|
|
205
|
-
onUpdate: (partial) => {
|
|
206
|
-
if (partial.details?.results[0]) {
|
|
207
|
-
const previous = allResults[resultIndex];
|
|
208
|
-
allResults[resultIndex] = partial.details.results[0];
|
|
209
|
-
preserveMetadata(allResults[resultIndex], previous);
|
|
210
|
-
const flowText = partial.content?.[0]?.text;
|
|
211
|
-
if (flowText !== undefined) {
|
|
212
|
-
setLiveText(`${toolCallId || 'collapsed'}#${resultIndex}`, flowText);
|
|
213
|
-
setLiveText(`collapsed#${resultIndex}`, flowText);
|
|
214
|
-
}
|
|
215
|
-
emitProgress(partial.content?.[0]?.text);
|
|
216
|
-
}
|
|
217
|
-
},
|
|
218
|
-
makeDetails,
|
|
219
|
-
});
|
|
220
|
-
const previous2 = allResults[resultIndex];
|
|
221
|
-
allResults[resultIndex] = result;
|
|
222
|
-
preserveMetadata(allResults[resultIndex], previous2);
|
|
223
|
-
emitProgress();
|
|
224
|
-
if (isFlowSuccess(result) || signal?.aborted)
|
|
225
|
-
break;
|
|
226
|
-
if (attempt < attemptModels.length - 1 && shouldFailover(result)) {
|
|
227
|
-
continue;
|
|
228
|
-
}
|
|
229
|
-
break;
|
|
230
|
-
}
|
|
231
|
-
if (result && !isFlowSuccess(result) && attemptedModels.length > 1) {
|
|
232
|
-
const summary = `Model failover attempts: ${attemptedModels.join(" -> ")}`;
|
|
233
|
-
const baseStderr = result.stderr.trim();
|
|
234
|
-
result.stderr = baseStderr ? `${baseStderr}\n\n${summary}` : summary;
|
|
235
|
-
const previous3 = allResults[resultIndex];
|
|
236
|
-
allResults[resultIndex] = result;
|
|
237
|
-
preserveMetadata(allResults[resultIndex], previous3);
|
|
238
|
-
emitProgress();
|
|
239
|
-
}
|
|
240
|
-
if (onFlowMetrics) {
|
|
241
|
-
const flowDuration = Date.now() - flowStart;
|
|
242
|
-
onFlowMetrics({
|
|
243
|
-
type: normalizedType,
|
|
244
|
-
durationMs: flowDuration,
|
|
245
|
-
exitCode: result.exitCode,
|
|
246
|
-
success: isFlowSuccess(result),
|
|
247
|
-
model: result.model,
|
|
248
|
-
failoverCount: Math.max(0, attemptedModels.length - 1),
|
|
249
|
-
usage: result.usage,
|
|
250
|
-
source: result.agentSource,
|
|
251
|
-
depth: currentDepth + 1,
|
|
252
|
-
});
|
|
253
|
-
}
|
|
254
|
-
return result;
|
|
255
|
-
}
|
|
256
|
-
export function formatPriorAuditHistory(entries) {
|
|
257
|
-
if (entries.length === 0)
|
|
258
|
-
return "";
|
|
259
|
-
const lines = entries.map((e) => {
|
|
260
|
-
const parts = [
|
|
261
|
-
`**Cycle ${e.cycle + 1}**`,
|
|
262
|
-
`- Verdict: ${e.verdict}`,
|
|
263
|
-
];
|
|
264
|
-
if (e.feedback) {
|
|
265
|
-
parts.push(`- Feedback: ${e.feedback.slice(0, 2000)}`);
|
|
266
|
-
}
|
|
267
|
-
if (e.buildFeedbacks && e.buildFeedbacks.length > 0) {
|
|
268
|
-
parts.push(`- Per-Build Feedback:`);
|
|
269
|
-
e.buildFeedbacks.forEach((fb, i) => {
|
|
270
|
-
if (fb) {
|
|
271
|
-
parts.push(` - Build ${i + 1}: ${fb.slice(0, 1500)}`);
|
|
272
|
-
}
|
|
273
|
-
else {
|
|
274
|
-
parts.push(` - Build ${i + 1}: pass`);
|
|
275
|
-
}
|
|
276
|
-
});
|
|
277
|
-
}
|
|
278
|
-
return parts.join("\n");
|
|
279
|
-
});
|
|
280
|
-
return `## Prior Audit History\n\n${lines.join("\n\n")}`;
|
|
281
|
-
}
|
|
282
|
-
export function formatPriorBuildOutputs(entries) {
|
|
283
|
-
if (entries.length === 0)
|
|
284
|
-
return "";
|
|
285
|
-
const lines = entries.map((e) => {
|
|
286
|
-
const parts = [`**Cycle ${e.cycle + 1}**`];
|
|
287
|
-
if (e.buildOutputs.length > 0) {
|
|
288
|
-
parts.push(`- Build Outputs:`);
|
|
289
|
-
e.buildOutputs.forEach((bo, i) => {
|
|
290
|
-
parts.push(` - Build ${i + 1}: ${bo.slice(0, 3000)}`);
|
|
291
|
-
});
|
|
292
|
-
}
|
|
293
|
-
return parts.join("\n");
|
|
294
|
-
});
|
|
295
|
-
return `## Prior Build Outputs\n\n${lines.join("\n\n")}`;
|
|
296
|
-
}
|
|
297
|
-
export function buildGroupAuditIntent(builds, cycleHistory) {
|
|
298
|
-
const sections = builds.map((b, i) => {
|
|
299
|
-
const section = [
|
|
300
|
-
`### Build ${i + 1}`,
|
|
301
|
-
``,
|
|
302
|
-
`## Build Aim`,
|
|
303
|
-
b.aim,
|
|
304
|
-
``,
|
|
305
|
-
];
|
|
306
|
-
if (b.acceptance) {
|
|
307
|
-
section.push(`## Acceptance Criteria`, b.acceptance, ``);
|
|
308
|
-
}
|
|
309
|
-
if (b.intent) {
|
|
310
|
-
section.push(`## Build Intent`, b.intent, ``);
|
|
311
|
-
}
|
|
312
|
-
section.push(`## Build Output`, b.output.slice(0, MAX_AUDIT_OUTPUT_SLICE));
|
|
313
|
-
return section.join("\n");
|
|
314
|
-
});
|
|
315
|
-
const parts = [
|
|
316
|
-
...sections,
|
|
317
|
-
``,
|
|
318
|
-
];
|
|
319
|
-
if (cycleHistory && cycleHistory.length > 0) {
|
|
320
|
-
const auditHistory = formatPriorAuditHistory(cycleHistory);
|
|
321
|
-
if (auditHistory) {
|
|
322
|
-
parts.push(auditHistory, ``);
|
|
323
|
-
}
|
|
324
|
-
const buildOutputs = formatPriorBuildOutputs(cycleHistory);
|
|
325
|
-
if (buildOutputs) {
|
|
326
|
-
parts.push(buildOutputs, ``);
|
|
327
|
-
}
|
|
328
|
-
}
|
|
329
|
-
parts.push(`Check for: security issues, correctness, completeness, edge cases, and any overlooked requirements per build. For each build, indicate whether it passes or needs rework with specific actionable feedback.`);
|
|
330
|
-
return parts.join("\n\n");
|
|
331
|
-
}
|
|
332
45
|
async function executeGroupedPingPong(deps, group, allResults, toolCallId, emitProgress, selectedFlowModelConfig) {
|
|
333
46
|
const { items, auditLoop, buildIndices, auditIndex } = group;
|
|
334
47
|
const maxCycles = (auditLoop ?? 0) + 1;
|
|
@@ -336,8 +49,6 @@ async function executeGroupedPingPong(deps, group, allResults, toolCallId, emitP
|
|
|
336
49
|
const verdictHistory = [];
|
|
337
50
|
const cycleHistory = [];
|
|
338
51
|
const auditFeedbacks = new Array(items.length).fill(null);
|
|
339
|
-
// Initialize all slots (re-creates ghosts; must stamp auditLoopGroupId
|
|
340
|
-
// because executeFlows pre-allocation gets overwritten here).
|
|
341
52
|
for (let i = 0; i < items.length; i++) {
|
|
342
53
|
allResults[buildIndices[i]] = createGhostResult(items[i].type, items[i].intent, items[i].aim);
|
|
343
54
|
allResults[buildIndices[i]].status = "running";
|
|
@@ -352,7 +63,6 @@ async function executeGroupedPingPong(deps, group, allResults, toolCallId, emitP
|
|
|
352
63
|
const key = toolCallId || 'collapsed';
|
|
353
64
|
const buildResults = new Array(items.length);
|
|
354
65
|
while (cycle < maxCycles) {
|
|
355
|
-
// ─── Phase A: Run all builds in parallel ───
|
|
356
66
|
for (let i = 0; i < items.length; i++) {
|
|
357
67
|
allResults[buildIndices[i]].status = "running";
|
|
358
68
|
allResults[buildIndices[i]].exitCode = -1;
|
|
@@ -366,7 +76,6 @@ async function executeGroupedPingPong(deps, group, allResults, toolCallId, emitP
|
|
|
366
76
|
setLiveText(`${key}#${auditIndex}`, "[awaiting...]");
|
|
367
77
|
setLiveText(`collapsed#${auditIndex}`, "[awaiting...]");
|
|
368
78
|
emitProgress();
|
|
369
|
-
// Run all builds in parallel
|
|
370
79
|
const buildPromises = items.map((item, i) => {
|
|
371
80
|
const buildInput = cycle > 0
|
|
372
81
|
? buildReworkIntent(item.intent, item.aim, item.acceptance, auditFeedbacks[i] ?? "No issues found.", cycleHistory)
|
|
@@ -385,7 +94,6 @@ async function executeGroupedPingPong(deps, group, allResults, toolCallId, emitP
|
|
|
385
94
|
allResults[buildIndices[i]].deadlineAtMs = undefined;
|
|
386
95
|
}
|
|
387
96
|
emitProgress();
|
|
388
|
-
// Check if any build failed
|
|
389
97
|
const anyBuildFailed = buildResults.some(r => !isFlowSuccess(r));
|
|
390
98
|
if (anyBuildFailed) {
|
|
391
99
|
const { model: skipAuditModel, maxContextTokens: skipAuditMaxCtx } = resolveAuditModel(deps.flows, deps.tierOverrideResolver, selectedFlowModelConfig.strategy, deps.fallbackModel);
|
|
@@ -400,7 +108,6 @@ async function executeGroupedPingPong(deps, group, allResults, toolCallId, emitP
|
|
|
400
108
|
emitProgress();
|
|
401
109
|
break;
|
|
402
110
|
}
|
|
403
|
-
// ─── Phase B: Run ONE audit that reviews all builds ───
|
|
404
111
|
for (let i = 0; i < items.length; i++) {
|
|
405
112
|
allResults[buildIndices[i]].status = "awaiting";
|
|
406
113
|
clearLiveText(`${key}#${buildIndices[i]}`);
|
|
@@ -429,7 +136,6 @@ async function executeGroupedPingPong(deps, group, allResults, toolCallId, emitP
|
|
|
429
136
|
const auditResult = await executeSingleFlow(deps, auditItem, allResults, auditIndex, toolCallId, emitProgress, selectedFlowModelConfig);
|
|
430
137
|
auditResult.auditParentType = items[0].type;
|
|
431
138
|
allResults[auditIndex] = auditResult;
|
|
432
|
-
// Parse per-build verdicts
|
|
433
139
|
const perBuildVerdicts = auditResult.structuredOutput?.builds;
|
|
434
140
|
const topLevelVerdict = auditResult.structuredOutput?.verdict ?? "pass";
|
|
435
141
|
const topLevelFeedback = auditResult.structuredOutput?.feedback;
|
|
@@ -447,7 +153,6 @@ async function executeGroupedPingPong(deps, group, allResults, toolCallId, emitP
|
|
|
447
153
|
}
|
|
448
154
|
}
|
|
449
155
|
else {
|
|
450
|
-
// Fallback: top-level verdict applies to all builds
|
|
451
156
|
if (topLevelVerdict === "rework") {
|
|
452
157
|
for (let i = 0; i < items.length; i++) {
|
|
453
158
|
auditFeedbacks[i] = topLevelFeedback ?? "Fix issues found in audit.";
|
|
@@ -480,12 +185,10 @@ async function executeGroupedPingPong(deps, group, allResults, toolCallId, emitP
|
|
|
480
185
|
break;
|
|
481
186
|
}
|
|
482
187
|
if (cycle + 1 >= maxCycles) {
|
|
483
|
-
break;
|
|
188
|
+
break;
|
|
484
189
|
}
|
|
485
190
|
cycle++;
|
|
486
|
-
// Continue loop — builds needing rework will re-run
|
|
487
191
|
}
|
|
488
|
-
// Finalize: set real exit codes
|
|
489
192
|
for (let i = 0; i < items.length; i++) {
|
|
490
193
|
allResults[buildIndices[i]].exitCode = isFlowSuccess(buildResults[i]) ? 0 : (buildResults[i].exitCode > 0 ? buildResults[i].exitCode : 1);
|
|
491
194
|
allResults[buildIndices[i]].status = isFlowSuccess(buildResults[i]) ? "done" : "error";
|
|
@@ -497,7 +200,6 @@ async function executeGroupedPingPong(deps, group, allResults, toolCallId, emitP
|
|
|
497
200
|
allResults[auditIndex].exitCode = isFlowSuccess(allResults[auditIndex]) ? 0 : (allResults[auditIndex].exitCode > 0 ? allResults[auditIndex].exitCode : 1);
|
|
498
201
|
allResults[auditIndex].status = "done";
|
|
499
202
|
}
|
|
500
|
-
// Populate pingPongMeta on each build result
|
|
501
203
|
for (let i = 0; i < items.length; i++) {
|
|
502
204
|
allResults[buildIndices[i]].pingPongMeta = {
|
|
503
205
|
cycles: cycle + 1,
|
|
@@ -505,20 +207,22 @@ async function executeGroupedPingPong(deps, group, allResults, toolCallId, emitP
|
|
|
505
207
|
finalVerdict: allResults[auditIndex].structuredOutput?.verdict ?? (allResults[auditIndex].status === "skipped" ? "fail" : "pass"),
|
|
506
208
|
};
|
|
507
209
|
}
|
|
210
|
+
if (allResults[auditIndex].status !== "skipped") {
|
|
211
|
+
allResults[auditIndex].pingPongMeta = {
|
|
212
|
+
cycles: cycle + 1,
|
|
213
|
+
verdicts: verdictHistory,
|
|
214
|
+
finalVerdict: allResults[auditIndex].structuredOutput?.verdict ?? "pass",
|
|
215
|
+
};
|
|
216
|
+
}
|
|
508
217
|
emitProgress();
|
|
509
218
|
return buildResults;
|
|
510
219
|
}
|
|
511
220
|
// ---------------------------------------------------------------------------
|
|
512
221
|
// FlowExecutor
|
|
513
222
|
// ---------------------------------------------------------------------------
|
|
514
|
-
/**
|
|
515
|
-
* Execute a set of flow tasks with full orchestration: cycle detection,
|
|
516
|
-
* project confirmation, parallel execution with model failover, and telemetry.
|
|
517
|
-
*/
|
|
518
223
|
export async function executeFlows(deps, params, toolCallId, auditLoop) {
|
|
519
224
|
const { flows, currentDepth, maxDepth, ancestorFlowStack, preventCycles, toolOptimize, structuredOutput, cwd, loadedFlowModelConfigs, maxConcurrency, defaultComplexity, signal, onUpdate, makeDetails, getFlag, tierOverrideResolver, fallbackModel, forkSessionSnapshotJsonl, projectFlowsDir, hasUI, uiConfirm, onFlowMetrics, confirmProjectFlows, goalContext, } = deps;
|
|
520
225
|
const requested = new Set(params.map((f) => f.type.toLowerCase()));
|
|
521
|
-
// Cycle check
|
|
522
226
|
if (preventCycles) {
|
|
523
227
|
const violations = getFlowCycleViolations(requested, ancestorFlowStack);
|
|
524
228
|
if (violations.length > 0) {
|
|
@@ -533,7 +237,6 @@ export async function executeFlows(deps, params, toolCallId, auditLoop) {
|
|
|
533
237
|
};
|
|
534
238
|
}
|
|
535
239
|
}
|
|
536
|
-
// Project flow confirmation
|
|
537
240
|
const projectFlows = getRequestedProjectFlows(flows, requested);
|
|
538
241
|
if (projectFlows.length > 0 && confirmProjectFlows !== false) {
|
|
539
242
|
const { ok, blocked } = await confirmProjectFlowsIfNeeded(projectFlows, projectFlowsDir, hasUI, uiConfirm);
|
|
@@ -545,18 +248,15 @@ export async function executeFlows(deps, params, toolCallId, auditLoop) {
|
|
|
545
248
|
};
|
|
546
249
|
}
|
|
547
250
|
}
|
|
548
|
-
// Resolve model strategy
|
|
549
251
|
const cliFlowMode = normalizeFlowModeName(getFlag("flow-mode"));
|
|
550
252
|
const cliFlowModelConfig = normalizeFlowModeName(getFlag("flow-model-config"));
|
|
551
253
|
if (cliFlowMode !== undefined && cliFlowModelConfig !== undefined && cliFlowMode !== cliFlowModelConfig) {
|
|
552
254
|
logWarn(`[pi-agent-flow] Both --flow-mode "${cliFlowMode}" and --flow-model-config "${cliFlowModelConfig}" were provided. Using --flow-mode.`);
|
|
553
255
|
}
|
|
554
256
|
const selectedFlowModelConfig = selectFlowModelStrategy(loadedFlowModelConfigs.configs, cliFlowMode ?? cliFlowModelConfig ?? loadedFlowModelConfigs.selectedName);
|
|
555
|
-
// Partition params into regular and grouped ping-pong flows
|
|
556
257
|
const regularParams = [];
|
|
557
258
|
const regularIndices = [];
|
|
558
259
|
const groups = [];
|
|
559
|
-
// Compute effective audit loop per build = max(explicit override, complexity-implied)
|
|
560
260
|
const effectiveAuditLoops = params.map((p) => {
|
|
561
261
|
if (p.type.toLowerCase() === "build") {
|
|
562
262
|
return Math.max(auditLoop ?? 0, getImpliedAuditLoop(p.complexity));
|
|
@@ -583,8 +283,8 @@ export async function executeFlows(deps, params, toolCallId, auditLoop) {
|
|
|
583
283
|
items: [params[i]],
|
|
584
284
|
auditLoop: effectiveAuditLoops[i],
|
|
585
285
|
buildIndices: [buildIndex],
|
|
586
|
-
auditIndex: -1,
|
|
587
|
-
groupId: -1,
|
|
286
|
+
auditIndex: -1,
|
|
287
|
+
groupId: -1,
|
|
588
288
|
};
|
|
589
289
|
groups.push(buildGroup);
|
|
590
290
|
}
|
|
@@ -593,17 +293,14 @@ export async function executeFlows(deps, params, toolCallId, auditLoop) {
|
|
|
593
293
|
regularIndices.push(nextIndex);
|
|
594
294
|
regularParams.push(params[i]);
|
|
595
295
|
nextIndex++;
|
|
596
|
-
// Non-build param breaks contiguity — reset so later builds start a new group
|
|
597
296
|
buildGroup = undefined;
|
|
598
297
|
}
|
|
599
298
|
}
|
|
600
|
-
// Assign audit indices after all builds are allocated
|
|
601
299
|
let groupCounter = 0;
|
|
602
300
|
for (const group of groups) {
|
|
603
301
|
group.auditIndex = nextIndex++;
|
|
604
302
|
group.groupId = groupCounter++;
|
|
605
303
|
}
|
|
606
|
-
// Pre-allocate results array
|
|
607
304
|
const allResults = new Array(nextIndex);
|
|
608
305
|
for (let i = 0; i < regularParams.length; i++) {
|
|
609
306
|
const idx = regularIndices[i];
|
|
@@ -633,7 +330,6 @@ export async function executeFlows(deps, params, toolCallId, auditLoop) {
|
|
|
633
330
|
allResults[group.auditIndex].auditParentType = "build";
|
|
634
331
|
allResults[group.auditIndex].auditLoopGroupId = group.groupId;
|
|
635
332
|
}
|
|
636
|
-
// Streaming progress
|
|
637
333
|
let lastEmittedSignature;
|
|
638
334
|
const emitProgress = (streamingText) => {
|
|
639
335
|
const activeStreamingText = allResults
|
|
@@ -642,18 +338,24 @@ export async function executeFlows(deps, params, toolCallId, auditLoop) {
|
|
|
642
338
|
.filter((text) => Boolean(text))
|
|
643
339
|
.at(-1);
|
|
644
340
|
const text = streamingText ?? activeStreamingText ?? "";
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
341
|
+
if (toolCallId) {
|
|
342
|
+
publishFlowLiveText(toolCallId, text);
|
|
343
|
+
for (let i = 0; i < allResults.length; i++) {
|
|
344
|
+
const r = allResults[i];
|
|
345
|
+
if (r.streamingText) {
|
|
346
|
+
publishFlowLiveTextAtIndex(toolCallId, i, r.streamingText);
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
else {
|
|
351
|
+
setLiveText("collapsed", text);
|
|
352
|
+
for (let i = 0; i < allResults.length; i++) {
|
|
353
|
+
const r = allResults[i];
|
|
354
|
+
if (r.streamingText) {
|
|
355
|
+
setLiveText(`collapsed#${i}`, r.streamingText);
|
|
356
|
+
}
|
|
654
357
|
}
|
|
655
358
|
}
|
|
656
|
-
// Now check onUpdate for host callback
|
|
657
359
|
if (!onUpdate)
|
|
658
360
|
return;
|
|
659
361
|
const signature = text +
|
|
@@ -678,15 +380,12 @@ export async function executeFlows(deps, params, toolCallId, auditLoop) {
|
|
|
678
380
|
}
|
|
679
381
|
catch (err) {
|
|
680
382
|
if (err instanceof Error && err.message.includes("outside active run")) {
|
|
681
|
-
// Agent listener invoked from async callback (child stdout handler)
|
|
682
|
-
// after the active run context ended. Safe to drop this update.
|
|
683
383
|
return;
|
|
684
384
|
}
|
|
685
385
|
throw err;
|
|
686
386
|
}
|
|
687
387
|
};
|
|
688
388
|
emitProgress();
|
|
689
|
-
// Execute all flows
|
|
690
389
|
const executionStart = Date.now();
|
|
691
390
|
const regularPromise = regularParams.length > 0
|
|
692
391
|
? mapFlowConcurrent(regularParams, maxConcurrency, async (item, localIndex) => {
|
|
@@ -697,19 +396,14 @@ export async function executeFlows(deps, params, toolCallId, auditLoop) {
|
|
|
697
396
|
const groupPromises = groups.map((group) => executeGroupedPingPong(deps, group, allResults, toolCallId, emitProgress, selectedFlowModelConfig));
|
|
698
397
|
await Promise.all([regularPromise, ...groupPromises]);
|
|
699
398
|
const results = [...allResults];
|
|
700
|
-
// Record last flow completion for dynamic notifications
|
|
701
399
|
const lastResult = results[results.length - 1];
|
|
702
400
|
if (lastResult) {
|
|
703
401
|
setFlowComplete(lastResult.type, lastResult.acceptance, results.length - 1, results.length);
|
|
704
402
|
}
|
|
705
|
-
// Mark flow completion for the continuation hold — gives the user
|
|
706
|
-
// time to read the result before the next flow auto-spawns.
|
|
707
403
|
markFlowCompleted(deps.sessionManager.getSessionId());
|
|
708
|
-
// Goal continuation callback
|
|
709
404
|
if (deps.goalContinuationCallback) {
|
|
710
405
|
await deps.goalContinuationCallback(results);
|
|
711
406
|
}
|
|
712
|
-
// Build tool result
|
|
713
407
|
const successCount = results.filter((r) => isFlowSuccess(r)).length;
|
|
714
408
|
const flowReports = results.map((r) => {
|
|
715
409
|
const output = getFlowSummaryText(r);
|