salmon-loop 0.2.13 → 0.3.0
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 +97 -77
- 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 +10 -5
- 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/backends/salmon-loop/task-executor.js +1 -0
- 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/merge.js +14 -0
- 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-program-bootstrap.js +1 -0
- 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 +4 -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/interaction/orchestration/facade.js +1 -1
- 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 +113 -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 +5 -3
- 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 +300 -58
- 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/mcp/client.js +2 -1
- 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/core/version.js +17 -0
- 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 +14 -7
- 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
package/dist/core/llm/utils.js
CHANGED
|
@@ -10,32 +10,22 @@ export function formatContextForPrompt(context, options = {}) {
|
|
|
10
10
|
}
|
|
11
11
|
return formatContextForXmlPrompt(context);
|
|
12
12
|
}
|
|
13
|
-
export function
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
try {
|
|
18
|
-
return JSON.parse(jsonBlockMatch[1]);
|
|
19
|
-
}
|
|
20
|
-
catch (__e) {
|
|
21
|
-
// Fallback to raw content if block is invalid
|
|
22
|
-
}
|
|
13
|
+
export function parsePlanFromLLMContent(content) {
|
|
14
|
+
const trimmed = String(content ?? '').trim();
|
|
15
|
+
if (!trimmed.startsWith('{') || !trimmed.endsWith('}')) {
|
|
16
|
+
throw new Error(text.llm.planInvalidJson);
|
|
23
17
|
}
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
try {
|
|
28
|
-
return JSON.parse(jsonMatch[0]);
|
|
29
|
-
}
|
|
30
|
-
catch (__e) {
|
|
31
|
-
// Fallback
|
|
32
|
-
}
|
|
18
|
+
let parsed;
|
|
19
|
+
try {
|
|
20
|
+
parsed = JSON.parse(trimmed);
|
|
33
21
|
}
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
|
|
22
|
+
catch {
|
|
23
|
+
throw new Error(text.llm.planInvalidJson);
|
|
24
|
+
}
|
|
25
|
+
if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
|
|
26
|
+
throw new Error(text.llm.planInvalidJson);
|
|
27
|
+
}
|
|
28
|
+
const plan = parsed;
|
|
39
29
|
if (!plan.goal || !Array.isArray(plan.files) || !Array.isArray(plan.changes) || !plan.verify) {
|
|
40
30
|
throw new Error(text.llm.planInvalid);
|
|
41
31
|
}
|
|
@@ -46,10 +36,9 @@ export function extractUnifiedDiffFromLLMContent(content) {
|
|
|
46
36
|
throw wrapPatchEmpty();
|
|
47
37
|
}
|
|
48
38
|
const looksLikeUnifiedDiff = (text) => {
|
|
49
|
-
return /^\s*
|
|
39
|
+
return /^\s*diff --git /m.test(text);
|
|
50
40
|
};
|
|
51
|
-
// 1) Prefer fenced code blocks and always pick the LAST diff
|
|
52
|
-
// Accept both git-style (`diff --git`) and minimal unified diffs (`--- a/...` + `+++ b/...`).
|
|
41
|
+
// 1) Prefer fenced code blocks and always pick the LAST canonical diff block (LLM may generate multiple attempts).
|
|
53
42
|
const fencedBlocks = [];
|
|
54
43
|
const fenceRegex = /```(?:diff)?\s*\n([\s\S]*?)\n```/gi;
|
|
55
44
|
let fenceMatch = null;
|
|
@@ -62,10 +51,10 @@ export function extractUnifiedDiffFromLLMContent(content) {
|
|
|
62
51
|
if (fencedBlocks.length > 0) {
|
|
63
52
|
return fencedBlocks[fencedBlocks.length - 1].trim();
|
|
64
53
|
}
|
|
65
|
-
// 2) Raw diff without markdown: keep the first diff
|
|
54
|
+
// 2) Raw diff without markdown: keep the first canonical diff section.
|
|
66
55
|
// In "pure diff" mode, LLMs typically return only the patch, so selecting the first marker
|
|
67
56
|
// avoids accidentally dropping the leading `diff --git` header.
|
|
68
|
-
const rawStart = content.search(/^\s*
|
|
57
|
+
const rawStart = content.search(/^\s*diff --git /m);
|
|
69
58
|
if (rawStart !== -1)
|
|
70
59
|
return content.slice(rawStart).trim();
|
|
71
60
|
// Final fallback: original simple cleanup
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import { extractKeywords } from '../context/keywords.js';
|
|
2
|
+
const DEFAULT_MAX_ITEMS = 3;
|
|
3
|
+
const DEFAULT_MAX_SUMMARY_CHARS = 220;
|
|
4
|
+
function trimToUndefined(value) {
|
|
5
|
+
if (typeof value !== 'string')
|
|
6
|
+
return undefined;
|
|
7
|
+
const trimmed = value.trim();
|
|
8
|
+
return trimmed ? trimmed : undefined;
|
|
9
|
+
}
|
|
10
|
+
function clampText(value, maxChars) {
|
|
11
|
+
if (value.length <= maxChars)
|
|
12
|
+
return value;
|
|
13
|
+
return `${value.slice(0, Math.max(0, maxChars - 1)).trimEnd()}…`;
|
|
14
|
+
}
|
|
15
|
+
function normalizeCandidate(candidate, maxSummaryChars) {
|
|
16
|
+
const path = trimToUndefined(candidate.path);
|
|
17
|
+
const title = trimToUndefined(candidate.title);
|
|
18
|
+
const summary = trimToUndefined(candidate.summary);
|
|
19
|
+
if (!path || !title || !summary)
|
|
20
|
+
return undefined;
|
|
21
|
+
const tags = Array.isArray(candidate.tags)
|
|
22
|
+
? candidate.tags
|
|
23
|
+
.map((tag) => trimToUndefined(tag)?.toLowerCase())
|
|
24
|
+
.filter((tag) => Boolean(tag))
|
|
25
|
+
: undefined;
|
|
26
|
+
return {
|
|
27
|
+
path,
|
|
28
|
+
title,
|
|
29
|
+
summary: clampText(summary, maxSummaryChars),
|
|
30
|
+
tags,
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
function buildAlreadySurfacedHaystack(values) {
|
|
34
|
+
return (values ?? []).join('\n').toLowerCase();
|
|
35
|
+
}
|
|
36
|
+
function hasToolConflict(candidate, activeToolNames) {
|
|
37
|
+
const toolTags = (candidate.tags ?? []).filter((tag) => tag.startsWith('tool:'));
|
|
38
|
+
if (toolTags.length === 0)
|
|
39
|
+
return false;
|
|
40
|
+
const active = new Set(activeToolNames.map((name) => name.trim().toLowerCase()).filter(Boolean));
|
|
41
|
+
if (active.size === 0)
|
|
42
|
+
return false;
|
|
43
|
+
return toolTags.some((tag) => active.has(tag.slice('tool:'.length)));
|
|
44
|
+
}
|
|
45
|
+
function computeCandidateScore(candidate, keywords) {
|
|
46
|
+
if (keywords.length === 0)
|
|
47
|
+
return 0;
|
|
48
|
+
const pathLower = candidate.path.toLowerCase();
|
|
49
|
+
const titleLower = candidate.title.toLowerCase();
|
|
50
|
+
const summaryLower = candidate.summary.toLowerCase();
|
|
51
|
+
const tagsLower = candidate.tags ?? [];
|
|
52
|
+
let score = 0;
|
|
53
|
+
for (const keyword of keywords) {
|
|
54
|
+
const normalized = keyword.trim().toLowerCase();
|
|
55
|
+
if (!normalized)
|
|
56
|
+
continue;
|
|
57
|
+
if (pathLower.includes(normalized))
|
|
58
|
+
score += 6;
|
|
59
|
+
if (titleLower.includes(normalized))
|
|
60
|
+
score += 5;
|
|
61
|
+
if (summaryLower.includes(normalized))
|
|
62
|
+
score += 4;
|
|
63
|
+
if (tagsLower.some((tag) => tag.includes(normalized)))
|
|
64
|
+
score += 3;
|
|
65
|
+
}
|
|
66
|
+
return score;
|
|
67
|
+
}
|
|
68
|
+
export function buildRelevantMemoryCandidates(context) {
|
|
69
|
+
const candidates = [];
|
|
70
|
+
const knowledge = context.knowledgeBase;
|
|
71
|
+
const metadata = context.projectMetadata;
|
|
72
|
+
if (Array.isArray(knowledge?.project_rules) && knowledge.project_rules.length > 0) {
|
|
73
|
+
candidates.push({
|
|
74
|
+
path: '.salmonloop/knowledge/project_rules',
|
|
75
|
+
title: 'Project rules',
|
|
76
|
+
summary: knowledge.project_rules.join('; '),
|
|
77
|
+
tags: ['rules', 'project'],
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
if (trimToUndefined(knowledge?.user_preferences)) {
|
|
81
|
+
candidates.push({
|
|
82
|
+
path: '.salmonloop/knowledge/user_preferences',
|
|
83
|
+
title: 'User preferences',
|
|
84
|
+
summary: knowledge.user_preferences,
|
|
85
|
+
tags: ['preferences', 'user'],
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
for (const [index, decision] of (knowledge?.architectural_decisions ?? []).entries()) {
|
|
89
|
+
const summary = trimToUndefined(decision?.decision);
|
|
90
|
+
if (!summary)
|
|
91
|
+
continue;
|
|
92
|
+
candidates.push({
|
|
93
|
+
path: `.salmonloop/knowledge/architectural_decisions/${index + 1}`,
|
|
94
|
+
title: `Architectural decision ${index + 1}`,
|
|
95
|
+
summary,
|
|
96
|
+
tags: ['architecture', ...(decision.related_files ?? []).map((file) => file.toLowerCase())],
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
if (trimToUndefined(metadata?.aiInstructions)) {
|
|
100
|
+
candidates.push({
|
|
101
|
+
path: '.salmonloop/project/ai-instructions',
|
|
102
|
+
title: 'Project AI instructions',
|
|
103
|
+
summary: metadata.aiInstructions,
|
|
104
|
+
tags: ['instructions', 'project'],
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
return candidates;
|
|
108
|
+
}
|
|
109
|
+
export function selectRelevantMemory(args) {
|
|
110
|
+
const maxItems = Math.max(1, Math.floor(args.maxItems ?? DEFAULT_MAX_ITEMS));
|
|
111
|
+
const maxSummaryChars = Math.max(48, Math.floor(args.maxSummaryChars ?? DEFAULT_MAX_SUMMARY_CHARS));
|
|
112
|
+
const haystack = buildAlreadySurfacedHaystack(args.alreadySurfacedText);
|
|
113
|
+
const activeToolNames = args.activeToolNames ?? [];
|
|
114
|
+
const keywords = extractKeywords(args.instruction ?? '');
|
|
115
|
+
const deduped = new Map();
|
|
116
|
+
for (const rawCandidate of args.candidates) {
|
|
117
|
+
const candidate = normalizeCandidate(rawCandidate, maxSummaryChars);
|
|
118
|
+
if (!candidate)
|
|
119
|
+
continue;
|
|
120
|
+
if (deduped.has(candidate.path))
|
|
121
|
+
continue;
|
|
122
|
+
if (haystack.includes(candidate.path.toLowerCase()) ||
|
|
123
|
+
haystack.includes(candidate.title.toLowerCase()) ||
|
|
124
|
+
haystack.includes(candidate.summary.toLowerCase())) {
|
|
125
|
+
continue;
|
|
126
|
+
}
|
|
127
|
+
if (hasToolConflict(candidate, activeToolNames))
|
|
128
|
+
continue;
|
|
129
|
+
deduped.set(candidate.path, candidate);
|
|
130
|
+
}
|
|
131
|
+
const scored = [...deduped.values()].map((candidate) => ({
|
|
132
|
+
candidate,
|
|
133
|
+
score: computeCandidateScore(candidate, keywords),
|
|
134
|
+
}));
|
|
135
|
+
const ranked = scored
|
|
136
|
+
.filter((entry) => entry.score > 0 || keywords.length === 0)
|
|
137
|
+
.sort((left, right) => {
|
|
138
|
+
if (left.score !== right.score)
|
|
139
|
+
return right.score - left.score;
|
|
140
|
+
return left.candidate.path.localeCompare(right.candidate.path);
|
|
141
|
+
});
|
|
142
|
+
return ranked.slice(0, maxItems).map((entry) => entry.candidate);
|
|
143
|
+
}
|
|
144
|
+
//# sourceMappingURL=relevant-retrieval.js.map
|
|
@@ -3,6 +3,17 @@ import { FileAdapter } from '../adapters/fs/index.js';
|
|
|
3
3
|
import { sanitizeObject, sanitizeErrorMessage } from '../utils/sanitizer.js';
|
|
4
4
|
import { recordAuditEvent } from './audit-trail.js';
|
|
5
5
|
import { mapErrorForDisplay } from './error-mapping.js';
|
|
6
|
+
/**
|
|
7
|
+
* Reporter for machine-readable modes where stdout/stderr are protocol channels.
|
|
8
|
+
*/
|
|
9
|
+
export class SilentReporter {
|
|
10
|
+
log(_level, _message, _metadata) {
|
|
11
|
+
// Intentionally empty.
|
|
12
|
+
}
|
|
13
|
+
clear() {
|
|
14
|
+
// Intentionally empty.
|
|
15
|
+
}
|
|
16
|
+
}
|
|
6
17
|
/**
|
|
7
18
|
* Standard Console Reporter
|
|
8
19
|
*/
|
|
@@ -418,8 +429,6 @@ export class Logger {
|
|
|
418
429
|
const auditMeta = typeof meta === 'string' ? { source: meta } : meta;
|
|
419
430
|
recordAuditEvent(action, sanitizedDetails, auditMeta);
|
|
420
431
|
this.writeToLog('audit', formatted);
|
|
421
|
-
if (!this.silent)
|
|
422
|
-
this.reporter.log('audit', formatted);
|
|
423
432
|
}
|
|
424
433
|
sanitizeLogMessage(message) {
|
|
425
434
|
let result = '';
|
package/dist/core/patch/diff.js
CHANGED
|
@@ -10,9 +10,14 @@ const TEMPLATE_URLS = {
|
|
|
10
10
|
'system/plan_system.hbs': new URL('./templates/system/plan_system.hbs', import.meta.url),
|
|
11
11
|
'system/reflection.hbs': new URL('./templates/system/reflection.hbs', import.meta.url),
|
|
12
12
|
'system/patch_system.hbs': new URL('./templates/system/patch_system.hbs', import.meta.url),
|
|
13
|
+
'system/autopilot_system.hbs': new URL('./templates/system/autopilot_system.hbs', import.meta.url),
|
|
14
|
+
'system/answer_system.hbs': new URL('./templates/system/answer_system.hbs', import.meta.url),
|
|
15
|
+
'system/research_system.hbs': new URL('./templates/system/research_system.hbs', import.meta.url),
|
|
13
16
|
'phases/explore_user.hbs': new URL('./templates/phases/explore_user.hbs', import.meta.url),
|
|
14
17
|
'phases/plan_user.hbs': new URL('./templates/phases/plan_user.hbs', import.meta.url),
|
|
15
18
|
'phases/patch_user.hbs': new URL('./templates/phases/patch_user.hbs', import.meta.url),
|
|
19
|
+
'phases/research_user.hbs': new URL('./templates/phases/research_user.hbs', import.meta.url),
|
|
20
|
+
'phases/review_user.hbs': new URL('./templates/phases/review_user.hbs', import.meta.url),
|
|
16
21
|
};
|
|
17
22
|
export class PromptRegistry {
|
|
18
23
|
templates = new Map();
|
|
@@ -30,10 +35,15 @@ export class PromptRegistry {
|
|
|
30
35
|
await this.loadTemplate('explore_system', 'system/explore_system.hbs');
|
|
31
36
|
await this.loadTemplate('plan_system', 'system/plan_system.hbs');
|
|
32
37
|
await this.loadTemplate('patch_system', 'system/patch_system.hbs');
|
|
38
|
+
await this.loadTemplate('autopilot_system', 'system/autopilot_system.hbs');
|
|
39
|
+
await this.loadTemplate('answer_system', 'system/answer_system.hbs');
|
|
40
|
+
await this.loadTemplate('research_system', 'system/research_system.hbs');
|
|
33
41
|
await this.loadTemplate('reflection', 'system/reflection.hbs');
|
|
34
42
|
await this.loadTemplate('explore', 'phases/explore_user.hbs');
|
|
35
43
|
await this.loadTemplate('plan', 'phases/plan_user.hbs');
|
|
36
44
|
await this.loadTemplate('patch', 'phases/patch_user.hbs');
|
|
45
|
+
await this.loadTemplate('research', 'phases/research_user.hbs');
|
|
46
|
+
await this.loadTemplate('review', 'phases/review_user.hbs');
|
|
37
47
|
})();
|
|
38
48
|
return this.initPromise;
|
|
39
49
|
}
|
|
@@ -73,8 +83,8 @@ export class PromptRegistry {
|
|
|
73
83
|
/**
|
|
74
84
|
* Get serializable tool definitions for template rendering
|
|
75
85
|
*/
|
|
76
|
-
|
|
77
|
-
return
|
|
86
|
+
serializeToolsForTemplate(tools) {
|
|
87
|
+
return tools.map((spec) => ({
|
|
78
88
|
name: spec.name,
|
|
79
89
|
source: spec.source,
|
|
80
90
|
intent: spec.intent,
|
|
@@ -90,6 +100,12 @@ export class PromptRegistry {
|
|
|
90
100
|
examples: spec.examples,
|
|
91
101
|
}));
|
|
92
102
|
}
|
|
103
|
+
/**
|
|
104
|
+
* Get serializable tool definitions for template rendering
|
|
105
|
+
*/
|
|
106
|
+
getToolsForTemplate(tools = this.tools) {
|
|
107
|
+
return this.serializeToolsForTemplate(tools);
|
|
108
|
+
}
|
|
93
109
|
/**
|
|
94
110
|
* Convert Zod schema to a JSON Schema representation
|
|
95
111
|
*/
|
|
@@ -142,15 +158,30 @@ export class PromptRegistry {
|
|
|
142
158
|
renderPlanSystemWithRuntime(runtime) {
|
|
143
159
|
return this.render('plan_system', { tools: this.getToolsForTemplate(), runtime });
|
|
144
160
|
}
|
|
161
|
+
renderPlanSystemWithTools(tools, runtime) {
|
|
162
|
+
return this.render('plan_system', { tools: this.getToolsForTemplate(tools), runtime });
|
|
163
|
+
}
|
|
145
164
|
renderPatchSystem() {
|
|
146
165
|
return this.render('patch_system', { tools: this.getToolsForTemplate() });
|
|
147
166
|
}
|
|
148
167
|
renderPatchSystemWithRuntime(runtime) {
|
|
149
168
|
return this.render('patch_system', { tools: this.getToolsForTemplate(), runtime });
|
|
150
169
|
}
|
|
170
|
+
renderPatchSystemWithTools(tools, runtime) {
|
|
171
|
+
return this.render('patch_system', { tools: this.getToolsForTemplate(tools), runtime });
|
|
172
|
+
}
|
|
151
173
|
renderExploreSystem() {
|
|
152
174
|
return this.render('explore_system', { tools: this.getToolsForTemplate() });
|
|
153
175
|
}
|
|
176
|
+
renderAutopilotSystem() {
|
|
177
|
+
return this.render('autopilot_system', {});
|
|
178
|
+
}
|
|
179
|
+
renderAnswerSystem() {
|
|
180
|
+
return this.render('answer_system', {});
|
|
181
|
+
}
|
|
182
|
+
renderResearchSystem() {
|
|
183
|
+
return this.render('research_system', {});
|
|
184
|
+
}
|
|
154
185
|
renderExploreSystemWithRuntime(runtime) {
|
|
155
186
|
return this.render('explore_system', { tools: this.getToolsForTemplate(), runtime });
|
|
156
187
|
}
|
|
@@ -163,6 +194,12 @@ export class PromptRegistry {
|
|
|
163
194
|
renderPatch(vars) {
|
|
164
195
|
return this.render('patch', vars);
|
|
165
196
|
}
|
|
197
|
+
renderResearch(vars) {
|
|
198
|
+
return this.render('research', vars);
|
|
199
|
+
}
|
|
200
|
+
renderReview(vars) {
|
|
201
|
+
return this.render('review', vars);
|
|
202
|
+
}
|
|
166
203
|
renderReflection(vars) {
|
|
167
204
|
return this.render('reflection', vars);
|
|
168
205
|
}
|
|
@@ -1,4 +1,13 @@
|
|
|
1
|
+
import { resolvePhaseVisibleTools } from '../tools/tool-visibility.js';
|
|
2
|
+
import { Phase } from '../types/runtime.js';
|
|
1
3
|
import { getPromptRegistry } from './registry.js';
|
|
4
|
+
function resolveToolSpecs(toolRegistry) {
|
|
5
|
+
if (!toolRegistry)
|
|
6
|
+
return [];
|
|
7
|
+
if (Array.isArray(toolRegistry))
|
|
8
|
+
return toolRegistry;
|
|
9
|
+
return toolRegistry.listAll();
|
|
10
|
+
}
|
|
2
11
|
function extractTargetFiles(plan) {
|
|
3
12
|
try {
|
|
4
13
|
const parsed = JSON.parse(plan);
|
|
@@ -20,14 +29,26 @@ export async function getExplorePrompt(context, instruction, lastError) {
|
|
|
20
29
|
lastError,
|
|
21
30
|
});
|
|
22
31
|
}
|
|
23
|
-
export async function getExploreSystemPrompt(
|
|
32
|
+
export async function getExploreSystemPrompt(runtime) {
|
|
24
33
|
const promptRegistry = getPromptRegistry();
|
|
25
34
|
await promptRegistry.init();
|
|
26
|
-
if (toolRegistry) {
|
|
27
|
-
promptRegistry.setTools(toolRegistry.listAll());
|
|
28
|
-
}
|
|
29
35
|
return promptRegistry.renderExploreSystemWithRuntime(runtime);
|
|
30
36
|
}
|
|
37
|
+
export async function getAutopilotSystemPrompt() {
|
|
38
|
+
const promptRegistry = getPromptRegistry();
|
|
39
|
+
await promptRegistry.init();
|
|
40
|
+
return promptRegistry.renderAutopilotSystem();
|
|
41
|
+
}
|
|
42
|
+
export async function getAnswerSystemPrompt() {
|
|
43
|
+
const promptRegistry = getPromptRegistry();
|
|
44
|
+
await promptRegistry.init();
|
|
45
|
+
return promptRegistry.renderAnswerSystem();
|
|
46
|
+
}
|
|
47
|
+
export async function getResearchSystemPrompt() {
|
|
48
|
+
const promptRegistry = getPromptRegistry();
|
|
49
|
+
await promptRegistry.init();
|
|
50
|
+
return promptRegistry.renderResearchSystem();
|
|
51
|
+
}
|
|
31
52
|
export async function getPlanPrompt(context, instruction, maxFilesChanged, lastError) {
|
|
32
53
|
const promptRegistry = getPromptRegistry();
|
|
33
54
|
await promptRegistry.init();
|
|
@@ -50,20 +71,37 @@ export async function getPatchPrompt(plan, context, maxFilesChanged, maxDiffLine
|
|
|
50
71
|
lastError,
|
|
51
72
|
});
|
|
52
73
|
}
|
|
74
|
+
export async function getResearchPrompt(context, instruction) {
|
|
75
|
+
const promptRegistry = getPromptRegistry();
|
|
76
|
+
await promptRegistry.init();
|
|
77
|
+
return promptRegistry.renderResearch({
|
|
78
|
+
context,
|
|
79
|
+
instruction,
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
export async function getReviewPrompt(contextJson) {
|
|
83
|
+
const promptRegistry = getPromptRegistry();
|
|
84
|
+
await promptRegistry.init();
|
|
85
|
+
return promptRegistry.renderReview({ contextJson });
|
|
86
|
+
}
|
|
53
87
|
export async function getPlanSystemPrompt(toolRegistry, runtime) {
|
|
54
88
|
const promptRegistry = getPromptRegistry();
|
|
55
89
|
await promptRegistry.init();
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
90
|
+
const promptVisibleTools = resolvePhaseVisibleTools({
|
|
91
|
+
phase: Phase.PLAN,
|
|
92
|
+
tools: resolveToolSpecs(toolRegistry),
|
|
93
|
+
runtime,
|
|
94
|
+
});
|
|
95
|
+
return promptRegistry.renderPlanSystemWithTools(promptVisibleTools, runtime);
|
|
60
96
|
}
|
|
61
97
|
export async function getPatchSystemPrompt(toolRegistry, runtime) {
|
|
62
98
|
const promptRegistry = getPromptRegistry();
|
|
63
99
|
await promptRegistry.init();
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
100
|
+
const promptVisibleTools = resolvePhaseVisibleTools({
|
|
101
|
+
phase: Phase.PATCH,
|
|
102
|
+
tools: resolveToolSpecs(toolRegistry),
|
|
103
|
+
runtime,
|
|
104
|
+
});
|
|
105
|
+
return promptRegistry.renderPatchSystemWithTools(promptVisibleTools, runtime);
|
|
68
106
|
}
|
|
69
107
|
//# sourceMappingURL=runtime.js.map
|
|
@@ -34,7 +34,7 @@ The previous attempt failed with the following error. Please fix the issue descr
|
|
|
34
34
|
1. **Format**: Is it standard git unified diff (starting with `diff --git`)?
|
|
35
35
|
2. **Paths**: Do `--- a/path` and `+++ b/path` exactly match target files?
|
|
36
36
|
3. **Scope**: Does it only modify what's requested in the instruction?
|
|
37
|
-
4. **Context**: Are there
|
|
37
|
+
4. **Context**: Are there enough exact context lines for each hunk to apply cleanly?
|
|
38
38
|
5. **Cleanliness**: Is there ANY text other than the diff itself? (If yes, remove it).
|
|
39
39
|
|
|
40
40
|
# Requirements
|
|
@@ -43,13 +43,10 @@ The previous attempt failed with the following error. Please fix the issue descr
|
|
|
43
43
|
- **If you need to fix an error, regenerate the ENTIRE diff correctly in one block.**
|
|
44
44
|
- **CRITICAL**: Use EXACT relative paths from the repository root in diff headers.
|
|
45
45
|
- Example: `--- a/src/index.js` and `+++ b/src/index.js`
|
|
46
|
-
- **Context Matching**: Provide
|
|
47
|
-
- Indentation and whitespace must match EXACTLY.
|
|
48
|
-
- **DO NOT include `index <old>..<new>` lines** (the host may strip them for safety).
|
|
46
|
+
- **Context Matching**: Provide exact context lines; indentation and whitespace must match EXACTLY.
|
|
49
47
|
- Constraints:
|
|
50
48
|
- Maximum {{maxFilesChanged}} files.
|
|
51
49
|
- Maximum {{maxDiffLines}} total diff lines.
|
|
52
|
-
- No file creation, deletion, or renaming.
|
|
53
50
|
- No unrelated refactoring or formatting.
|
|
54
51
|
- **DO NOT translate or modify comments unless explicitly instructed.**
|
|
55
52
|
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
You are running in deep research mode.
|
|
2
|
+
Use available tools to gather external information as needed.
|
|
3
|
+
Return JSON with keys: researchNotes, researchFindings, sources, researchText.
|
|
4
|
+
Each researchFinding should include: summary, confidence (0-1), uncertainty (string).
|
|
5
|
+
Each source should include: toolName, summary, ok, timestamp (epoch ms).
|
|
6
|
+
|
|
7
|
+
Instruction:
|
|
8
|
+
{{{instruction}}}
|
|
9
|
+
|
|
10
|
+
Context:
|
|
11
|
+
{{{context}}}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
You are a coding assistant in "answer" mode.
|
|
2
|
+
You may use read-only tools to inspect the repository when helpful.
|
|
3
|
+
Never write files, never apply patches, and never run shell commands.
|
|
4
|
+
If repository inspection is not required, answer directly without tools.
|
|
5
|
+
Answer in the same language as the user.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
You are a coding assistant running in "autopilot" mode.
|
|
2
|
+
Drive the task forward autonomously and answer in the same language as the user.
|
|
3
|
+
Use the repository context available in the current turn when present.
|
|
4
|
+
If no repository action is possible yet, explain the next best action succinctly.
|
|
5
|
+
Prefer taking a reasonable repository action over asking the user for confirmation.
|
|
6
|
+
Treat simple repo-relative paths like "smoke.txt", "README.md", or "src/index.ts" as valid paths from the repository root.
|
|
7
|
+
Do not ask the user to validate a path that is already a valid relative path or can be inferred directly from the instruction.
|
|
8
|
+
Use `interaction.ask_user` only when the task is genuinely ambiguous and you cannot safely infer the next action.
|
|
9
|
+
When calling `interaction.ask_user`, the arguments MUST be valid JSON with exactly this shape: {"questions":[{"header":"Short header","question":"One clear question","options":[{"label":"Option 1","description":"Why pick it"},{"label":"Option 2","description":"Why pick it"}],"multiSelect":false}]}.
|
|
10
|
+
Do not call `interaction.ask_user` with free-form strings, a single question field, string-only options, or empty options arrays.
|
|
11
|
+
For simple file creation or edits, call `fs.write_file` directly with {"file":"relative/path.ext","content":"..."} instead of asking the user for the path again.
|
|
@@ -1,26 +1,17 @@
|
|
|
1
|
-
|
|
1
|
+
You are in EXPLORE. Find the files relevant to the user's request and read them before planning. Do not modify files.
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
- You can list directories (`fs.list`), search code (`code.search`), and read files (`fs.read`).
|
|
5
|
-
- You can ask the user a short clarification question (`interaction.ask_user`) when the request is ambiguous.
|
|
6
|
-
- You CANNOT modify files. Your role is purely investigative.
|
|
3
|
+
Use only these exact tool names in EXPLORE: `fs.list`, `code.search`, `fs.read`, `interaction.ask_user`.
|
|
7
4
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
3. Use `fs.read` to examine the content of promising files.
|
|
13
|
-
4. Continue exploring until you are confident you have identified the files that need to be modified.
|
|
14
|
-
5. When you have found the relevant context, reply with a concise summary of your findings to complete the phase.
|
|
5
|
+
Default sequence:
|
|
6
|
+
- If the user gives a file path, call `fs.read` first using `{"file":"path/to/file"}`.
|
|
7
|
+
- Otherwise, use `code.search` with `{"pattern":"keyword"}` or `fs.list` with `{"path":"."}` to find a plausible file, then call `fs.read` on it as soon as possible.
|
|
8
|
+
- Use `interaction.ask_user` only if the request is too ambiguous to choose a reasonable first file or search target.
|
|
15
9
|
|
|
16
|
-
|
|
17
|
-
-
|
|
18
|
-
-
|
|
19
|
-
-
|
|
20
|
-
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
- Be efficient. Do not read the entire codebase.
|
|
25
|
-
- If the user provides specific file paths, read them first.
|
|
26
|
-
"}}
|
|
10
|
+
Rules:
|
|
11
|
+
- Do not finish EXPLORE until at least one `fs.read` call succeeds.
|
|
12
|
+
- Do not mention a file as relevant unless you have read it with `fs.read`.
|
|
13
|
+
- Do not guess file contents.
|
|
14
|
+
- Use valid JSON arguments only.
|
|
15
|
+
- Be efficient: prefer short list/search/read loops over broad exploration.
|
|
16
|
+
|
|
17
|
+
When you have enough read-backed context, reply with a concise summary of the files you read and why they matter.
|
|
@@ -1,18 +1,6 @@
|
|
|
1
|
-
You are SalmonLoop.
|
|
1
|
+
You are SalmonLoop.
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
Path hint: {{runtime.plan.planPathHint}}
|
|
7
|
-
|
|
8
|
-
Guidelines:
|
|
9
|
-
- Use `plan.read` to obtain `baseHash`.
|
|
10
|
-
- Use `plan.update` with this `sessionId` to update plan steps by stable `sl:id`.
|
|
11
|
-
- Prefer appending tasks under `work_root` and tracking progress via `sl:status` and checkboxes.
|
|
12
|
-
- Keep phase outputs strictly compliant (PLAN must still be pure JSON, PATCH must still be a unified diff). Tool calls are allowed, but your final content must remain valid.
|
|
3
|
+
Primary text is authoritative. Do not guess missing file contents. If required content is missing, use the available read-only tools to fetch it before finalizing.
|
|
4
|
+
{{#if phaseInstruction}}
|
|
5
|
+
{{phaseInstruction}}
|
|
13
6
|
{{/if}}
|
|
14
|
-
|
|
15
|
-
## Knowledge Retention
|
|
16
|
-
You have access to a cross-session knowledge base. When you learn important project-specific rules, long-term architectural decisions, or user preferences, use the `update_knowledge` tool to persist them. This helps you stay consistent in future sessions.
|
|
17
|
-
|
|
18
|
-
{{> tool_defs}}
|
|
@@ -1,10 +1,41 @@
|
|
|
1
|
-
|
|
1
|
+
You are PATCH, a phase-native diff compiler. Produce only a canonical unified diff document.
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
-
|
|
6
|
-
-
|
|
7
|
-
-
|
|
8
|
-
|
|
3
|
+
Output contract:
|
|
4
|
+
- The very first line must be `diff --git a/... b/...`.
|
|
5
|
+
- The document may contain multiple file sections.
|
|
6
|
+
- Each file section must use `--- a/...` and `+++ b/...`.
|
|
7
|
+
- For file add/delete, use `--- /dev/null` or `+++ /dev/null` as appropriate.
|
|
8
|
+
- An `index` line is optional and not required.
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
Tooling rules:
|
|
11
|
+
- Default tool set is read-only and minimal: `fs.read`, `code.search`.
|
|
12
|
+
- Use tools only when necessary to read plan-relevant files.
|
|
13
|
+
- Any further context lookups must remain read-only and target plan-relevant files.
|
|
14
|
+
- Never call or mention write tools.
|
|
15
|
+
|
|
16
|
+
{{> tool_defs}}
|
|
17
|
+
|
|
18
|
+
Fidelity rule:
|
|
19
|
+
- Context lines (lines starting with a single space) must match the source text exactly, byte-for-byte.
|
|
20
|
+
|
|
21
|
+
Strict bans (do not output any of these):
|
|
22
|
+
- Prose, explanations, or commentary.
|
|
23
|
+
- Markdown fences or code blocks.
|
|
24
|
+
- JSON or other structured wrappers.
|
|
25
|
+
- Multiple alternatives or options.
|
|
26
|
+
- Tool calls, tool schemas, or tool instructions.
|
|
27
|
+
|
|
28
|
+
LEGAL EXAMPLE (verbatim):
|
|
29
|
+
diff --git a/README.md b/README.md
|
|
30
|
+
--- a/README.md
|
|
31
|
+
+++ b/README.md
|
|
32
|
+
@@ -1 +1 @@
|
|
33
|
+
-Hello
|
|
34
|
+
+Hello world
|
|
35
|
+
|
|
36
|
+
ILLEGAL PATTERNS (each is invalid):
|
|
37
|
+
Here is the diff:
|
|
38
|
+
Fenced diff blocks that start with triple backticks.
|
|
39
|
+
{"diff":"diff --git a/x b/x"}
|
|
40
|
+
Option A: diff --git a/x b/x
|
|
41
|
+
Tool calls, tool schemas, or tool instructions.
|