salmon-loop 0.2.13 → 0.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/dist/cli/argv/headless-detection.js +27 -0
- package/dist/cli/chat-flow.js +11 -0
- package/dist/cli/chat.js +160 -24
- package/dist/cli/commands/chat.js +14 -7
- package/dist/cli/commands/flow-mode.js +63 -0
- package/dist/cli/commands/registry.js +2 -0
- package/dist/cli/commands/run/benchmark-artifacts.js +41 -0
- package/dist/cli/commands/run/early-errors.js +23 -0
- package/dist/cli/commands/run/handler.js +115 -27
- package/dist/cli/commands/run/headless-error-writer.js +8 -0
- package/dist/cli/commands/run/loop-params.js +2 -0
- package/dist/cli/commands/run/mode.js +2 -5
- package/dist/cli/commands/run/parse-options.js +16 -0
- package/dist/cli/commands/run/persist-session.js +10 -1
- package/dist/cli/commands/run/preflight.js +10 -0
- package/dist/cli/commands/run/reporter-factory.js +4 -0
- package/dist/cli/commands/run/runtime-llm.js +38 -11
- package/dist/cli/commands/run/runtime-options.js +2 -2
- package/dist/cli/commands/serve.js +91 -71
- package/dist/cli/commands/tool-names.js +78 -78
- package/dist/cli/headless/anthropic-stream-normalized-encoder.js +6 -1
- package/dist/cli/headless/json-protocol.js +37 -0
- package/dist/cli/headless/native-stream-normalized-encoder.js +6 -1
- package/dist/cli/headless/protocol-metadata.js +22 -0
- package/dist/cli/headless/stream-json-protocol.js +34 -1
- package/dist/cli/index.js +6 -4
- package/dist/cli/locales/en.js +30 -6
- package/dist/cli/program-bootstrap.js +8 -3
- package/dist/cli/program-commands.js +5 -1
- package/dist/cli/reporters/anthropic-stream.js +7 -1
- package/dist/cli/reporters/json.js +4 -0
- package/dist/cli/reporters/stream-json.js +17 -2
- package/dist/cli/run-cli.js +5 -3
- package/dist/cli/slash/runtime.js +27 -12
- package/dist/cli/ui/components/CommandInput.js +7 -3
- package/dist/cli/ui/components/CommandSuggestionList.js +1 -1
- package/dist/cli/utils/command-option-source.js +13 -0
- package/dist/cli/utils/verify-resolver.js +8 -4
- package/dist/cli/utils/worktree-prepare-resolver.js +7 -3
- package/dist/core/adapters/fs/file-adapter.js +6 -0
- package/dist/core/adapters/fs/filesystem.js +2 -1
- package/dist/core/adapters/git/git-adapter.js +78 -1
- package/dist/core/benchmark/patch-artifact.js +124 -0
- package/dist/core/benchmark/swe-bench.js +25 -0
- package/dist/core/config/load.js +18 -11
- package/dist/core/config/resolve-llm.js +12 -0
- package/dist/core/config/resolvers/server.js +0 -6
- package/dist/core/config/validate.js +73 -21
- package/dist/core/context/gatherers/metadata-gatherer.js +1 -0
- package/dist/core/context/gatherers/ripgrep-gatherer.js +84 -2
- package/dist/core/context/keywords.js +18 -4
- package/dist/core/context/service-deps.js +2 -2
- package/dist/core/context/service.js +8 -0
- package/dist/core/context/steps/context-gather.js +38 -0
- package/dist/core/context/summarization/summarizer.js +55 -12
- package/dist/core/context/targeting/target-resolver.js +4 -4
- package/dist/core/extensions/index.js +23 -5
- package/dist/core/extensions/paths.js +31 -0
- package/dist/core/extensions/schemas.js +8 -5
- package/dist/core/facades/cli-chat.js +6 -2
- package/dist/core/facades/cli-command-chat.js +1 -0
- package/dist/core/facades/cli-command-tool-names.js +2 -0
- package/dist/core/facades/cli-observability.js +1 -1
- package/dist/core/facades/cli-run-handler.js +4 -2
- package/dist/core/facades/cli-run-persist-session.js +1 -0
- package/dist/core/facades/cli-serve.js +2 -4
- package/dist/core/facades/cli-utils-worktree.js +1 -1
- package/dist/core/failure/diagnostics.js +53 -1
- package/dist/core/grizzco/dsl/llm-strategy.js +4 -1
- package/dist/core/grizzco/engine/outcome/loop-result-mapper.js +67 -9
- package/dist/core/grizzco/engine/pipeline/pipeline.js +6 -2
- package/dist/core/grizzco/engine/transaction/attempt-failure.js +90 -15
- package/dist/core/grizzco/engine/transaction/report-mapper.js +17 -3
- package/dist/core/grizzco/engine/transaction/transaction-runner.js +165 -7
- package/dist/core/grizzco/flows/AutopilotFlow.js +18 -0
- package/dist/core/grizzco/flows/flow-dispatch.js +11 -0
- package/dist/core/grizzco/steps/answer.js +13 -14
- package/dist/core/grizzco/steps/autopilot.js +396 -0
- package/dist/core/grizzco/steps/cache-sharing.js +29 -0
- package/dist/core/grizzco/steps/explore.js +37 -21
- package/dist/core/grizzco/steps/generateReview.js +2 -5
- package/dist/core/grizzco/steps/patch/apply-check.js +10 -0
- package/dist/core/grizzco/steps/patch/diff-normalization.js +70 -0
- package/dist/core/grizzco/steps/patch/diff-salvage.js +46 -0
- package/dist/core/grizzco/steps/patch/prompt-input.js +42 -0
- package/dist/core/grizzco/steps/patch.js +105 -146
- package/dist/core/grizzco/steps/plan.js +101 -25
- package/dist/core/grizzco/steps/preflight.js +5 -6
- package/dist/core/grizzco/steps/request-assembly.js +78 -0
- package/dist/core/grizzco/steps/research.js +39 -36
- package/dist/core/grizzco/steps/tool-runtime.js +47 -0
- package/dist/core/grizzco/steps/verify-shared.js +23 -0
- package/dist/core/grizzco/steps/verify.js +13 -21
- package/dist/core/llm/ai-sdk/chat-executor.js +2 -0
- package/dist/core/llm/ai-sdk/high-level-phase-specs.js +63 -0
- package/dist/core/llm/ai-sdk/message-mapper.js +40 -10
- package/dist/core/llm/ai-sdk/provider-factory.js +14 -0
- package/dist/core/llm/ai-sdk/request-params.js +73 -0
- package/dist/core/llm/ai-sdk/result-mapper.js +16 -0
- package/dist/core/llm/ai-sdk.js +112 -27
- package/dist/core/llm/capabilities.js +12 -0
- package/dist/core/llm/contracts/repair.js +36 -30
- package/dist/core/llm/errors.js +83 -2
- package/dist/core/llm/message-composition.js +7 -22
- package/dist/core/llm/phase-router.js +29 -10
- package/dist/core/llm/redact.js +28 -3
- package/dist/core/llm/registry.js +2 -0
- package/dist/core/llm/request-augmentation.js +55 -0
- package/dist/core/llm/request-envelope.js +334 -0
- package/dist/core/llm/shared-request-assembly.js +35 -0
- package/dist/core/llm/stream-utils.js +13 -4
- package/dist/core/llm/utils.js +18 -29
- package/dist/core/memory/relevant-retrieval.js +144 -0
- package/dist/core/observability/logger.js +11 -2
- package/dist/core/patch/diff.js +1 -0
- package/dist/core/prompts/registry.js +39 -2
- package/dist/core/prompts/runtime.js +50 -12
- package/dist/core/prompts/templates/phases/patch_user.hbs +2 -5
- package/dist/core/prompts/templates/phases/research_user.hbs +11 -0
- package/dist/core/prompts/templates/phases/review_user.hbs +3 -0
- package/dist/core/prompts/templates/system/answer_system.hbs +5 -0
- package/dist/core/prompts/templates/system/autopilot_system.hbs +11 -0
- package/dist/core/prompts/templates/system/explore_system.hbs +14 -23
- package/dist/core/prompts/templates/system/main_system.hbs +4 -16
- package/dist/core/prompts/templates/system/patch_system.hbs +39 -8
- package/dist/core/prompts/templates/system/plan_system.hbs +86 -1
- package/dist/core/prompts/templates/system/research_system.hbs +2 -0
- package/dist/core/protocols/a2a/agent-card.js +3 -2
- package/dist/core/protocols/a2a/sdk/executor.js +2 -1
- package/dist/core/protocols/a2a/sdk/server.js +0 -1
- package/dist/core/protocols/acp/formal-agent.js +74 -51
- package/dist/core/protocols/acp/handlers.js +5 -1
- package/dist/core/protocols/acp/permission-provider.js +1 -1
- package/dist/core/protocols/shared/flow-mode-mapping.js +23 -0
- package/dist/core/public-capabilities/flow-mode-metadata.js +39 -0
- package/dist/core/public-capabilities/projections.js +29 -0
- package/dist/core/public-capabilities/registry.js +26 -0
- package/dist/core/public-capabilities/types.js +2 -0
- package/dist/core/runtime/agent-server-runtime.js +47 -43
- package/dist/core/runtime/execution-profile.js +67 -0
- package/dist/core/session/artifact-state.js +160 -0
- package/dist/core/session/compaction/index.js +183 -0
- package/dist/core/session/compaction/microcompact.js +78 -0
- package/dist/core/session/compaction/tracking.js +48 -0
- package/dist/core/session/compaction/types.js +11 -0
- package/dist/core/session/compression.js +8 -0
- package/dist/core/session/manager.js +244 -8
- package/dist/core/session/pruning-strategy.js +55 -9
- package/dist/core/session/replacement-preview-provider.js +24 -0
- package/dist/core/session/replacement-state.js +131 -0
- package/dist/core/session/resume-repair/pipeline.js +79 -0
- package/dist/core/session/resume-repair/stages/load-raw-archive-state.js +40 -0
- package/dist/core/session/resume-repair/stages/reattach-runtime-state.js +8 -0
- package/dist/core/session/resume-repair/stages/recover-orphaned-branches.js +10 -0
- package/dist/core/session/resume-repair/stages/relink-boundary-and-tail.js +36 -0
- package/dist/core/session/resume-repair/stages/replay-startup-hooks.js +23 -0
- package/dist/core/session/resume-repair/stages/rescue-stale-metadata.js +17 -0
- package/dist/core/session/resume-repair/types.js +2 -0
- package/dist/core/session/summary-sync.js +164 -13
- package/dist/core/session/token-tracker.js +6 -0
- package/dist/core/skills/audit.js +34 -0
- package/dist/core/skills/bridge.js +84 -7
- package/dist/core/skills/discovery.js +94 -0
- package/dist/core/skills/feature-flags.js +52 -0
- package/dist/core/skills/index.js +1 -1
- package/dist/core/skills/loader.js +195 -20
- package/dist/core/skills/parser.js +296 -24
- package/dist/core/skills/permissions.js +117 -0
- package/dist/core/skills/runtime/MicroTaskRunner.js +10 -4
- package/dist/core/skills/runtime/SkillRunner.js +240 -61
- package/dist/core/strata/layers/shadow-driver/shadow-driver.js +37 -7
- package/dist/core/strata/layers/worktree.js +67 -10
- package/dist/core/strata/runtime/synchronizer.js +29 -2
- package/dist/core/streaming/stream-assembler.js +75 -31
- package/dist/core/sub-agent/context-snapshot.js +156 -0
- package/dist/core/sub-agent/core/loop.js +1 -1
- package/dist/core/sub-agent/core/manager.js +119 -20
- package/dist/core/sub-agent/dispatch-policy.js +29 -0
- package/dist/core/sub-agent/prefix-consistency.js +48 -0
- package/dist/core/sub-agent/registry-defaults.js +4 -0
- package/dist/core/sub-agent/tools/task-spawn.js +79 -2
- package/dist/core/sub-agent/types.js +134 -5
- package/dist/core/tools/audit.js +13 -4
- package/dist/core/tools/builtin/ast-grep.js +1 -1
- package/dist/core/tools/builtin/ast.js +1 -1
- package/dist/core/tools/builtin/benchmark.js +360 -0
- package/dist/core/tools/builtin/code-search/backends/rg.js +2 -1
- package/dist/core/tools/builtin/code-search/executor.js +6 -1
- package/dist/core/tools/builtin/code-search/spec.js +26 -2
- package/dist/core/tools/builtin/fs.js +256 -23
- package/dist/core/tools/builtin/git.js +2 -2
- package/dist/core/tools/builtin/index.js +51 -2
- package/dist/core/tools/builtin/interaction.js +8 -1
- package/dist/core/tools/builtin/plan.js +37 -15
- package/dist/core/tools/builtin/shell.js +1 -1
- package/dist/core/tools/loader.js +39 -16
- package/dist/core/tools/mapper.js +17 -3
- package/dist/core/tools/parallel/scheduler.js +35 -4
- package/dist/core/tools/permissions/permission-rules.js +5 -10
- package/dist/core/tools/policy.js +6 -1
- package/dist/core/tools/recoverable-tool-errors.js +10 -0
- package/dist/core/tools/router.js +24 -6
- package/dist/core/tools/session.js +458 -48
- package/dist/core/tools/tool-visibility.js +62 -0
- package/dist/core/tools/types.js +9 -1
- package/dist/core/types/execution.js +4 -0
- package/dist/core/types/flow-mode.js +8 -0
- package/dist/core/utils/path.js +52 -0
- package/dist/core/verification/runner.js +4 -1
- package/dist/languages/typescript/index.js +4 -1
- package/dist/locales/en.js +35 -2
- package/dist/utils/eol.js +1 -1
- package/package.json +13 -6
- package/scripts/fix-es-abstract-compat.js +77 -0
- package/dist/core/runtime/fastify-server-bundle.js +0 -26
- package/dist/core/runtime/sidecar-fastify-plugin.js +0 -35
- package/dist/core/runtime/sidecar-paths.js +0 -47
- package/dist/core/runtime/sidecar-route-catalog.js +0 -103
|
@@ -3,8 +3,35 @@ import { getBudgetRunSummary } from '../../../context/budget/integration.js';
|
|
|
3
3
|
import { getAuthorizationDecisionsFromAuditTrail } from '../../../observability/authorization-decisions.js';
|
|
4
4
|
import { buildFailureEnvelope } from '../../../observability/error-envelope.js';
|
|
5
5
|
import { getTokenUsageFromAuditTrail } from '../../../observability/token-usage.js';
|
|
6
|
+
import { resolveExecutionProfile } from '../../../runtime/execution-profile.js';
|
|
6
7
|
import { ErrorType, Phase } from '../../../types/runtime.js';
|
|
8
|
+
const ROOT_CAUSE_CODES = [
|
|
9
|
+
'LLM_RATE_LIMITED',
|
|
10
|
+
'LLM_UPSTREAM_5XX',
|
|
11
|
+
'LLM_NETWORK_UNREACHABLE',
|
|
12
|
+
'LLM_REQUEST_TIMEOUT',
|
|
13
|
+
'PLAN_OUTPUT_NOT_JSON',
|
|
14
|
+
'PLAN_SCHEMA_INVALID',
|
|
15
|
+
'STDOUT_CONTRACT_VIOLATION',
|
|
16
|
+
'RESOURCE_LIMIT_CONFIRMED',
|
|
17
|
+
];
|
|
18
|
+
function toRootCauseCode(code) {
|
|
19
|
+
if (typeof code !== 'string')
|
|
20
|
+
return undefined;
|
|
21
|
+
return ROOT_CAUSE_CODES.includes(code)
|
|
22
|
+
? code
|
|
23
|
+
: undefined;
|
|
24
|
+
}
|
|
7
25
|
export function buildLoopResultFromTransaction({ executionReport, flowMode, options, telemetry, auditPath, }) {
|
|
26
|
+
const profile = resolveExecutionProfile(flowMode);
|
|
27
|
+
const rootCause = toRootCauseCode(executionReport.lastErrorCode);
|
|
28
|
+
const terminalReason = executionReport.retryExhausted
|
|
29
|
+
? 'RETRY_BUDGET_EXHAUSTED'
|
|
30
|
+
: executionReport.terminalReasonCode === 'AWAITING_INPUT'
|
|
31
|
+
? undefined
|
|
32
|
+
: executionReport.success
|
|
33
|
+
? undefined
|
|
34
|
+
: 'NON_RETRYABLE_FAILURE';
|
|
8
35
|
const ctx = executionReport.lastContext ??
|
|
9
36
|
executionReport.flowReport.data;
|
|
10
37
|
const contextHash = (() => {
|
|
@@ -19,11 +46,35 @@ export function buildLoopResultFromTransaction({ executionReport, flowMode, opti
|
|
|
19
46
|
const verifyArtifact = ctx && typeof ctx === 'object' && 'verifyArtifact' in ctx
|
|
20
47
|
? ctx.verifyArtifact
|
|
21
48
|
: executionReport.lastVerifyArtifact;
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
:
|
|
26
|
-
|
|
49
|
+
const artifactHints = (() => {
|
|
50
|
+
const hints = {
|
|
51
|
+
verifyArtifact,
|
|
52
|
+
subAgentPatchArtifacts: executionReport.lastSubAgentPatchArtifacts?.length
|
|
53
|
+
? executionReport.lastSubAgentPatchArtifacts
|
|
54
|
+
: undefined,
|
|
55
|
+
subAgentAuditArtifacts: executionReport.lastSubAgentAuditArtifacts?.length
|
|
56
|
+
? executionReport.lastSubAgentAuditArtifacts
|
|
57
|
+
: undefined,
|
|
58
|
+
recentReadArtifacts: executionReport.lastRecentReadArtifacts?.length
|
|
59
|
+
? executionReport.lastRecentReadArtifacts
|
|
60
|
+
: undefined,
|
|
61
|
+
toolResultPreviewArtifacts: executionReport.lastToolResultPreviewArtifacts?.length
|
|
62
|
+
? executionReport.lastToolResultPreviewArtifacts
|
|
63
|
+
: undefined,
|
|
64
|
+
};
|
|
65
|
+
if (!hints.verifyArtifact &&
|
|
66
|
+
!hints.subAgentPatchArtifacts &&
|
|
67
|
+
!hints.subAgentAuditArtifacts &&
|
|
68
|
+
!hints.recentReadArtifacts &&
|
|
69
|
+
!hints.toolResultPreviewArtifacts) {
|
|
70
|
+
return undefined;
|
|
71
|
+
}
|
|
72
|
+
return hints;
|
|
73
|
+
})();
|
|
74
|
+
const assistantMessage = ((flowMode === 'answer' || profile.driver === 'agent') &&
|
|
75
|
+
ctx?.report?.summary?.trim?.()
|
|
76
|
+
? String(ctx.report.summary).trim()
|
|
77
|
+
: undefined) ?? undefined;
|
|
27
78
|
const finalPatch = ctx && typeof ctx === 'object' && 'diff' in ctx ? ctx.diff : undefined;
|
|
28
79
|
const changedFiles = ctx && typeof ctx === 'object' && 'changedFiles' in ctx ? ctx.changedFiles : undefined;
|
|
29
80
|
const authorizationDecisions = (() => {
|
|
@@ -36,14 +87,12 @@ export function buildLoopResultFromTransaction({ executionReport, flowMode, opti
|
|
|
36
87
|
const attempts = executionReport.attempts;
|
|
37
88
|
const usage = getTokenUsageFromAuditTrail() ?? undefined;
|
|
38
89
|
const budgetSummary = getBudgetRunSummary() ?? undefined;
|
|
39
|
-
if (options.dryRun ||
|
|
40
|
-
flowMode === 'review' ||
|
|
41
|
-
flowMode === 'research' ||
|
|
42
|
-
flowMode === 'answer') {
|
|
90
|
+
if (options.dryRun || profile.readOnly) {
|
|
43
91
|
return {
|
|
44
92
|
success: true,
|
|
45
93
|
reason: text.loop.operationCompleted,
|
|
46
94
|
reasonCode: options.dryRun ? 'DRY_RUN' : 'SUCCESS',
|
|
95
|
+
terminalReason,
|
|
47
96
|
attempts,
|
|
48
97
|
contextHash,
|
|
49
98
|
logs: telemetry.getLogs(),
|
|
@@ -55,6 +104,7 @@ export function buildLoopResultFromTransaction({ executionReport, flowMode, opti
|
|
|
55
104
|
assistantMessage,
|
|
56
105
|
auditPath,
|
|
57
106
|
verifyArtifact,
|
|
107
|
+
artifactHints,
|
|
58
108
|
authorizationSummary: executionReport.authorizationSummary || undefined,
|
|
59
109
|
strategyName: executionReport.flowReport.strategyName ?? flowMode,
|
|
60
110
|
fsMode: executionReport.flowReport.fsMode ?? flowMode,
|
|
@@ -65,6 +115,7 @@ export function buildLoopResultFromTransaction({ executionReport, flowMode, opti
|
|
|
65
115
|
success: true,
|
|
66
116
|
reason: text.loop.operationCompleted,
|
|
67
117
|
reasonCode: 'SUCCESS',
|
|
118
|
+
terminalReason,
|
|
68
119
|
attempts,
|
|
69
120
|
contextHash,
|
|
70
121
|
logs: telemetry.getLogs(),
|
|
@@ -76,6 +127,7 @@ export function buildLoopResultFromTransaction({ executionReport, flowMode, opti
|
|
|
76
127
|
assistantMessage,
|
|
77
128
|
auditPath,
|
|
78
129
|
verifyArtifact,
|
|
130
|
+
artifactHints,
|
|
79
131
|
authorizationSummary: executionReport.authorizationSummary || undefined,
|
|
80
132
|
strategyName: executionReport.flowReport.strategyName ?? flowMode,
|
|
81
133
|
fsMode: executionReport.flowReport.fsMode ?? flowMode,
|
|
@@ -107,6 +159,8 @@ export function buildLoopResultFromTransaction({ executionReport, flowMode, opti
|
|
|
107
159
|
success: false,
|
|
108
160
|
reason: safeHint,
|
|
109
161
|
reasonCode,
|
|
162
|
+
terminalReason,
|
|
163
|
+
rootCause,
|
|
110
164
|
diagnosticCode: executionReport.terminalDiagnosticCode ?? reasonCode,
|
|
111
165
|
safeHint,
|
|
112
166
|
remediationSteps,
|
|
@@ -122,6 +176,7 @@ export function buildLoopResultFromTransaction({ executionReport, flowMode, opti
|
|
|
122
176
|
errorCode: executionReport.lastErrorCode,
|
|
123
177
|
auditPath,
|
|
124
178
|
verifyArtifact,
|
|
179
|
+
artifactHints,
|
|
125
180
|
authorizationSummary: executionReport.authorizationSummary || undefined,
|
|
126
181
|
strategyName: executionReport.flowReport.strategyName ?? flowMode,
|
|
127
182
|
fsMode: executionReport.flowReport.fsMode ?? flowMode,
|
|
@@ -138,6 +193,7 @@ export function buildLoopFailureResult({ message, flowMode, telemetry, auditPath
|
|
|
138
193
|
const decisions = getAuthorizationDecisionsFromAuditTrail();
|
|
139
194
|
return decisions.length > 0 ? decisions : undefined;
|
|
140
195
|
})();
|
|
196
|
+
const rootCause = toRootCauseCode(errorCode);
|
|
141
197
|
const errorEnvelope = buildFailureEnvelope({
|
|
142
198
|
phase: failurePhase,
|
|
143
199
|
fallbackMessage: message,
|
|
@@ -146,6 +202,8 @@ export function buildLoopFailureResult({ message, flowMode, telemetry, auditPath
|
|
|
146
202
|
success: false,
|
|
147
203
|
reason: message,
|
|
148
204
|
reasonCode,
|
|
205
|
+
terminalReason: 'NON_RETRYABLE_FAILURE',
|
|
206
|
+
rootCause,
|
|
149
207
|
diagnosticCode: reasonCode,
|
|
150
208
|
safeHint: message,
|
|
151
209
|
remediationSteps: [],
|
|
@@ -300,19 +300,23 @@ export class Pipeline {
|
|
|
300
300
|
async execute() {
|
|
301
301
|
try {
|
|
302
302
|
const data = await this.promise;
|
|
303
|
+
const lastExecutedStep = [...this.traces].reverse().find((trace) => !trace.name.endsWith(':recovery'))?.name ??
|
|
304
|
+
this.lastStepName;
|
|
303
305
|
return {
|
|
304
306
|
success: true,
|
|
305
307
|
duration: Date.now() - this.startTime,
|
|
306
|
-
lastStep:
|
|
308
|
+
lastStep: lastExecutedStep,
|
|
307
309
|
data,
|
|
308
310
|
traces: this.traces,
|
|
309
311
|
};
|
|
310
312
|
}
|
|
311
313
|
catch (error) {
|
|
314
|
+
const lastExecutedStep = [...this.traces].reverse().find((trace) => !trace.name.endsWith(':recovery'))?.name ??
|
|
315
|
+
this.lastStepName;
|
|
312
316
|
return {
|
|
313
317
|
success: false,
|
|
314
318
|
error: error instanceof Error ? error : new Error(String(error)),
|
|
315
|
-
lastStep:
|
|
319
|
+
lastStep: lastExecutedStep,
|
|
316
320
|
duration: Date.now() - this.startTime,
|
|
317
321
|
data: this.ctxRef.current,
|
|
318
322
|
traces: this.traces,
|
|
@@ -2,6 +2,8 @@ import { text } from '../../../../locales/index.js';
|
|
|
2
2
|
import { buildFailureGuidance } from '../../../failure/diagnostics.js';
|
|
3
3
|
import { sanitizeError } from '../../../llm/errors.js';
|
|
4
4
|
import { mapErrorForDisplay } from '../../../observability/error-mapping.js';
|
|
5
|
+
import { resolveExecutionProfile } from '../../../runtime/execution-profile.js';
|
|
6
|
+
import { isRecoverableToolInputErrorCode } from '../../../tools/recoverable-tool-errors.js';
|
|
5
7
|
import { EXECUTION_PHASES } from '../../../types/runtime.js';
|
|
6
8
|
import { classifyError, isRetryable } from '../../../verification/runner.js';
|
|
7
9
|
const RETRYABLE_PHASES = new Set([
|
|
@@ -19,6 +21,7 @@ const NON_RETRYABLE_PERMISSION_CODES = new Set([
|
|
|
19
21
|
'PERMISSION_REQUIRED_CONTEXT_CACHE_OUTSIDE_ROOT',
|
|
20
22
|
'PERMISSION_DENIED_CONTEXT_CACHE_OUTSIDE_ROOT',
|
|
21
23
|
]);
|
|
24
|
+
const NON_RETRYABLE_LLM_CODES = new Set(['LLM_AUTHENTICATION_FAILED']);
|
|
22
25
|
function inferFailurePhase(flowReport) {
|
|
23
26
|
const failedTrace = [...flowReport.traces].reverse().find((trace) => Boolean(trace.error));
|
|
24
27
|
if (failedTrace && EXECUTION_PHASES.includes(failedTrace.name)) {
|
|
@@ -67,6 +70,7 @@ function extractInterrupt(error) {
|
|
|
67
70
|
}
|
|
68
71
|
export function resolveAttemptFailure(params) {
|
|
69
72
|
const { flowReport, context, flowMode } = params;
|
|
73
|
+
const profile = resolveExecutionProfile(flowMode);
|
|
70
74
|
const interrupt = extractInterrupt(flowReport.error);
|
|
71
75
|
const interruptCode = extractErrorCode(flowReport.error);
|
|
72
76
|
if (interruptCode === 'INTERRUPT_REQUIRED' && interrupt?.type === 'awaiting_input') {
|
|
@@ -87,23 +91,19 @@ export function resolveAttemptFailure(params) {
|
|
|
87
91
|
inputRequired,
|
|
88
92
|
};
|
|
89
93
|
}
|
|
90
|
-
const
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
const applyBackFailed =
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
context?.applyBackResult?.success === false &&
|
|
97
|
-
!context.applyBackResult.skipped;
|
|
94
|
+
const autopilotCompletion = flowMode === 'autopilot' && context && 'completion' in context ? context.completion : undefined;
|
|
95
|
+
const verifyOk = profile.verifyPolicy === 'never' ? true : context?.verifyResult?.ok !== false;
|
|
96
|
+
const applyBackResult = context && 'applyBackResult' in context ? context.applyBackResult : undefined;
|
|
97
|
+
const applyBackFailed = profile.failurePolicy === 'rollback' &&
|
|
98
|
+
applyBackResult?.success === false &&
|
|
99
|
+
!applyBackResult.skipped;
|
|
98
100
|
const environmentMode = context?.options?.environmentMode;
|
|
99
101
|
if (applyBackFailed) {
|
|
100
|
-
const fallbackReason =
|
|
101
|
-
context.applyBackResult?.error ||
|
|
102
|
-
text.loop.applyBackFailed;
|
|
102
|
+
const fallbackReason = applyBackResult?.safeMessage || applyBackResult?.error || text.loop.applyBackFailed;
|
|
103
103
|
const guidance = buildFailureGuidance({
|
|
104
104
|
reasonCode: 'APPLY_BACK_FAILED',
|
|
105
105
|
failurePhase: 'APPLY_BACK',
|
|
106
|
-
errorCode:
|
|
106
|
+
errorCode: applyBackResult?.errorCode || 'APPLY_BACK_FAILED',
|
|
107
107
|
environmentMode,
|
|
108
108
|
fallbackReason,
|
|
109
109
|
});
|
|
@@ -112,16 +112,51 @@ export function resolveAttemptFailure(params) {
|
|
|
112
112
|
reasonCode: 'APPLY_BACK_FAILED',
|
|
113
113
|
failurePhase: 'APPLY_BACK',
|
|
114
114
|
retryable: false,
|
|
115
|
-
errorCode:
|
|
115
|
+
errorCode: applyBackResult?.errorCode || 'APPLY_BACK_FAILED',
|
|
116
116
|
diagnosticCode: guidance.diagnosticCode,
|
|
117
117
|
safeHint: guidance.safeHint,
|
|
118
118
|
remediationSteps: guidance.remediationSteps,
|
|
119
119
|
};
|
|
120
120
|
}
|
|
121
|
-
if (flowReport.success && verifyOk) {
|
|
121
|
+
if (flowReport.success && verifyOk && !autopilotCompletion) {
|
|
122
122
|
return undefined;
|
|
123
123
|
}
|
|
124
124
|
const errorCode = extractErrorCode(flowReport.error) ?? extractErrorCodeFromTraces(flowReport);
|
|
125
|
+
if (flowMode === 'autopilot' && autopilotCompletion) {
|
|
126
|
+
if (autopilotCompletion.status === 'changed' ||
|
|
127
|
+
autopilotCompletion.status === 'read_only_answer') {
|
|
128
|
+
if (flowReport.success && verifyOk)
|
|
129
|
+
return undefined;
|
|
130
|
+
}
|
|
131
|
+
const reasonCode = autopilotCompletion.status === 'verification_missing'
|
|
132
|
+
? 'VERIFY_COMMAND_MISSING'
|
|
133
|
+
: autopilotCompletion.status === 'tool_failure' &&
|
|
134
|
+
isRecoverableToolInputErrorCode(autopilotCompletion.errorCode)
|
|
135
|
+
? 'TOOL_CORRECTION_REQUIRED'
|
|
136
|
+
: 'LOOP_FAILED';
|
|
137
|
+
const failurePhase = autopilotCompletion.status === 'verification_missing' ? 'VERIFY' : 'AUTOPILOT';
|
|
138
|
+
const fallbackReason = autopilotCompletion.reason ||
|
|
139
|
+
(autopilotCompletion.status === 'no_effect'
|
|
140
|
+
? 'Autopilot completed without changing files or producing an answer.'
|
|
141
|
+
: text.loop.loopExecutionFailed);
|
|
142
|
+
const guidance = buildFailureGuidance({
|
|
143
|
+
reasonCode,
|
|
144
|
+
failurePhase,
|
|
145
|
+
errorCode: autopilotCompletion.errorCode,
|
|
146
|
+
environmentMode,
|
|
147
|
+
fallbackReason,
|
|
148
|
+
});
|
|
149
|
+
return {
|
|
150
|
+
reason: guidance.safeHint,
|
|
151
|
+
reasonCode,
|
|
152
|
+
failurePhase,
|
|
153
|
+
retryable: reasonCode === 'TOOL_CORRECTION_REQUIRED' || autopilotCompletion.status === 'no_effect',
|
|
154
|
+
errorCode: autopilotCompletion.errorCode,
|
|
155
|
+
diagnosticCode: guidance.diagnosticCode,
|
|
156
|
+
safeHint: guidance.safeHint,
|
|
157
|
+
remediationSteps: guidance.remediationSteps,
|
|
158
|
+
};
|
|
159
|
+
}
|
|
125
160
|
if (errorCode === 'PREFLIGHT_NOT_GIT') {
|
|
126
161
|
const fallbackReason = sanitizeReason(flowReport.error);
|
|
127
162
|
const guidance = buildFailureGuidance({
|
|
@@ -182,7 +217,28 @@ export function resolveAttemptFailure(params) {
|
|
|
182
217
|
remediationSteps: guidance.remediationSteps,
|
|
183
218
|
};
|
|
184
219
|
}
|
|
185
|
-
if (
|
|
220
|
+
if (errorCode && NON_RETRYABLE_LLM_CODES.has(errorCode)) {
|
|
221
|
+
const failurePhase = inferFailurePhase(flowReport);
|
|
222
|
+
const fallbackReason = sanitizeReason(flowReport.error);
|
|
223
|
+
const guidance = buildFailureGuidance({
|
|
224
|
+
reasonCode: 'LOOP_FAILED',
|
|
225
|
+
failurePhase,
|
|
226
|
+
errorCode,
|
|
227
|
+
environmentMode,
|
|
228
|
+
fallbackReason,
|
|
229
|
+
});
|
|
230
|
+
return {
|
|
231
|
+
reason: guidance.safeHint,
|
|
232
|
+
reasonCode: 'LOOP_FAILED',
|
|
233
|
+
failurePhase,
|
|
234
|
+
retryable: false,
|
|
235
|
+
errorCode,
|
|
236
|
+
diagnosticCode: guidance.diagnosticCode,
|
|
237
|
+
safeHint: guidance.safeHint,
|
|
238
|
+
remediationSteps: guidance.remediationSteps,
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
if (profile.verifyPolicy !== 'never' && context?.verifyResult?.ok === false) {
|
|
186
242
|
const verifyOutput = context.verifyResult.output || text.loop.loopExecutionFailed;
|
|
187
243
|
const errorType = classifyError(verifyOutput);
|
|
188
244
|
const fallbackReason = sanitizeReason(context.lastError || verifyOutput);
|
|
@@ -207,6 +263,25 @@ export function resolveAttemptFailure(params) {
|
|
|
207
263
|
}
|
|
208
264
|
const failurePhase = inferFailurePhase(flowReport);
|
|
209
265
|
const fallbackReason = sanitizeReason(context?.lastError || flowReport.error);
|
|
266
|
+
if (isRecoverableToolInputErrorCode(errorCode)) {
|
|
267
|
+
const guidance = buildFailureGuidance({
|
|
268
|
+
reasonCode: 'TOOL_CORRECTION_REQUIRED',
|
|
269
|
+
failurePhase,
|
|
270
|
+
errorCode,
|
|
271
|
+
environmentMode,
|
|
272
|
+
fallbackReason,
|
|
273
|
+
});
|
|
274
|
+
return {
|
|
275
|
+
reason: guidance.safeHint,
|
|
276
|
+
reasonCode: 'TOOL_CORRECTION_REQUIRED',
|
|
277
|
+
failurePhase,
|
|
278
|
+
retryable: RETRYABLE_PHASES.has(failurePhase),
|
|
279
|
+
errorCode,
|
|
280
|
+
diagnosticCode: guidance.diagnosticCode,
|
|
281
|
+
safeHint: guidance.safeHint,
|
|
282
|
+
remediationSteps: guidance.remediationSteps,
|
|
283
|
+
};
|
|
284
|
+
}
|
|
210
285
|
const guidance = buildFailureGuidance({
|
|
211
286
|
reasonCode: failurePhase === 'ROLLBACK' ? 'ROLLBACK_FAILED' : 'LOOP_FAILED',
|
|
212
287
|
failurePhase,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export function mapSuccessReport(params) {
|
|
2
|
-
const { attempt, flowReport, history, authorizationSummary, lastContext, lastVerifyArtifact, lastErrorCode, } = params;
|
|
2
|
+
const { attempt, flowReport, history, authorizationSummary, lastContext, lastVerifyArtifact, lastSubAgentPatchArtifacts, lastSubAgentAuditArtifacts, lastRecentReadArtifacts, lastToolResultPreviewArtifacts, lastErrorCode, } = params;
|
|
3
3
|
return {
|
|
4
4
|
success: true,
|
|
5
5
|
attempts: attempt,
|
|
@@ -10,10 +10,14 @@ export function mapSuccessReport(params) {
|
|
|
10
10
|
retryExhausted: false,
|
|
11
11
|
lastContext,
|
|
12
12
|
lastVerifyArtifact,
|
|
13
|
+
lastSubAgentPatchArtifacts,
|
|
14
|
+
lastSubAgentAuditArtifacts,
|
|
15
|
+
lastRecentReadArtifacts,
|
|
16
|
+
lastToolResultPreviewArtifacts,
|
|
13
17
|
};
|
|
14
18
|
}
|
|
15
19
|
export function mapTerminalFailureReport(params) {
|
|
16
|
-
const { attempt, flowReport, history, authorizationSummary, lastContext, lastVerifyArtifact, failure, lastErrorCode, } = params;
|
|
20
|
+
const { attempt, flowReport, history, authorizationSummary, lastContext, lastVerifyArtifact, lastSubAgentPatchArtifacts, lastSubAgentAuditArtifacts, lastRecentReadArtifacts, lastToolResultPreviewArtifacts, failure, lastErrorCode, } = params;
|
|
17
21
|
return {
|
|
18
22
|
success: false,
|
|
19
23
|
attempts: attempt,
|
|
@@ -24,6 +28,10 @@ export function mapTerminalFailureReport(params) {
|
|
|
24
28
|
retryExhausted: false,
|
|
25
29
|
lastContext,
|
|
26
30
|
lastVerifyArtifact,
|
|
31
|
+
lastSubAgentPatchArtifacts,
|
|
32
|
+
lastSubAgentAuditArtifacts,
|
|
33
|
+
lastRecentReadArtifacts,
|
|
34
|
+
lastToolResultPreviewArtifacts,
|
|
27
35
|
terminalReason: failure.reason,
|
|
28
36
|
terminalReasonCode: failure.reasonCode,
|
|
29
37
|
terminalFailurePhase: failure.failurePhase,
|
|
@@ -34,7 +42,7 @@ export function mapTerminalFailureReport(params) {
|
|
|
34
42
|
};
|
|
35
43
|
}
|
|
36
44
|
export function mapRetryExhaustedReport(params) {
|
|
37
|
-
const { attempts, flowReport, history, authorizationSummary, lastErrorCode, lastContext, lastVerifyArtifact, } = params;
|
|
45
|
+
const { attempts, flowReport, history, authorizationSummary, failure, lastErrorCode, lastContext, lastVerifyArtifact, lastSubAgentPatchArtifacts, lastSubAgentAuditArtifacts, lastRecentReadArtifacts, lastToolResultPreviewArtifacts, } = params;
|
|
38
46
|
return {
|
|
39
47
|
success: false,
|
|
40
48
|
attempts,
|
|
@@ -45,6 +53,12 @@ export function mapRetryExhaustedReport(params) {
|
|
|
45
53
|
retryExhausted: true,
|
|
46
54
|
lastContext,
|
|
47
55
|
lastVerifyArtifact,
|
|
56
|
+
lastSubAgentPatchArtifacts,
|
|
57
|
+
lastSubAgentAuditArtifacts,
|
|
58
|
+
lastRecentReadArtifacts,
|
|
59
|
+
lastToolResultPreviewArtifacts,
|
|
60
|
+
terminalFailurePhase: failure?.failurePhase,
|
|
61
|
+
terminalDiagnosticCode: failure?.diagnosticCode,
|
|
48
62
|
};
|
|
49
63
|
}
|
|
50
64
|
//# sourceMappingURL=report-mapper.js.map
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { recordAuditEvent } from '../../../observability/audit-trail.js';
|
|
2
2
|
import { mapErrorForAudit } from '../../../observability/error-mapping.js';
|
|
3
3
|
import { ReflectionEngine } from '../../../reflection/engine.js';
|
|
4
|
-
import {
|
|
4
|
+
import { resolveExecutionProfile } from '../../../runtime/execution-profile.js';
|
|
5
|
+
import { executeFlowAttempt } from '../../flows/flow-dispatch.js';
|
|
5
6
|
import { resolveAttemptFailure } from './attempt-failure.js';
|
|
6
7
|
import { buildAuthorizationSummary } from './authorization-summary.js';
|
|
7
8
|
import { mapRetryExhaustedReport, mapSuccessReport, mapTerminalFailureReport, } from './report-mapper.js';
|
|
@@ -12,6 +13,108 @@ export class FlowTransactionCancelledError extends Error {
|
|
|
12
13
|
this.name = 'FlowTransactionCancelledError';
|
|
13
14
|
}
|
|
14
15
|
}
|
|
16
|
+
function isArtifactHandle(value) {
|
|
17
|
+
return (Boolean(value) &&
|
|
18
|
+
typeof value === 'object' &&
|
|
19
|
+
typeof value.handle === 'string');
|
|
20
|
+
}
|
|
21
|
+
function mergeArtifactHandles(existing, incoming, limit = 4) {
|
|
22
|
+
const merged = [...existing];
|
|
23
|
+
const seen = new Set(existing.map((artifact) => artifact.handle));
|
|
24
|
+
for (const artifact of incoming) {
|
|
25
|
+
if (seen.has(artifact.handle))
|
|
26
|
+
continue;
|
|
27
|
+
merged.push(artifact);
|
|
28
|
+
seen.add(artifact.handle);
|
|
29
|
+
}
|
|
30
|
+
if (merged.length <= limit)
|
|
31
|
+
return merged;
|
|
32
|
+
return merged.slice(merged.length - limit);
|
|
33
|
+
}
|
|
34
|
+
function extractSubAgentArtifacts(entries) {
|
|
35
|
+
if (!Array.isArray(entries) || entries.length === 0) {
|
|
36
|
+
return { patchArtifacts: [], auditArtifacts: [] };
|
|
37
|
+
}
|
|
38
|
+
const patchArtifacts = [];
|
|
39
|
+
const auditArtifacts = [];
|
|
40
|
+
for (const entry of entries) {
|
|
41
|
+
if (entry?.toolName !== 'agent_dispatch' || entry.toolResultStatus !== 'ok')
|
|
42
|
+
continue;
|
|
43
|
+
if (isArtifactHandle(entry.toolResultPatchArtifact)) {
|
|
44
|
+
patchArtifacts.push(entry.toolResultPatchArtifact);
|
|
45
|
+
}
|
|
46
|
+
if (isArtifactHandle(entry.toolResultAuditArtifact)) {
|
|
47
|
+
auditArtifacts.push(entry.toolResultAuditArtifact);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return { patchArtifacts, auditArtifacts };
|
|
51
|
+
}
|
|
52
|
+
function extractRecentReadArtifacts(entries) {
|
|
53
|
+
if (!Array.isArray(entries) || entries.length === 0) {
|
|
54
|
+
return [];
|
|
55
|
+
}
|
|
56
|
+
const recentReads = [];
|
|
57
|
+
for (const entry of entries) {
|
|
58
|
+
if (entry.toolIntent !== 'READ' || entry.toolResultStatus !== 'ok')
|
|
59
|
+
continue;
|
|
60
|
+
if (typeof entry.toolResultReadArtifactPath !== 'string')
|
|
61
|
+
continue;
|
|
62
|
+
if (!isArtifactHandle(entry.toolResultReadArtifact))
|
|
63
|
+
continue;
|
|
64
|
+
recentReads.push({
|
|
65
|
+
path: entry.toolResultReadArtifactPath,
|
|
66
|
+
artifact: entry.toolResultReadArtifact,
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
return recentReads;
|
|
70
|
+
}
|
|
71
|
+
function mergeReadArtifacts(existing, incoming, limit = 6) {
|
|
72
|
+
const merged = [];
|
|
73
|
+
const seen = new Set();
|
|
74
|
+
for (const item of [...existing, ...incoming]) {
|
|
75
|
+
const key = `${item.path}::${item.artifact.handle}`;
|
|
76
|
+
if (seen.has(key))
|
|
77
|
+
continue;
|
|
78
|
+
seen.add(key);
|
|
79
|
+
merged.push(item);
|
|
80
|
+
}
|
|
81
|
+
if (merged.length <= limit)
|
|
82
|
+
return merged;
|
|
83
|
+
return merged.slice(merged.length - limit);
|
|
84
|
+
}
|
|
85
|
+
function extractToolResultPreviewArtifacts(entries) {
|
|
86
|
+
if (!Array.isArray(entries) || entries.length === 0) {
|
|
87
|
+
return [];
|
|
88
|
+
}
|
|
89
|
+
const previews = [];
|
|
90
|
+
for (const entry of entries) {
|
|
91
|
+
if (entry.toolResultStatus !== 'ok')
|
|
92
|
+
continue;
|
|
93
|
+
if (typeof entry.toolResultPreviewLabel !== 'string')
|
|
94
|
+
continue;
|
|
95
|
+
if (!isArtifactHandle(entry.toolResultPreviewArtifact))
|
|
96
|
+
continue;
|
|
97
|
+
previews.push({
|
|
98
|
+
label: entry.toolResultPreviewLabel,
|
|
99
|
+
artifact: entry.toolResultPreviewArtifact,
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
return previews;
|
|
103
|
+
}
|
|
104
|
+
function mergePreviewArtifacts(existing, incoming, limit = 6) {
|
|
105
|
+
const merged = [];
|
|
106
|
+
const seen = new Set();
|
|
107
|
+
for (const item of [...existing, ...incoming]) {
|
|
108
|
+
const key = `${item.label}::${item.artifact.handle}`;
|
|
109
|
+
if (seen.has(key))
|
|
110
|
+
continue;
|
|
111
|
+
seen.add(key);
|
|
112
|
+
merged.push(item);
|
|
113
|
+
}
|
|
114
|
+
if (merged.length <= limit)
|
|
115
|
+
return merged;
|
|
116
|
+
return merged.slice(merged.length - limit);
|
|
117
|
+
}
|
|
15
118
|
export class FlowTransactionRunner {
|
|
16
119
|
params;
|
|
17
120
|
historyEntries = [];
|
|
@@ -20,8 +123,25 @@ export class FlowTransactionRunner {
|
|
|
20
123
|
authorizationSummary = null;
|
|
21
124
|
lastContext;
|
|
22
125
|
lastVerifyArtifact;
|
|
126
|
+
lastSubAgentPatchArtifacts;
|
|
127
|
+
lastSubAgentAuditArtifacts;
|
|
128
|
+
lastRecentReadArtifacts;
|
|
129
|
+
lastToolResultPreviewArtifacts;
|
|
130
|
+
lastReplacementState;
|
|
23
131
|
constructor(params) {
|
|
24
132
|
this.params = params;
|
|
133
|
+
this.lastVerifyArtifact = params.options.artifactHints?.verifyArtifact;
|
|
134
|
+
this.lastSubAgentPatchArtifacts = [
|
|
135
|
+
...(params.options.artifactHints?.subAgentPatchArtifacts ?? []),
|
|
136
|
+
];
|
|
137
|
+
this.lastSubAgentAuditArtifacts = [
|
|
138
|
+
...(params.options.artifactHints?.subAgentAuditArtifacts ?? []),
|
|
139
|
+
];
|
|
140
|
+
this.lastRecentReadArtifacts = [...(params.options.artifactHints?.recentReadArtifacts ?? [])];
|
|
141
|
+
this.lastToolResultPreviewArtifacts = [
|
|
142
|
+
...(params.options.artifactHints?.toolResultPreviewArtifacts ?? []),
|
|
143
|
+
];
|
|
144
|
+
this.lastReplacementState = params.options.replacementState;
|
|
25
145
|
}
|
|
26
146
|
isShrinkCtx(ctx) {
|
|
27
147
|
return Boolean(ctx && 'verifyResult' in ctx);
|
|
@@ -29,13 +149,15 @@ export class FlowTransactionRunner {
|
|
|
29
149
|
async execute() {
|
|
30
150
|
let retries = 0;
|
|
31
151
|
let lastReport;
|
|
152
|
+
let lastAttemptFailure;
|
|
153
|
+
const profile = resolveExecutionProfile(this.params.flowMode);
|
|
32
154
|
while (true) {
|
|
33
155
|
if (this.params.options.signal?.aborted) {
|
|
34
156
|
throw new FlowTransactionCancelledError();
|
|
35
157
|
}
|
|
36
158
|
const attempt = retries + 1;
|
|
37
159
|
recordAuditEvent('loop.attempt.start', { attempt, flowMode: this.params.flowMode }, { phase: 'PREFLIGHT', scope: 'session' });
|
|
38
|
-
const result = await
|
|
160
|
+
const result = await executeFlowAttempt({
|
|
39
161
|
workspace: this.params.env.workspace,
|
|
40
162
|
options: this.params.options,
|
|
41
163
|
mode: this.params.flowMode,
|
|
@@ -46,6 +168,20 @@ export class FlowTransactionRunner {
|
|
|
46
168
|
shadowInitialRef: this.params.env.shadowInitialRef,
|
|
47
169
|
attempt,
|
|
48
170
|
initialContext: this.currentContext,
|
|
171
|
+
artifactHints: {
|
|
172
|
+
verifyArtifact: this.lastVerifyArtifact,
|
|
173
|
+
subAgentPatchArtifacts: this.lastSubAgentPatchArtifacts.length > 0
|
|
174
|
+
? this.lastSubAgentPatchArtifacts
|
|
175
|
+
: undefined,
|
|
176
|
+
subAgentAuditArtifacts: this.lastSubAgentAuditArtifacts.length > 0
|
|
177
|
+
? this.lastSubAgentAuditArtifacts
|
|
178
|
+
: undefined,
|
|
179
|
+
recentReadArtifacts: this.lastRecentReadArtifacts.length > 0 ? this.lastRecentReadArtifacts : undefined,
|
|
180
|
+
toolResultPreviewArtifacts: this.lastToolResultPreviewArtifacts.length > 0
|
|
181
|
+
? this.lastToolResultPreviewArtifacts
|
|
182
|
+
: undefined,
|
|
183
|
+
},
|
|
184
|
+
replacementState: this.lastReplacementState,
|
|
49
185
|
lastError: this.currentLastError,
|
|
50
186
|
applyBackRuntime: {
|
|
51
187
|
activeRepoPath: this.params.env.activeRepoPath,
|
|
@@ -64,11 +200,18 @@ export class FlowTransactionRunner {
|
|
|
64
200
|
if (shrinkCtx?.verifyArtifact) {
|
|
65
201
|
this.lastVerifyArtifact = shrinkCtx.verifyArtifact;
|
|
66
202
|
}
|
|
203
|
+
const subAgentArtifacts = extractSubAgentArtifacts(terminalCtx?.toolCallingAudit);
|
|
204
|
+
this.lastSubAgentPatchArtifacts = mergeArtifactHandles(this.lastSubAgentPatchArtifacts, subAgentArtifacts.patchArtifacts);
|
|
205
|
+
this.lastSubAgentAuditArtifacts = mergeArtifactHandles(this.lastSubAgentAuditArtifacts, subAgentArtifacts.auditArtifacts);
|
|
206
|
+
this.lastRecentReadArtifacts = mergeReadArtifacts(this.lastRecentReadArtifacts, extractRecentReadArtifacts(terminalCtx?.toolCallingAudit));
|
|
207
|
+
this.lastToolResultPreviewArtifacts = mergePreviewArtifacts(this.lastToolResultPreviewArtifacts, extractToolResultPreviewArtifacts(terminalCtx?.toolCallingAudit));
|
|
208
|
+
this.lastReplacementState = terminalCtx?.replacementState ?? this.lastReplacementState;
|
|
67
209
|
const attemptFailure = resolveAttemptFailure({
|
|
68
210
|
flowReport: result,
|
|
69
211
|
context: shrinkCtx,
|
|
70
212
|
flowMode: this.params.flowMode,
|
|
71
213
|
});
|
|
214
|
+
lastAttemptFailure = attemptFailure;
|
|
72
215
|
const entry = {
|
|
73
216
|
attempt,
|
|
74
217
|
plan: shrinkCtx?.plan ?? null,
|
|
@@ -82,9 +225,11 @@ export class FlowTransactionRunner {
|
|
|
82
225
|
this.params.telemetry.addHistory(entry);
|
|
83
226
|
this.authorizationSummary = buildAuthorizationSummary(shrinkCtx?.toolAuditLogger?.getLogs?.());
|
|
84
227
|
if (!attemptFailure) {
|
|
85
|
-
const successPhase =
|
|
86
|
-
?
|
|
87
|
-
:
|
|
228
|
+
const successPhase = profile.failurePolicy === 'preserve'
|
|
229
|
+
? profile.entryPhase
|
|
230
|
+
: profile.readOnly
|
|
231
|
+
? 'SHRINK'
|
|
232
|
+
: 'APPLY_BACK';
|
|
88
233
|
recordAuditEvent('loop.attempt.success', { attempt, flowMode: this.params.flowMode }, { phase: successPhase, severity: 'low', scope: 'session' });
|
|
89
234
|
// Reflection Mechanism: trigger when multiple attempts were needed
|
|
90
235
|
if (attempt > 1 && this.params.options.llm) {
|
|
@@ -107,8 +252,12 @@ export class FlowTransactionRunner {
|
|
|
107
252
|
history: this.historyEntries,
|
|
108
253
|
authorizationSummary: this.authorizationSummary,
|
|
109
254
|
lastErrorCode: this.extractErrorCode(result.error),
|
|
110
|
-
lastContext:
|
|
255
|
+
lastContext: terminalCtx,
|
|
111
256
|
lastVerifyArtifact: this.lastVerifyArtifact,
|
|
257
|
+
lastSubAgentPatchArtifacts: this.lastSubAgentPatchArtifacts,
|
|
258
|
+
lastSubAgentAuditArtifacts: this.lastSubAgentAuditArtifacts,
|
|
259
|
+
lastRecentReadArtifacts: this.lastRecentReadArtifacts,
|
|
260
|
+
lastToolResultPreviewArtifacts: this.lastToolResultPreviewArtifacts,
|
|
112
261
|
});
|
|
113
262
|
}
|
|
114
263
|
if (attemptFailure.reasonCode === 'AWAITING_INPUT') {
|
|
@@ -160,8 +309,12 @@ export class FlowTransactionRunner {
|
|
|
160
309
|
history: this.historyEntries,
|
|
161
310
|
authorizationSummary: this.authorizationSummary,
|
|
162
311
|
lastErrorCode: attemptFailure.errorCode ?? this.extractErrorCode(result.error),
|
|
163
|
-
lastContext:
|
|
312
|
+
lastContext: terminalCtx,
|
|
164
313
|
lastVerifyArtifact: this.lastVerifyArtifact,
|
|
314
|
+
lastSubAgentPatchArtifacts: this.lastSubAgentPatchArtifacts,
|
|
315
|
+
lastSubAgentAuditArtifacts: this.lastSubAgentAuditArtifacts,
|
|
316
|
+
lastRecentReadArtifacts: this.lastRecentReadArtifacts,
|
|
317
|
+
lastToolResultPreviewArtifacts: this.lastToolResultPreviewArtifacts,
|
|
165
318
|
failure: attemptFailure,
|
|
166
319
|
});
|
|
167
320
|
}
|
|
@@ -184,9 +337,14 @@ export class FlowTransactionRunner {
|
|
|
184
337
|
flowReport: lastReport,
|
|
185
338
|
history: this.historyEntries,
|
|
186
339
|
authorizationSummary: this.authorizationSummary,
|
|
340
|
+
failure: lastAttemptFailure,
|
|
187
341
|
lastErrorCode: this.extractErrorCode(lastReport.error),
|
|
188
342
|
lastContext: this.lastContext,
|
|
189
343
|
lastVerifyArtifact: this.lastVerifyArtifact,
|
|
344
|
+
lastSubAgentPatchArtifacts: this.lastSubAgentPatchArtifacts,
|
|
345
|
+
lastSubAgentAuditArtifacts: this.lastSubAgentAuditArtifacts,
|
|
346
|
+
lastRecentReadArtifacts: this.lastRecentReadArtifacts,
|
|
347
|
+
lastToolResultPreviewArtifacts: this.lastToolResultPreviewArtifacts,
|
|
190
348
|
});
|
|
191
349
|
}
|
|
192
350
|
extractErrorCode(error) {
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Pipeline } from '../engine/pipeline/pipeline.js';
|
|
2
|
+
import { saveAudit } from '../steps/audit.js';
|
|
3
|
+
import { runAutopilot, runAutopilotVerifyGate } from '../steps/autopilot.js';
|
|
4
|
+
import { displayReport } from '../steps/display-report.js';
|
|
5
|
+
import { runPreflight } from '../steps/preflight.js';
|
|
6
|
+
export async function executeAutopilotFlow(initCtx) {
|
|
7
|
+
const pipeline = Pipeline.of(initCtx)
|
|
8
|
+
.step('PREFLIGHT', runPreflight)
|
|
9
|
+
.step('AUTOPILOT', runAutopilot)
|
|
10
|
+
.step('VERIFY_GATE', runAutopilotVerifyGate)
|
|
11
|
+
.step('REPORT', displayReport);
|
|
12
|
+
const report = await pipeline.execute();
|
|
13
|
+
report.auditPath = await saveAudit(report, initCtx.options);
|
|
14
|
+
report.strategyName = initCtx.mode;
|
|
15
|
+
report.fsMode = initCtx.mode;
|
|
16
|
+
return report;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=AutopilotFlow.js.map
|