salmon-loop 0.2.3 → 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 +161 -24
- package/dist/cli/commands/chat.js +30 -24
- package/dist/cli/commands/context.js +15 -3
- package/dist/cli/commands/flow-mode.js +63 -0
- package/dist/cli/commands/help-format.js +12 -0
- package/dist/cli/commands/registry.js +6 -7
- package/dist/cli/commands/run/benchmark-artifacts.js +41 -0
- package/dist/cli/commands/run/config-resolution.js +30 -24
- package/dist/cli/commands/run/early-errors.js +23 -0
- package/dist/cli/commands/run/handler.js +131 -44
- package/dist/cli/commands/run/headless-error-writer.js +8 -0
- package/dist/cli/commands/run/loop-params.js +3 -0
- package/dist/cli/commands/run/mode.js +2 -5
- package/dist/cli/commands/run/parse-options.js +18 -2
- 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/run/validate-options.js +0 -5
- package/dist/cli/commands/run/verbose.js +2 -7
- package/dist/cli/commands/serve.js +117 -90
- 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 +32 -6
- package/dist/cli/program-bootstrap.js +14 -4
- package/dist/cli/program-commands.js +9 -1
- package/dist/cli/program-options.js +1 -0
- 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 +30 -15
- 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/output-format.js +6 -0
- package/dist/cli/utils/resolve-cli-config.js +98 -0
- package/dist/cli/utils/verbose-level.js +8 -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 +39 -18
- package/dist/core/config/merge.js +27 -0
- package/dist/core/config/paths.js +24 -5
- package/dist/core/config/resolve-llm.js +12 -0
- package/dist/core/config/resolve.js +7 -5
- package/dist/core/config/resolvers/server.js +0 -6
- package/dist/core/config/validate.js +94 -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 +2 -1
- package/dist/core/facades/cli-command-tool-names.js +2 -0
- package/dist/core/facades/cli-context.js +1 -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 +173 -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 -3
- 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/intent/chat-intent.js +0 -4
- 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 +74 -1
- 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 +8 -6
- package/dist/core/protocols/a2a/sdk/server.js +0 -1
- package/dist/core/protocols/acp/formal-agent.js +221 -55
- package/dist/core/protocols/acp/handlers.js +5 -1
- package/dist/core/protocols/acp/permission-provider.js +21 -1
- package/dist/core/protocols/shared/execution-request.js +24 -0
- 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 +12 -4
- package/dist/core/session/manager.js +247 -10
- 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 +70 -13
- 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/interfaces/cli/task-runner.js +4 -3
- package/dist/languages/typescript/index.js +4 -1
- package/dist/locales/en.js +87 -2
- package/dist/utils/eol.js +1 -1
- package/package.json +15 -8
- 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
|
@@ -1,16 +1,21 @@
|
|
|
1
1
|
import { text } from '../../../locales/index.js';
|
|
2
2
|
import { LIMITS } from '../../config/limits.js';
|
|
3
|
+
import { supportsLlmStreaming } from '../../llm/capabilities.js';
|
|
3
4
|
import { repairToJsonObject } from '../../llm/contracts/repair.js';
|
|
4
5
|
import { sanitizeError } from '../../llm/errors.js';
|
|
5
|
-
import { composeChatMessages } from '../../llm/message-composition.js';
|
|
6
6
|
import { emitLlmOutput } from '../../llm/output-policy.js';
|
|
7
|
-
import {
|
|
7
|
+
import { parsePlanFromLLMContent } from '../../llm/utils.js';
|
|
8
|
+
import { recordAuditEvent } from '../../observability/audit-trail.js';
|
|
8
9
|
import { logIgnoredError } from '../../observability/ignored-error.js';
|
|
9
10
|
import { readPlan, updatePlan } from '../../plan/index.js';
|
|
10
11
|
import { getPlanPrompt, getPlanSystemPrompt } from '../../prompts/runtime.js';
|
|
12
|
+
import { SessionReplacementPreviewProvider } from '../../session/replacement-preview-provider.js';
|
|
11
13
|
import { chatWithTools, chatWithToolsStreaming } from '../../tools/session.js';
|
|
14
|
+
import { resolveVisibleToolSpecs } from '../../tools/tool-visibility.js';
|
|
12
15
|
import { Phase } from '../../types/runtime.js';
|
|
13
16
|
import { resolveLlmToolCallingPolicy } from '../dsl/llm-strategy.js';
|
|
17
|
+
import { buildPhaseRequestEnvelope } from './request-assembly.js';
|
|
18
|
+
import { buildPhaseToolRuntimeContext, buildToolVisibilityRuntime } from './tool-runtime.js';
|
|
14
19
|
function sanitizeSubtaskText(raw) {
|
|
15
20
|
const oneLine = String(raw ?? '')
|
|
16
21
|
.replace(/\r?\n/g, ' ')
|
|
@@ -27,6 +32,25 @@ function sanitizeSubtaskText(raw) {
|
|
|
27
32
|
return withoutComments;
|
|
28
33
|
return withoutComments.slice(0, maxLen - 1).trimEnd() + '…';
|
|
29
34
|
}
|
|
35
|
+
function recordPlanRepairAttempt(args) {
|
|
36
|
+
recordAuditEvent('plan.repair.attempt', {
|
|
37
|
+
reason: args.reason,
|
|
38
|
+
badContentLength: args.badContentLength,
|
|
39
|
+
toolsDisabled: true,
|
|
40
|
+
}, { source: 'plan', severity: 'low', scope: 'session', phase: 'PLAN' });
|
|
41
|
+
}
|
|
42
|
+
function recordPlanRepairResult(args) {
|
|
43
|
+
recordAuditEvent('plan.repair.result', {
|
|
44
|
+
ok: args.ok,
|
|
45
|
+
contentLength: args.contentLength,
|
|
46
|
+
error: args.error,
|
|
47
|
+
}, {
|
|
48
|
+
source: 'plan',
|
|
49
|
+
severity: args.ok ? 'low' : 'medium',
|
|
50
|
+
scope: 'session',
|
|
51
|
+
phase: 'PLAN',
|
|
52
|
+
});
|
|
53
|
+
}
|
|
30
54
|
async function hydrateRuntimePlanTodos(ctx, plan) {
|
|
31
55
|
const runtime = ctx.planRuntime;
|
|
32
56
|
if (!runtime?.sessionId)
|
|
@@ -64,6 +88,15 @@ async function hydrateRuntimePlanTodos(ctx, plan) {
|
|
|
64
88
|
},
|
|
65
89
|
});
|
|
66
90
|
}
|
|
91
|
+
export function hasSuccessfulPlanUpdateDuringPlan(ctx) {
|
|
92
|
+
const auditEntries = ctx.toolCallingAudit;
|
|
93
|
+
if (!Array.isArray(auditEntries) || auditEntries.length === 0)
|
|
94
|
+
return false;
|
|
95
|
+
return auditEntries.some((entry) => entry.phase === Phase.PLAN &&
|
|
96
|
+
entry.toolName === 'plan.update' &&
|
|
97
|
+
entry.toolResultStatus === 'ok' &&
|
|
98
|
+
entry.toolResultOutputOk === true);
|
|
99
|
+
}
|
|
67
100
|
export const generatePlan = async (ctx) => {
|
|
68
101
|
const toolstack = ctx.toolstack;
|
|
69
102
|
const toolPolicy = resolveLlmToolCallingPolicy(Phase.PLAN, ctx.options.llm);
|
|
@@ -83,21 +116,53 @@ export const generatePlan = async (ctx) => {
|
|
|
83
116
|
message: `Plan generated: ${plan.goal}`,
|
|
84
117
|
timestamp: new Date(),
|
|
85
118
|
});
|
|
86
|
-
|
|
87
|
-
|
|
119
|
+
if (ctx.planRuntime?.sessionId) {
|
|
120
|
+
// Transitional fallback: legacy/non-tool PLAN runs may hydrate runtime subtasks from final JSON.
|
|
121
|
+
await hydrateRuntimePlanTodos(ctx, plan).catch((error) => logIgnoredError('[Plan] hydrate runtime plan todos (legacy)', error));
|
|
122
|
+
}
|
|
88
123
|
return {
|
|
89
124
|
...ctx,
|
|
90
125
|
plan,
|
|
91
126
|
};
|
|
92
127
|
}
|
|
93
|
-
const
|
|
94
|
-
const
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
128
|
+
const toolVisibility = buildToolVisibilityRuntime(ctx);
|
|
129
|
+
const promptVisibleTools = resolveVisibleToolSpecs({
|
|
130
|
+
phase: Phase.PLAN,
|
|
131
|
+
toolstack,
|
|
132
|
+
worktreeRoot: ctx.workspace.strategy === 'worktree' ? ctx.workspace.workPath : undefined,
|
|
133
|
+
flowMode: ctx.mode,
|
|
134
|
+
runtime: toolVisibility,
|
|
135
|
+
});
|
|
136
|
+
const systemPrompt = await getPlanSystemPrompt(promptVisibleTools, toolVisibility);
|
|
137
|
+
const requestEnvelope = await buildPhaseRequestEnvelope({
|
|
138
|
+
phase: Phase.PLAN,
|
|
139
|
+
defaultNamespace: 'plan',
|
|
140
|
+
context: ctx.context,
|
|
141
|
+
contextResult: ctx.contextResult,
|
|
142
|
+
cacheSharing: ctx.cacheSharing,
|
|
143
|
+
onCacheMismatch: (mismatch) => {
|
|
144
|
+
recordAuditEvent('request.cache_sharing_hash_mismatch', mismatch, {
|
|
145
|
+
source: 'llm',
|
|
146
|
+
severity: 'low',
|
|
147
|
+
scope: 'session',
|
|
148
|
+
phase: Phase.PLAN,
|
|
149
|
+
});
|
|
150
|
+
},
|
|
151
|
+
systemPrompt,
|
|
152
|
+
buildUserPrompt: (contextPrompt) => getPlanPrompt(contextPrompt, ctx.options.instruction, LIMITS.maxFilesChanged, ctx.lastError),
|
|
98
153
|
conversationContext: ctx.options.conversationContext,
|
|
154
|
+
artifactHints: ctx.artifactHints,
|
|
155
|
+
toolCallingAudit: ctx.toolCallingAudit,
|
|
156
|
+
previewProvider: new SessionReplacementPreviewProvider(ctx.replacementState),
|
|
157
|
+
toolVisibility: {
|
|
158
|
+
toolstack,
|
|
159
|
+
runtime: toolVisibility,
|
|
160
|
+
worktreeRoot: ctx.workspace.strategy === 'worktree' ? ctx.workspace.workPath : undefined,
|
|
161
|
+
flowMode: ctx.mode,
|
|
162
|
+
},
|
|
99
163
|
});
|
|
100
|
-
const
|
|
164
|
+
const { cacheSurface, envelope, baseMessages } = requestEnvelope;
|
|
165
|
+
const supportsStreaming = supportsLlmStreaming(ctx.options.llm, Phase.PLAN);
|
|
101
166
|
const llmOutput = {
|
|
102
167
|
policy: ctx.options.llmOutput,
|
|
103
168
|
kind: 'plan',
|
|
@@ -105,23 +170,13 @@ export const generatePlan = async (ctx) => {
|
|
|
105
170
|
};
|
|
106
171
|
const response = await (supportsStreaming ? chatWithToolsStreaming : chatWithTools)(baseMessages, {
|
|
107
172
|
responseFormat: 'json_object',
|
|
173
|
+
providerHints: envelope.providerHints,
|
|
108
174
|
signal: ctx.options.signal,
|
|
109
175
|
}, {
|
|
110
176
|
phase: Phase.PLAN,
|
|
111
177
|
llm: ctx.options.llm,
|
|
112
|
-
runtime:
|
|
113
|
-
|
|
114
|
-
persistenceRoot: ctx.workspace.baseRepoPath || ctx.workspace.workPath,
|
|
115
|
-
worktreeRoot: ctx.workspace.strategy === 'worktree' ? ctx.workspace.workPath : undefined,
|
|
116
|
-
attemptId: ctx.attempt ?? 1,
|
|
117
|
-
dryRun: Boolean(ctx.options?.dryRun),
|
|
118
|
-
llm: ctx.options.llm,
|
|
119
|
-
model: ctx.options.llm.getModelId?.() || process.env.SALMONLOOP_MODEL || process.env.S8P_MODEL,
|
|
120
|
-
userInputProvider: ctx.options.userInputProvider,
|
|
121
|
-
agentKind: ctx.options.agentKind ?? 'primary',
|
|
122
|
-
languagePlugins: ctx.options.languagePlugins,
|
|
123
|
-
subAgentController: ctx.options.subAgentController,
|
|
124
|
-
},
|
|
178
|
+
runtime: buildPhaseToolRuntimeContext(ctx, Phase.PLAN, cacheSurface),
|
|
179
|
+
toolVisibility,
|
|
125
180
|
toolstack,
|
|
126
181
|
eventPayload: ctx.options.eventPayload,
|
|
127
182
|
toolCallingAudit: {
|
|
@@ -145,6 +200,10 @@ export const generatePlan = async (ctx) => {
|
|
|
145
200
|
plan = parsePlanFromLLMContent(finalContent);
|
|
146
201
|
}
|
|
147
202
|
catch (e) {
|
|
203
|
+
recordPlanRepairAttempt({
|
|
204
|
+
reason: sanitizeError(e),
|
|
205
|
+
badContentLength: finalContent.length,
|
|
206
|
+
});
|
|
148
207
|
let repaired;
|
|
149
208
|
try {
|
|
150
209
|
repaired = await repairToJsonObject({
|
|
@@ -156,6 +215,11 @@ export const generatePlan = async (ctx) => {
|
|
|
156
215
|
});
|
|
157
216
|
}
|
|
158
217
|
catch (repairError) {
|
|
218
|
+
recordPlanRepairResult({
|
|
219
|
+
ok: false,
|
|
220
|
+
contentLength: 0,
|
|
221
|
+
error: sanitizeError(repairError).slice(0, 400),
|
|
222
|
+
});
|
|
159
223
|
throw new Error(text.llm.planParseFailed(finalContent, sanitizeError(repairError)));
|
|
160
224
|
}
|
|
161
225
|
finalContent = repaired.content || '';
|
|
@@ -172,8 +236,17 @@ export const generatePlan = async (ctx) => {
|
|
|
172
236
|
plan = parsePlanFromLLMContent(finalContent);
|
|
173
237
|
}
|
|
174
238
|
catch (e2) {
|
|
239
|
+
recordPlanRepairResult({
|
|
240
|
+
ok: false,
|
|
241
|
+
contentLength: finalContent.length,
|
|
242
|
+
error: sanitizeError(e2).slice(0, 400),
|
|
243
|
+
});
|
|
175
244
|
throw new Error(text.llm.planParseFailed(finalContent, sanitizeError(e2)));
|
|
176
245
|
}
|
|
246
|
+
recordPlanRepairResult({
|
|
247
|
+
ok: true,
|
|
248
|
+
contentLength: finalContent.length,
|
|
249
|
+
});
|
|
177
250
|
}
|
|
178
251
|
ctx.emit({
|
|
179
252
|
type: 'log',
|
|
@@ -181,8 +254,11 @@ export const generatePlan = async (ctx) => {
|
|
|
181
254
|
message: `Plan generated: ${plan.goal}`,
|
|
182
255
|
timestamp: new Date(),
|
|
183
256
|
});
|
|
184
|
-
|
|
185
|
-
|
|
257
|
+
const hasModelPlanUpdate = hasSuccessfulPlanUpdateDuringPlan(ctx);
|
|
258
|
+
if (ctx.planRuntime?.sessionId && !hasModelPlanUpdate) {
|
|
259
|
+
// Transitional fallback: only hydrate when PLAN did not successfully persist via plan.update.
|
|
260
|
+
await hydrateRuntimePlanTodos(ctx, plan).catch((error) => logIgnoredError('[Plan] hydrate runtime plan todos (tools)', error));
|
|
261
|
+
}
|
|
186
262
|
return {
|
|
187
263
|
...ctx,
|
|
188
264
|
plan,
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { text } from '../../../locales/index.js';
|
|
2
2
|
import { recordAuditEvent } from '../../observability/audit-trail.js';
|
|
3
|
+
import { resolveExecutionProfile } from '../../runtime/execution-profile.js';
|
|
3
4
|
import { createStandardToolstack } from '../../tools/loader.js';
|
|
4
|
-
import { Phase } from '../../types/runtime.js';
|
|
5
5
|
import { preflight } from '../../verification/runner.js';
|
|
6
6
|
import { resolveLlmToolCallingPolicy } from '../dsl/llm-strategy.js';
|
|
7
7
|
export const runPreflight = async (ctx) => {
|
|
8
|
+
const executionProfile = resolveExecutionProfile(ctx.mode);
|
|
8
9
|
const result = await preflight(ctx.workspace, ctx.emit, {
|
|
9
|
-
ignoreDirty:
|
|
10
|
+
ignoreDirty: executionProfile.ignoreDirtyPreflight,
|
|
10
11
|
});
|
|
11
12
|
if (!result.ok) {
|
|
12
13
|
const reason = result.reason || text.loop.preflightFailedNotGit;
|
|
@@ -26,7 +27,8 @@ export const runPreflight = async (ctx) => {
|
|
|
26
27
|
message: text.loop.preflightPassed,
|
|
27
28
|
timestamp: new Date(),
|
|
28
29
|
});
|
|
29
|
-
const toolstack = resolveLlmToolCallingPolicy(
|
|
30
|
+
const toolstack = resolveLlmToolCallingPolicy(executionProfile.entryPhase, ctx.options.llm)
|
|
31
|
+
.enabled
|
|
30
32
|
? await createStandardToolstack({
|
|
31
33
|
repoRoot: ctx.workspace.workPath,
|
|
32
34
|
persistenceRoot: ctx.workspace.baseRepoPath || ctx.workspace.workPath,
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { augmentPromptWithRelevantMemory } from '../../llm/request-augmentation.js';
|
|
2
|
+
import { buildSharedRequestEnvelope as buildSharedRequestEnvelopeCore, } from '../../llm/shared-request-assembly.js';
|
|
3
|
+
import { formatContextForPrompt } from '../../llm/utils.js';
|
|
4
|
+
import { buildRelevantMemoryCandidates, selectRelevantMemory, } from '../../memory/relevant-retrieval.js';
|
|
5
|
+
import { resolveVisibleToolNames, } from '../../tools/tool-visibility.js';
|
|
6
|
+
import { resolveCacheSharingSurface, } from './cache-sharing.js';
|
|
7
|
+
export function buildSharedRequestEnvelope(args) {
|
|
8
|
+
return buildSharedRequestEnvelopeCore(args);
|
|
9
|
+
}
|
|
10
|
+
export async function buildAugmentedRequestEnvelope(args) {
|
|
11
|
+
const baseContextPrompt = args.baseContextPrompt ?? args.contextResult?.prompt ?? formatContextForPrompt(args.context);
|
|
12
|
+
const localContextHash = args.contextResult?.meta?.contextHash ?? args.context.contextHash;
|
|
13
|
+
const cacheSurface = resolveCacheSharingSurface({
|
|
14
|
+
phase: args.phase,
|
|
15
|
+
defaultNamespace: args.defaultNamespace,
|
|
16
|
+
localContextHash,
|
|
17
|
+
cacheSharing: args.cacheSharing,
|
|
18
|
+
mismatchPolicy: args.cacheMismatchPolicy,
|
|
19
|
+
onMismatch: args.onCacheMismatch,
|
|
20
|
+
});
|
|
21
|
+
const relevantMemory = selectRelevantMemory({
|
|
22
|
+
instruction: args.context.instruction,
|
|
23
|
+
candidates: args.relevantMemory?.entries ?? buildRelevantMemoryCandidates(args.context),
|
|
24
|
+
activeToolNames: resolveVisibleToolNames({
|
|
25
|
+
phase: args.phase,
|
|
26
|
+
toolstack: args.toolVisibility?.toolstack,
|
|
27
|
+
runtime: args.toolVisibility?.runtime,
|
|
28
|
+
worktreeRoot: args.toolVisibility?.worktreeRoot,
|
|
29
|
+
flowMode: args.toolVisibility?.flowMode,
|
|
30
|
+
}),
|
|
31
|
+
maxItems: args.relevantMemory?.maxItems,
|
|
32
|
+
alreadySurfacedText: [
|
|
33
|
+
baseContextPrompt,
|
|
34
|
+
...(Array.isArray(args.systemPrompt) ? args.systemPrompt : [args.systemPrompt]),
|
|
35
|
+
...(args.conversationContext ?? []).map((message) => message.content),
|
|
36
|
+
],
|
|
37
|
+
});
|
|
38
|
+
const contextPrompt = augmentPromptWithRelevantMemory({
|
|
39
|
+
basePrompt: baseContextPrompt,
|
|
40
|
+
selectedEntries: relevantMemory,
|
|
41
|
+
budgetTokens: args.relevantMemory?.budgetTokens,
|
|
42
|
+
countTokens: args.relevantMemory?.countTokens,
|
|
43
|
+
}).prompt;
|
|
44
|
+
const userPrompt = await args.buildUserPrompt(contextPrompt);
|
|
45
|
+
const shared = buildSharedRequestEnvelope({
|
|
46
|
+
defaultNamespace: cacheSurface.namespace,
|
|
47
|
+
contextHash: cacheSurface.contextHash,
|
|
48
|
+
systemPrompt: args.systemPrompt,
|
|
49
|
+
userPrompt,
|
|
50
|
+
conversationContext: args.conversationContext,
|
|
51
|
+
artifactHints: args.artifactHints,
|
|
52
|
+
toolCallingAudit: args.toolCallingAudit,
|
|
53
|
+
previewProvider: args.previewProvider,
|
|
54
|
+
attachments: [
|
|
55
|
+
{
|
|
56
|
+
key: 'context-prompt',
|
|
57
|
+
kind: 'context',
|
|
58
|
+
label: 'Context prompt',
|
|
59
|
+
content: contextPrompt,
|
|
60
|
+
cacheSafe: true,
|
|
61
|
+
},
|
|
62
|
+
...(args.extraAttachments ?? []),
|
|
63
|
+
],
|
|
64
|
+
providerHints: args.providerHints,
|
|
65
|
+
});
|
|
66
|
+
return {
|
|
67
|
+
contextPrompt,
|
|
68
|
+
userPrompt,
|
|
69
|
+
cacheSurface,
|
|
70
|
+
resolvedArtifactHints: shared.resolvedArtifactHints,
|
|
71
|
+
envelope: shared.envelope,
|
|
72
|
+
baseMessages: shared.baseMessages,
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
export async function buildPhaseRequestEnvelope(args) {
|
|
76
|
+
return buildAugmentedRequestEnvelope(args);
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=request-assembly.js.map
|
|
@@ -1,23 +1,14 @@
|
|
|
1
1
|
import { text } from '../../../locales/index.js';
|
|
2
|
-
import {
|
|
2
|
+
import { supportsLlmStreaming } from '../../llm/capabilities.js';
|
|
3
3
|
import { emitLlmOutput } from '../../llm/output-policy.js';
|
|
4
|
-
import {
|
|
4
|
+
import { recordAuditEvent } from '../../observability/audit-trail.js';
|
|
5
|
+
import { getResearchPrompt, getResearchSystemPrompt } from '../../prompts/runtime.js';
|
|
6
|
+
import { SessionReplacementPreviewProvider } from '../../session/replacement-preview-provider.js';
|
|
5
7
|
import { chatWithTools, chatWithToolsStreaming } from '../../tools/session.js';
|
|
6
8
|
import { Phase } from '../../types/runtime.js';
|
|
7
9
|
import { resolveLlmToolCallingPolicy } from '../dsl/llm-strategy.js';
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
'You are running in deep research mode.',
|
|
11
|
-
'Use available tools to gather external information as needed.',
|
|
12
|
-
'Return JSON with keys: researchNotes, researchFindings, sources, researchText.',
|
|
13
|
-
'Each researchFinding should include: summary, confidence (0-1), uncertainty (string).',
|
|
14
|
-
'Each source should include: toolName, summary, ok, timestamp (epoch ms).',
|
|
15
|
-
'',
|
|
16
|
-
`Instruction:\n${instruction}`,
|
|
17
|
-
'',
|
|
18
|
-
`Context:\n${contextText}`,
|
|
19
|
-
].join('\n');
|
|
20
|
-
}
|
|
10
|
+
import { buildPhaseRequestEnvelope } from './request-assembly.js';
|
|
11
|
+
import { buildPhaseToolRuntimeContext, buildToolVisibilityRuntime } from './tool-runtime.js';
|
|
21
12
|
function normalizeFindings(value) {
|
|
22
13
|
if (!value)
|
|
23
14
|
return [];
|
|
@@ -88,20 +79,43 @@ function buildSourcesFromAudit(entries) {
|
|
|
88
79
|
}));
|
|
89
80
|
}
|
|
90
81
|
export async function generateResearch(ctx) {
|
|
91
|
-
const
|
|
92
|
-
const
|
|
93
|
-
const
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
82
|
+
const systemPrompt = await getResearchSystemPrompt();
|
|
83
|
+
const toolVisibility = buildToolVisibilityRuntime(ctx);
|
|
84
|
+
const requestEnvelope = await buildPhaseRequestEnvelope({
|
|
85
|
+
phase: Phase.RESEARCH,
|
|
86
|
+
defaultNamespace: 'research',
|
|
87
|
+
context: ctx.context,
|
|
88
|
+
contextResult: ctx.contextResult,
|
|
89
|
+
cacheSharing: ctx.cacheSharing,
|
|
90
|
+
onCacheMismatch: (mismatch) => {
|
|
91
|
+
recordAuditEvent('request.cache_sharing_hash_mismatch', mismatch, {
|
|
92
|
+
source: 'llm',
|
|
93
|
+
severity: 'low',
|
|
94
|
+
scope: 'session',
|
|
95
|
+
phase: Phase.RESEARCH,
|
|
96
|
+
});
|
|
97
|
+
},
|
|
98
|
+
systemPrompt,
|
|
99
|
+
buildUserPrompt: async (contextText) => await getResearchPrompt(contextText, ctx.options.instruction),
|
|
97
100
|
conversationContext: ctx.options.conversationContext,
|
|
101
|
+
artifactHints: ctx.artifactHints,
|
|
102
|
+
toolCallingAudit: ctx.toolCallingAudit,
|
|
103
|
+
previewProvider: new SessionReplacementPreviewProvider(ctx.replacementState),
|
|
104
|
+
toolVisibility: {
|
|
105
|
+
toolstack: ctx.toolstack,
|
|
106
|
+
runtime: toolVisibility,
|
|
107
|
+
worktreeRoot: ctx.workspace.strategy === 'worktree' ? ctx.workspace.workPath : undefined,
|
|
108
|
+
flowMode: ctx.mode,
|
|
109
|
+
},
|
|
98
110
|
});
|
|
111
|
+
const { cacheSurface, envelope, baseMessages } = requestEnvelope;
|
|
99
112
|
const toolPolicy = resolveLlmToolCallingPolicy(Phase.RESEARCH, ctx.options.llm);
|
|
100
|
-
const supportsStreaming =
|
|
113
|
+
const supportsStreaming = supportsLlmStreaming(ctx.options.llm, Phase.RESEARCH);
|
|
101
114
|
const localAudit = [];
|
|
102
115
|
const sourcesFromAudit = () => buildSourcesFromAudit(localAudit);
|
|
103
116
|
if (!ctx.toolstack || !toolPolicy.enabled) {
|
|
104
117
|
const response = await ctx.options.llm.chat(baseMessages, {
|
|
118
|
+
providerHints: envelope.providerHints,
|
|
105
119
|
signal: ctx.options.signal,
|
|
106
120
|
phase: Phase.RESEARCH,
|
|
107
121
|
});
|
|
@@ -133,22 +147,11 @@ export async function generateResearch(ctx) {
|
|
|
133
147
|
kind: 'research',
|
|
134
148
|
step: 'RESEARCH',
|
|
135
149
|
};
|
|
136
|
-
const response = await (supportsStreaming ? chatWithToolsStreaming : chatWithTools)(baseMessages, { signal: ctx.options.signal }, {
|
|
150
|
+
const response = await (supportsStreaming ? chatWithToolsStreaming : chatWithTools)(baseMessages, { providerHints: envelope.providerHints, signal: ctx.options.signal }, {
|
|
137
151
|
phase: Phase.RESEARCH,
|
|
138
152
|
llm: ctx.options.llm,
|
|
139
|
-
runtime:
|
|
140
|
-
|
|
141
|
-
persistenceRoot: ctx.workspace.baseRepoPath || ctx.workspace.workPath,
|
|
142
|
-
worktreeRoot: ctx.workspace.strategy === 'worktree' ? ctx.workspace.workPath : undefined,
|
|
143
|
-
attemptId: ctx.attempt ?? 1,
|
|
144
|
-
dryRun: Boolean(ctx.options?.dryRun),
|
|
145
|
-
llm: ctx.options.llm,
|
|
146
|
-
model: ctx.options.llm.getModelId?.() || process.env.SALMONLOOP_MODEL || process.env.S8P_MODEL,
|
|
147
|
-
userInputProvider: ctx.options.userInputProvider,
|
|
148
|
-
agentKind: ctx.options.agentKind ?? 'primary',
|
|
149
|
-
languagePlugins: ctx.options.languagePlugins,
|
|
150
|
-
subAgentController: ctx.options.subAgentController,
|
|
151
|
-
},
|
|
153
|
+
runtime: buildPhaseToolRuntimeContext(ctx, Phase.RESEARCH, cacheSurface),
|
|
154
|
+
toolVisibility,
|
|
152
155
|
toolstack: ctx.toolstack,
|
|
153
156
|
eventPayload: ctx.options.eventPayload,
|
|
154
157
|
toolCallingAudit: {
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { buildSystemPrefixDigest, buildToolSchemaHash, } from '../../sub-agent/prefix-consistency.js';
|
|
2
|
+
export function buildPhaseToolRuntimeContext(ctx, phase, cacheSurface) {
|
|
3
|
+
return {
|
|
4
|
+
repoRoot: ctx.workspace.workPath,
|
|
5
|
+
persistenceRoot: ctx.workspace.baseRepoPath || ctx.workspace.workPath,
|
|
6
|
+
worktreeRoot: ctx.workspace.strategy === 'worktree' ? ctx.workspace.workPath : undefined,
|
|
7
|
+
flowMode: ctx.mode,
|
|
8
|
+
attemptId: ctx.attempt ?? 1,
|
|
9
|
+
dryRun: Boolean(ctx.options?.dryRun),
|
|
10
|
+
llm: ctx.options.llm,
|
|
11
|
+
model: ctx.options.llm.getModelId?.() || process.env.SALMONLOOP_MODEL || process.env.S8P_MODEL,
|
|
12
|
+
userInputProvider: ctx.options.userInputProvider,
|
|
13
|
+
agentKind: ctx.options.agentKind ?? 'primary',
|
|
14
|
+
languagePlugins: ctx.options.languagePlugins,
|
|
15
|
+
subAgentController: ctx.options.subAgentController,
|
|
16
|
+
phase,
|
|
17
|
+
contextSnapshot: {
|
|
18
|
+
conversationContext: ctx.options.conversationContext,
|
|
19
|
+
artifactHints: ctx.artifactHints,
|
|
20
|
+
toolCallingAudit: ctx.toolCallingAudit,
|
|
21
|
+
replacementState: ctx.replacementState,
|
|
22
|
+
planRuntime: ctx.planRuntime,
|
|
23
|
+
cacheSharing: {
|
|
24
|
+
namespace: cacheSurface.namespace,
|
|
25
|
+
contextHash: cacheSurface.contextHash,
|
|
26
|
+
toolSchemaHash: buildToolSchemaHash({
|
|
27
|
+
phase,
|
|
28
|
+
allowedToolNames: ctx.options.allowedToolNames,
|
|
29
|
+
}),
|
|
30
|
+
systemPrefixDigest: buildSystemPrefixDigest({
|
|
31
|
+
phase,
|
|
32
|
+
namespace: cacheSurface.namespace,
|
|
33
|
+
contextHash: cacheSurface.contextHash,
|
|
34
|
+
}),
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
export function buildToolVisibilityRuntime(ctx) {
|
|
40
|
+
if (!ctx.planRuntime) {
|
|
41
|
+
return undefined;
|
|
42
|
+
}
|
|
43
|
+
return {
|
|
44
|
+
plan: ctx.planRuntime,
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=tool-runtime.js.map
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { ArtifactStore } from '../../sub-agent/artifacts/store.js';
|
|
2
|
+
import { runVerify as runVerifyCommand } from '../../verification/runner.js';
|
|
3
|
+
export async function executeVerifyForWorkspace(params) {
|
|
4
|
+
const verifyResult = await runVerifyCommand(params.workspacePath, params.verify, undefined, params.signal);
|
|
5
|
+
let verifyArtifact;
|
|
6
|
+
if (!verifyResult.ok && verifyResult.output) {
|
|
7
|
+
try {
|
|
8
|
+
verifyArtifact = await ArtifactStore.saveText({
|
|
9
|
+
content: verifyResult.output,
|
|
10
|
+
mimeType: 'text/plain',
|
|
11
|
+
fileExt: 'log',
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
catch {
|
|
15
|
+
// Best-effort only; keep verifyResult.output in-memory for shrink/error classification.
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
return {
|
|
19
|
+
verifyResult,
|
|
20
|
+
...(verifyArtifact ? { verifyArtifact } : {}),
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=verify-shared.js.map
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { text } from '../../../locales/index.js';
|
|
2
2
|
import { collectBudgetMetrics, evaluateBudgetAlert, getGlobalAdjuster, recordBudgetAlert, } from '../../context/budget/integration.js';
|
|
3
3
|
import { recordAuditEvent } from '../../observability/audit-trail.js';
|
|
4
|
-
import {
|
|
5
|
-
import { runVerify as runVerifyCommand } from '../../verification/runner.js';
|
|
4
|
+
import { executeVerifyForWorkspace } from './verify-shared.js';
|
|
6
5
|
function extractCommandProgram(command) {
|
|
7
6
|
const trimmed = command.trim();
|
|
8
7
|
if (!trimmed)
|
|
@@ -16,8 +15,11 @@ export const runVerify = async (ctx) => {
|
|
|
16
15
|
verifyResult: { ok: true, output: text.loop.verificationSkipped, exitCode: null },
|
|
17
16
|
};
|
|
18
17
|
}
|
|
19
|
-
const verifyResult = await
|
|
20
|
-
|
|
18
|
+
const { verifyResult, verifyArtifact } = await executeVerifyForWorkspace({
|
|
19
|
+
workspacePath: ctx.workspace.workPath,
|
|
20
|
+
verify: ctx.options.verify,
|
|
21
|
+
signal: ctx.options.signal,
|
|
22
|
+
});
|
|
21
23
|
recordAuditEvent('verify.summary', {
|
|
22
24
|
ok: verifyResult.ok,
|
|
23
25
|
exitCode: verifyResult.exitCode,
|
|
@@ -92,23 +94,13 @@ export const runVerify = async (ctx) => {
|
|
|
92
94
|
message: text.loop.verificationFailedSummary,
|
|
93
95
|
timestamp: new Date(),
|
|
94
96
|
});
|
|
95
|
-
if (
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
ctx.emit({
|
|
103
|
-
type: 'log',
|
|
104
|
-
level: 'debug',
|
|
105
|
-
message: text.loop.verificationOutputStored(verifyArtifact.handle),
|
|
106
|
-
timestamp: new Date(),
|
|
107
|
-
});
|
|
108
|
-
}
|
|
109
|
-
catch {
|
|
110
|
-
// Best-effort only; keep verifyResult.output in-memory for shrink/error classification.
|
|
111
|
-
}
|
|
97
|
+
if (verifyArtifact) {
|
|
98
|
+
ctx.emit({
|
|
99
|
+
type: 'log',
|
|
100
|
+
level: 'debug',
|
|
101
|
+
message: text.loop.verificationOutputStored(verifyArtifact.handle),
|
|
102
|
+
timestamp: new Date(),
|
|
103
|
+
});
|
|
112
104
|
}
|
|
113
105
|
// We don't throw here, because we want to trigger rollback/shrink in the pipeline
|
|
114
106
|
// But wait, the Pipeline abstraction propagates errors immediately.
|
|
@@ -34,6 +34,7 @@ export async function executeAiSdkChatRequest(input) {
|
|
|
34
34
|
options: input.options,
|
|
35
35
|
headers: attemptCtx.langfuseHeaders,
|
|
36
36
|
abortSignal: attemptCtx.abortSignal,
|
|
37
|
+
providerOptionsKey: input.providerOptionsKey,
|
|
37
38
|
}));
|
|
38
39
|
const usage = extractUsageFromAiSdkResult(result);
|
|
39
40
|
if (usage) {
|
|
@@ -74,6 +75,7 @@ export async function* executeAiSdkChatStreamRequest(input) {
|
|
|
74
75
|
options: input.options,
|
|
75
76
|
headers: attemptCtx.langfuseHeaders,
|
|
76
77
|
abortSignal: attemptCtx.abortSignal,
|
|
78
|
+
providerOptionsKey: input.providerOptionsKey,
|
|
77
79
|
}));
|
|
78
80
|
yield* mapAiSdkStreamResultToChunks(result.fullStream);
|
|
79
81
|
},
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { LIMITS } from '../../config/limits.js';
|
|
2
|
+
import { getPatchPrompt, getPlanPrompt } from '../../prompts/runtime.js';
|
|
3
|
+
import { wrapPlanEmpty, sanitizeError, LlmError } from '../errors.js';
|
|
4
|
+
import { extractUnifiedDiffFromLLMContent, parsePlanFromLLMContent } from '../utils.js';
|
|
5
|
+
export const HIGH_LEVEL_PHASE_NAMES = [
|
|
6
|
+
'plan',
|
|
7
|
+
'patch',
|
|
8
|
+
];
|
|
9
|
+
function buildContextPromptAttachment(contextPrompt) {
|
|
10
|
+
return {
|
|
11
|
+
key: 'context-prompt',
|
|
12
|
+
kind: 'context',
|
|
13
|
+
label: 'Context prompt',
|
|
14
|
+
content: contextPrompt,
|
|
15
|
+
cacheSafe: true,
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
function buildPatchAttachments(contextPrompt, planStr) {
|
|
19
|
+
return [
|
|
20
|
+
buildContextPromptAttachment(contextPrompt),
|
|
21
|
+
{
|
|
22
|
+
key: 'plan-json',
|
|
23
|
+
kind: 'plan',
|
|
24
|
+
label: 'Plan JSON',
|
|
25
|
+
content: planStr,
|
|
26
|
+
},
|
|
27
|
+
];
|
|
28
|
+
}
|
|
29
|
+
function parsePlanResult(content) {
|
|
30
|
+
if (!content) {
|
|
31
|
+
throw wrapPlanEmpty();
|
|
32
|
+
}
|
|
33
|
+
try {
|
|
34
|
+
return parsePlanFromLLMContent(content);
|
|
35
|
+
}
|
|
36
|
+
catch (e) {
|
|
37
|
+
throw new LlmError('LLM plan parsing failed', 'LLM_PLAN_INVALID_JSON', {
|
|
38
|
+
causeMessage: sanitizeError(e),
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
function parsePatchResult(content) {
|
|
43
|
+
return extractUnifiedDiffFromLLMContent(content ?? '');
|
|
44
|
+
}
|
|
45
|
+
export const HIGH_LEVEL_PHASE_SPECS = {
|
|
46
|
+
plan: {
|
|
47
|
+
name: 'plan',
|
|
48
|
+
namespace: 'plan',
|
|
49
|
+
observationName: 'PLAN:plan-json',
|
|
50
|
+
buildPrompt: async ({ contextPrompt, instruction, lastError }) => getPlanPrompt(contextPrompt, instruction, LIMITS.maxFilesChanged, lastError),
|
|
51
|
+
buildAttachments: ({ contextPrompt }) => [buildContextPromptAttachment(contextPrompt)],
|
|
52
|
+
parseResult: (content) => parsePlanResult(content),
|
|
53
|
+
},
|
|
54
|
+
patch: {
|
|
55
|
+
name: 'patch',
|
|
56
|
+
namespace: 'patch',
|
|
57
|
+
observationName: 'PATCH:unified-diff',
|
|
58
|
+
buildPrompt: async ({ planStr, contextPrompt, lastError }) => getPatchPrompt(planStr, contextPrompt, LIMITS.maxFilesChanged, LIMITS.maxDiffLines, lastError),
|
|
59
|
+
buildAttachments: ({ contextPrompt, planStr }) => buildPatchAttachments(contextPrompt, planStr),
|
|
60
|
+
parseResult: (content) => parsePatchResult(content),
|
|
61
|
+
},
|
|
62
|
+
};
|
|
63
|
+
//# sourceMappingURL=high-level-phase-specs.js.map
|