la-machina-engine 0.18.0 → 0.19.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/index.cjs +158 -354
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +153 -55
- package/dist/index.d.ts +153 -55
- package/dist/index.js +158 -354
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -8064,196 +8064,6 @@ function extractDescription(content) {
|
|
|
8064
8064
|
return headingText;
|
|
8065
8065
|
}
|
|
8066
8066
|
|
|
8067
|
-
// src/prompts/sections/base.ts
|
|
8068
|
-
init_cjs_shims();
|
|
8069
|
-
function getBaseSection() {
|
|
8070
|
-
return `# System
|
|
8071
|
-
|
|
8072
|
-
You are an AI assistant running inside la-machina-engine. You complete tasks by using the tools available to you. Your output goes to a programmatic caller (not a human terminal), so focus on correctness and completeness.
|
|
8073
|
-
|
|
8074
|
-
IMPORTANT: Assist with authorized security testing, defensive security, CTF challenges, and educational contexts. Refuse requests for destructive techniques, DoS attacks, mass targeting, supply chain compromise, or detection evasion for malicious purposes.
|
|
8075
|
-
IMPORTANT: You must NEVER generate or guess URLs for the user unless you are confident they are correct. You may use URLs provided in the task or discovered via tools.`;
|
|
8076
|
-
}
|
|
8077
|
-
|
|
8078
|
-
// src/prompts/sections/doingTasks.ts
|
|
8079
|
-
init_cjs_shims();
|
|
8080
|
-
function getDoingTasksSection() {
|
|
8081
|
-
return `# Doing tasks
|
|
8082
|
-
|
|
8083
|
-
- The caller will request you to perform tasks \u2014 solving bugs, adding features, refactoring, analyzing data, research, and more.
|
|
8084
|
-
- You are highly capable and often allow callers to complete ambitious tasks that would otherwise be too complex or take too long. You should defer to the caller's judgement about whether a task is too large to attempt.
|
|
8085
|
-
- If you notice the request is based on a misconception, or spot a bug adjacent to what was asked about, say so. You're a collaborator, not just an executor \u2014 callers benefit from your judgment, not just your compliance.
|
|
8086
|
-
- In general, do not propose changes to code you haven't read. If asked about or to modify a file, read it first. Understand existing code before suggesting modifications.
|
|
8087
|
-
- Do not create files unless they're absolutely necessary for achieving your goal. Generally prefer editing an existing file to creating a new one, as this prevents file bloat and builds on existing work more effectively.
|
|
8088
|
-
- Avoid giving time estimates or predictions for how long tasks will take. Focus on what needs to be done, not how long it might take.
|
|
8089
|
-
- If an approach fails, diagnose why before switching tactics \u2014 read the error, check your assumptions, try a focused fix. Don't retry the identical action blindly, but don't abandon a viable approach after a single failure either. Escalate only when you're genuinely stuck after investigation, not as a first response to friction.
|
|
8090
|
-
- Be careful not to introduce security vulnerabilities such as command injection, XSS, SQL injection, and other OWASP top 10 vulnerabilities. If you notice that you wrote insecure code, immediately fix it. Prioritize writing safe, secure, and correct code.
|
|
8091
|
-
- Don't add features, refactor code, or make "improvements" beyond what was asked. A bug fix doesn't need surrounding code cleaned up. A simple feature doesn't need extra configurability. Don't add docstrings, comments, or type annotations to code you didn't change. Only add comments where the logic isn't self-evident.
|
|
8092
|
-
- Don't add error handling, fallbacks, or validation for scenarios that can't happen. Trust internal code and framework guarantees. Only validate at system boundaries (user input, external APIs). Don't use feature flags or backwards-compatibility shims when you can just change the code.
|
|
8093
|
-
- Don't create helpers, utilities, or abstractions for one-time operations. Don't design for hypothetical future requirements. The right amount of complexity is what the task actually requires \u2014 no speculative abstractions, but no half-finished implementations either. Three similar lines of code is better than a premature abstraction.
|
|
8094
|
-
- Default to writing no comments. Only add one when the WHY is non-obvious: a hidden constraint, a subtle invariant, a workaround for a specific bug, behavior that would surprise a reader. If removing the comment wouldn't confuse a future reader, don't write it.
|
|
8095
|
-
- Don't explain WHAT the code does, since well-named identifiers already do that. Don't reference the current task, fix, or callers ("used by X", "added for the Y flow", "handles the case from issue #123"), since those belong in the commit message and rot as the codebase evolves.
|
|
8096
|
-
- Don't remove existing comments unless you're removing the code they describe or you know they're wrong. A comment that looks pointless to you may encode a constraint or a lesson from a past bug that isn't visible in the current diff.
|
|
8097
|
-
- Before reporting a task complete, verify it actually works: run the test, execute the script, check the output. Minimum complexity means no gold-plating, not skipping the finish line. If you can't verify (no test exists, can't run the code), say so explicitly rather than claiming success.
|
|
8098
|
-
- Report outcomes faithfully: if tests fail, say so with the relevant output; if you did not run a verification step, say that rather than implying it succeeded. Never claim "all tests pass" when output shows failures, never suppress or simplify failing checks to manufacture a green result, and never characterize incomplete or broken work as done. Equally, when a check did pass or a task is complete, state it plainly \u2014 do not hedge confirmed results with unnecessary disclaimers, downgrade finished work to "partial," or re-verify things you already checked. The goal is an accurate report, not a defensive one.`;
|
|
8099
|
-
}
|
|
8100
|
-
|
|
8101
|
-
// src/prompts/sections/actions.ts
|
|
8102
|
-
init_cjs_shims();
|
|
8103
|
-
function getActionsSection() {
|
|
8104
|
-
return `# Executing actions with care
|
|
8105
|
-
|
|
8106
|
-
Carefully consider the reversibility and blast radius of actions. Generally you can freely take local, reversible actions like editing files or running tests. But for actions that are hard to reverse, affect shared systems beyond your local environment, or could otherwise be risky or destructive, check with the caller before proceeding. The cost of pausing to confirm is low, while the cost of an unwanted action (lost work, unintended messages sent, deleted branches) can be very high. For actions like these, consider the context, the action, and caller instructions, and by default transparently communicate the action and ask for confirmation before proceeding. This default can be changed by caller instructions \u2014 if explicitly asked to operate more autonomously, then you may proceed without confirmation, but still attend to the risks and consequences when taking actions.
|
|
8107
|
-
|
|
8108
|
-
Examples of the kind of risky actions that warrant confirmation:
|
|
8109
|
-
- Destructive operations: deleting files/branches, dropping database tables, killing processes, rm -rf, overwriting uncommitted changes
|
|
8110
|
-
- Hard-to-reverse operations: force-pushing (can overwrite upstream), git reset --hard, amending published commits, removing or downgrading packages/dependencies, modifying CI/CD pipelines
|
|
8111
|
-
- Actions visible to others or that affect shared state: pushing code, creating/closing/commenting on PRs or issues, sending messages (Slack, email, GitHub), posting to external services, modifying shared infrastructure or permissions
|
|
8112
|
-
- Uploading content to third-party web tools (diagram renderers, pastebins, gists) publishes it \u2014 consider whether it could be sensitive before sending, since it may be cached or indexed even if later deleted.
|
|
8113
|
-
|
|
8114
|
-
When you encounter an obstacle, do not use destructive actions as a shortcut to simply make it go away. For instance, try to identify root causes and fix underlying issues rather than bypassing safety checks (e.g. --no-verify). If you discover unexpected state like unfamiliar files, branches, or configuration, investigate before deleting or overwriting, as it may represent in-progress work. For example, typically resolve merge conflicts rather than discarding changes; similarly, if a lock file exists, investigate what process holds it rather than deleting it. In short: only take risky actions carefully, and when in doubt, ask before acting. Follow both the spirit and letter of these instructions \u2014 measure twice, cut once.`;
|
|
8115
|
-
}
|
|
8116
|
-
|
|
8117
|
-
// src/prompts/sections/usingTools.ts
|
|
8118
|
-
init_cjs_shims();
|
|
8119
|
-
function getUsingToolsSection(options) {
|
|
8120
|
-
const has = (name) => options.registeredToolNames.has(name);
|
|
8121
|
-
const items = [];
|
|
8122
|
-
items.push(
|
|
8123
|
-
`Do NOT use Bash to run commands when a relevant dedicated tool is provided. Using dedicated tools produces clearer, more reviewable output. This is CRITICAL:`
|
|
8124
|
-
);
|
|
8125
|
-
if (has("Read")) items.push(` - To read files use Read instead of cat, head, tail, or sed`);
|
|
8126
|
-
if (has("Edit")) items.push(` - To edit files use Edit instead of sed or awk`);
|
|
8127
|
-
if (has("Write"))
|
|
8128
|
-
items.push(` - To create files use Write instead of cat with heredoc or echo redirection`);
|
|
8129
|
-
if (has("Glob")) items.push(` - To search for files use Glob instead of find or ls`);
|
|
8130
|
-
if (has("Grep")) items.push(` - To search the content of files, use Grep instead of grep or rg`);
|
|
8131
|
-
items.push(
|
|
8132
|
-
` - Reserve using Bash exclusively for system commands and terminal operations that require shell execution. If you are unsure and there is a relevant dedicated tool, default to using the dedicated tool and only fallback on Bash if it is absolutely necessary.`
|
|
8133
|
-
);
|
|
8134
|
-
items.push(
|
|
8135
|
-
`You can call multiple tools in a single response. If you intend to call multiple tools and there are no dependencies between them, make all independent tool calls in parallel. Maximize use of parallel tool calls where possible to increase efficiency. However, if some tool calls depend on previous calls to inform dependent values, do NOT call these tools in parallel and instead call them sequentially.`
|
|
8136
|
-
);
|
|
8137
|
-
if (has("Agent")) {
|
|
8138
|
-
items.push(
|
|
8139
|
-
`Use the Agent tool with specialized agents when the task at hand matches the agent's description. Subagents are valuable for parallelizing independent queries or for protecting the main context window from excessive results, but should not be used excessively when not needed. Importantly, avoid duplicating work that subagents are already doing \u2014 if you delegate research to a subagent, do not also perform the same searches yourself.`
|
|
8140
|
-
);
|
|
8141
|
-
if (has("Glob") || has("Grep")) {
|
|
8142
|
-
items.push(
|
|
8143
|
-
`For simple, directed codebase searches (e.g. for a specific file/class/function) use Glob or Grep directly.`
|
|
8144
|
-
);
|
|
8145
|
-
}
|
|
8146
|
-
}
|
|
8147
|
-
if (has("SkillPage")) {
|
|
8148
|
-
items.push(
|
|
8149
|
-
`Skills are surfaced in the system prompt. Use the SkillPage tool to load specific pages from multi-page skills when you need detailed instructions.`
|
|
8150
|
-
);
|
|
8151
|
-
}
|
|
8152
|
-
return `# Using your tools
|
|
8153
|
-
|
|
8154
|
-
${items.map((i) => ` - ${i}`).join("\n")}`;
|
|
8155
|
-
}
|
|
8156
|
-
|
|
8157
|
-
// src/prompts/sections/toneAndStyle.ts
|
|
8158
|
-
init_cjs_shims();
|
|
8159
|
-
function getToneAndStyleSection() {
|
|
8160
|
-
return `# Tone and style
|
|
8161
|
-
|
|
8162
|
-
- Only use emojis if the caller explicitly requests it. Avoid using emojis in all output unless asked.
|
|
8163
|
-
- Your responses should be concise and direct. Lead with the answer or action, not the reasoning.
|
|
8164
|
-
- When referencing specific functions or pieces of code include the pattern file_path:line_number.
|
|
8165
|
-
- When referencing GitHub issues or pull requests, use the owner/repo#123 format.
|
|
8166
|
-
- Do not use a colon before tool calls. Your tool calls may not be shown directly in the output, so text like "Let me read the file:" followed by a read tool call should just be "Let me read the file." with a period.
|
|
8167
|
-
|
|
8168
|
-
# Output efficiency
|
|
8169
|
-
|
|
8170
|
-
Go straight to the point. Try the simplest approach first without going in circles. Do not overdo it. Be extra concise.
|
|
8171
|
-
|
|
8172
|
-
Keep your text output brief and direct. Lead with the answer or action, not the reasoning. Skip filler words, preamble, and unnecessary transitions. Do not restate the task \u2014 just do it. When explaining, include only what is necessary.
|
|
8173
|
-
|
|
8174
|
-
Focus text output on:
|
|
8175
|
-
- Decisions that need input
|
|
8176
|
-
- High-level status updates at natural milestones
|
|
8177
|
-
- Errors or blockers that change the plan
|
|
8178
|
-
|
|
8179
|
-
If you can say it in one sentence, don't use three. Prefer short, direct sentences over long explanations.`;
|
|
8180
|
-
}
|
|
8181
|
-
|
|
8182
|
-
// src/prompts/sections/environment.ts
|
|
8183
|
-
init_cjs_shims();
|
|
8184
|
-
async function getEnvironmentSection(options) {
|
|
8185
|
-
let platform = "unknown";
|
|
8186
|
-
let osRelease = "";
|
|
8187
|
-
try {
|
|
8188
|
-
const os = await import("os");
|
|
8189
|
-
platform = os.platform();
|
|
8190
|
-
osRelease = os.release();
|
|
8191
|
-
} catch {
|
|
8192
|
-
platform = typeof navigator !== "undefined" ? "worker" : "unknown";
|
|
8193
|
-
}
|
|
8194
|
-
const shell = (typeof process !== "undefined" ? process.env?.SHELL : void 0) ?? (platform === "win32" ? "cmd.exe" : "/bin/sh");
|
|
8195
|
-
const osVersion = `${platform}${osRelease ? " " + osRelease : ""}`;
|
|
8196
|
-
const cwd = options.cwd ?? (typeof process !== "undefined" && process.cwd ? process.cwd() : "/");
|
|
8197
|
-
const date = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
8198
|
-
const lines = [
|
|
8199
|
-
"# Environment",
|
|
8200
|
-
"",
|
|
8201
|
-
`- Platform: ${platform}`,
|
|
8202
|
-
`- Shell: ${shell}`,
|
|
8203
|
-
`- OS Version: ${osVersion}`,
|
|
8204
|
-
`- Working directory: ${cwd}`,
|
|
8205
|
-
`- Model: ${options.modelId} (provider: ${options.provider})`,
|
|
8206
|
-
`- Current date: ${date}`
|
|
8207
|
-
];
|
|
8208
|
-
if (canSpawnProcesses()) {
|
|
8209
|
-
const git = await getGitContext(cwd);
|
|
8210
|
-
if (git) {
|
|
8211
|
-
lines.push("");
|
|
8212
|
-
lines.push("## Git");
|
|
8213
|
-
if (git.branch) lines.push(`- Branch: ${git.branch}`);
|
|
8214
|
-
if (git.isRepo) lines.push(`- Is git repo: true`);
|
|
8215
|
-
if (git.status) lines.push(`- Status:
|
|
8216
|
-
${git.status}`);
|
|
8217
|
-
if (git.recentCommits) lines.push(`- Recent commits:
|
|
8218
|
-
${git.recentCommits}`);
|
|
8219
|
-
}
|
|
8220
|
-
}
|
|
8221
|
-
return lines.join("\n");
|
|
8222
|
-
}
|
|
8223
|
-
async function getGitContext(cwd) {
|
|
8224
|
-
try {
|
|
8225
|
-
const { execSync } = await import("child_process");
|
|
8226
|
-
const opts = {
|
|
8227
|
-
cwd,
|
|
8228
|
-
stdio: ["ignore", "pipe", "ignore"],
|
|
8229
|
-
timeout: 5e3
|
|
8230
|
-
};
|
|
8231
|
-
try {
|
|
8232
|
-
execSync("git rev-parse --is-inside-work-tree", opts);
|
|
8233
|
-
} catch {
|
|
8234
|
-
return null;
|
|
8235
|
-
}
|
|
8236
|
-
const branch = tryExec(execSync, "git branch --show-current", opts);
|
|
8237
|
-
const status = tryExec(execSync, "git status --short", opts, 2e3);
|
|
8238
|
-
const recentCommits = tryExec(execSync, "git log --oneline -5", opts, 2e3);
|
|
8239
|
-
const ctx = { isRepo: true };
|
|
8240
|
-
if (branch) ctx.branch = branch;
|
|
8241
|
-
if (status) ctx.status = status;
|
|
8242
|
-
if (recentCommits) ctx.recentCommits = recentCommits;
|
|
8243
|
-
return ctx;
|
|
8244
|
-
} catch {
|
|
8245
|
-
return null;
|
|
8246
|
-
}
|
|
8247
|
-
}
|
|
8248
|
-
function tryExec(execSync, cmd, opts, maxChars = 1e3) {
|
|
8249
|
-
try {
|
|
8250
|
-
const out = execSync(cmd, opts).toString("utf-8").trim();
|
|
8251
|
-
return out.length > maxChars ? out.slice(0, maxChars) + "\n...(truncated)" : out;
|
|
8252
|
-
} catch {
|
|
8253
|
-
return "";
|
|
8254
|
-
}
|
|
8255
|
-
}
|
|
8256
|
-
|
|
8257
8067
|
// src/prompts/sections/mcp.ts
|
|
8258
8068
|
init_cjs_shims();
|
|
8259
8069
|
function getMcpSection(options) {
|
|
@@ -8339,14 +8149,21 @@ function getApiServicesSection(opts) {
|
|
|
8339
8149
|
lines.push("");
|
|
8340
8150
|
}
|
|
8341
8151
|
} else {
|
|
8342
|
-
|
|
8343
|
-
|
|
8344
|
-
|
|
8152
|
+
const hasDescribe = opts.hasDescribeService !== false;
|
|
8153
|
+
if (hasDescribe) {
|
|
8154
|
+
lines.push(
|
|
8155
|
+
"Configured external HTTP APIs. Use `ApiCall` to invoke, but first call `DescribeService(service)` to fetch that service's endpoint catalog. Auth is injected automatically."
|
|
8156
|
+
);
|
|
8157
|
+
} else {
|
|
8158
|
+
lines.push(
|
|
8159
|
+
"Configured external HTTP APIs. Use `ApiCall` to invoke. Auth is injected automatically."
|
|
8160
|
+
);
|
|
8161
|
+
}
|
|
8345
8162
|
lines.push("");
|
|
8346
8163
|
appendStrictApiToolRules(
|
|
8347
8164
|
lines,
|
|
8348
8165
|
/* hasLazy */
|
|
8349
|
-
|
|
8166
|
+
hasDescribe
|
|
8350
8167
|
);
|
|
8351
8168
|
for (const svc of withEndpoints) {
|
|
8352
8169
|
const count = svc.endpoints.length;
|
|
@@ -8401,33 +8218,20 @@ function resolveEffectiveMode(services, requested, threshold) {
|
|
|
8401
8218
|
// src/prompts/systemPrompt.ts
|
|
8402
8219
|
async function buildSystemPrompt(options) {
|
|
8403
8220
|
const sections = [];
|
|
8221
|
+
const visibleToolNames = options.visibleToolNames ?? /* @__PURE__ */ new Set();
|
|
8404
8222
|
if (options.coordinatorMode) {
|
|
8405
|
-
} else if (options.staticBase !== void 0 && options.staticBase.length > 0) {
|
|
8223
|
+
} else if (options.staticBase !== void 0 && options.staticBase.trim().length > 0) {
|
|
8406
8224
|
sections.push(options.staticBase);
|
|
8407
|
-
}
|
|
8408
|
-
sections.push(getBaseSection());
|
|
8409
|
-
sections.push(getDoingTasksSection());
|
|
8410
|
-
sections.push(getActionsSection());
|
|
8411
|
-
if (options.registeredToolNames !== void 0 && options.registeredToolNames.size > 0) {
|
|
8412
|
-
sections.push(getUsingToolsSection({ registeredToolNames: options.registeredToolNames }));
|
|
8413
|
-
}
|
|
8414
|
-
sections.push(getToneAndStyleSection());
|
|
8415
|
-
}
|
|
8416
|
-
sections.push(
|
|
8417
|
-
await getEnvironmentSection({
|
|
8418
|
-
modelId: options.modelId ?? "unknown",
|
|
8419
|
-
provider: options.provider ?? "unknown",
|
|
8420
|
-
cwd: options.cwd
|
|
8421
|
-
})
|
|
8422
|
-
);
|
|
8225
|
+
}
|
|
8423
8226
|
if (options.mcpTools !== void 0 && options.mcpTools.length > 0) {
|
|
8424
8227
|
const mcpSection = getMcpSection({ mcpTools: options.mcpTools });
|
|
8425
8228
|
if (mcpSection !== null) sections.push(mcpSection);
|
|
8426
8229
|
}
|
|
8427
|
-
if (options.apiServices !== void 0 && options.apiServices.length > 0) {
|
|
8230
|
+
if (options.apiServices !== void 0 && options.apiServices.length > 0 && visibleToolNames.has("ApiCall")) {
|
|
8428
8231
|
const apiSection = getApiServicesSection({
|
|
8429
8232
|
services: options.apiServices,
|
|
8430
8233
|
mode: options.apiCatalogMode ?? "lazy",
|
|
8234
|
+
hasDescribeService: visibleToolNames.has("DescribeService"),
|
|
8431
8235
|
...options.apiLazyTokenThreshold !== void 0 ? { lazyTokenThreshold: options.apiLazyTokenThreshold } : {}
|
|
8432
8236
|
});
|
|
8433
8237
|
if (apiSection !== null) sections.push(apiSection);
|
|
@@ -8448,7 +8252,7 @@ ${rules}`);
|
|
|
8448
8252
|
${lessons}`);
|
|
8449
8253
|
}
|
|
8450
8254
|
const effectiveSkillList = options.skillList !== void 0 ? options.skillList : options.skillsAutoload ? await collectSkills(options.storage, options.skillsDir ?? "skills") : void 0;
|
|
8451
|
-
if (effectiveSkillList !== void 0 && effectiveSkillList.length > 0) {
|
|
8255
|
+
if (effectiveSkillList !== void 0 && effectiveSkillList.length > 0 && visibleToolNames.has("SkillPage")) {
|
|
8452
8256
|
const lines = ["# Skills"];
|
|
8453
8257
|
for (const skill of effectiveSkillList) {
|
|
8454
8258
|
lines.push(`- ${skill.name}: ${skill.description}`);
|
|
@@ -10870,6 +10674,18 @@ function scrubRunOptions(opts) {
|
|
|
10870
10674
|
if (opts.tools !== void 0) out.tools = [...opts.tools];
|
|
10871
10675
|
if (opts.toolChoice !== void 0) out.toolChoice = opts.toolChoice;
|
|
10872
10676
|
if (opts.tokenBudget !== void 0) out.tokenBudget = opts.tokenBudget;
|
|
10677
|
+
if (opts.systemPromptBase !== void 0 && opts.systemPromptBase.length > 0) {
|
|
10678
|
+
out.systemPromptBase = {
|
|
10679
|
+
present: true,
|
|
10680
|
+
chars: opts.systemPromptBase.length
|
|
10681
|
+
};
|
|
10682
|
+
}
|
|
10683
|
+
if (opts.systemPromptAppend !== void 0 && opts.systemPromptAppend.length > 0) {
|
|
10684
|
+
out.systemPromptAppend = {
|
|
10685
|
+
present: true,
|
|
10686
|
+
chars: opts.systemPromptAppend.length
|
|
10687
|
+
};
|
|
10688
|
+
}
|
|
10873
10689
|
if (opts.knowledge !== void 0) {
|
|
10874
10690
|
const k = {};
|
|
10875
10691
|
if (opts.knowledge.folders !== void 0) k.folders = [...opts.knowledge.folders];
|
|
@@ -11393,60 +11209,36 @@ var Engine = class {
|
|
|
11393
11209
|
const memory = createSmartMemory({ storage, config: this.config.memory });
|
|
11394
11210
|
const agents = await this.resolveAgents(storage);
|
|
11395
11211
|
const mcpTools = await this.mcpManager.getTools();
|
|
11396
|
-
const toolNameSet = this.collectToolNames(mcpTools);
|
|
11397
11212
|
const coordinatorBase = isCoordinatorMode(this.config) ? getCoordinatorBasePrompt() : void 0;
|
|
11398
11213
|
const skillSource = this.resolveSkillSource(options.skills, storage);
|
|
11399
11214
|
const skillList = skillSource !== void 0 ? await skillSource.list() : void 0;
|
|
11400
11215
|
const apiConfig = this.resolveApiConfig(options.api);
|
|
11401
11216
|
const offloadConfig = this.resolveOffloadConfig(options.compaction?.toolResultOffload);
|
|
11402
11217
|
const knowledgeRuntime = this.resolveKnowledgeRuntime(options.knowledge, storage);
|
|
11403
|
-
let systemPrompt = await buildSystemPrompt({
|
|
11404
|
-
...coordinatorBase !== void 0 ? { base: coordinatorBase } : {},
|
|
11405
|
-
...options.systemPromptBase !== void 0 ? { staticBase: options.systemPromptBase } : {},
|
|
11406
|
-
...options.systemPromptAppend !== void 0 && options.systemPromptAppend.length > 0 ? { platformAppend: options.systemPromptAppend } : {},
|
|
11407
|
-
memory,
|
|
11408
|
-
storage,
|
|
11409
|
-
// When an override was supplied, skip the legacy disk-scan path.
|
|
11410
|
-
skillsAutoload: options.skills !== void 0 ? false : this.config.skills.autoload,
|
|
11411
|
-
...this.config.skills.path !== void 0 ? { skillsDir: this.config.skills.path } : {},
|
|
11412
|
-
...skillList !== void 0 ? { skillList } : {},
|
|
11413
|
-
modelId: this.config.model.modelId,
|
|
11414
|
-
provider: this.config.model.provider,
|
|
11415
|
-
registeredToolNames: toolNameSet,
|
|
11416
|
-
mcpTools,
|
|
11417
|
-
coordinatorMode: isCoordinatorMode(this.config),
|
|
11418
|
-
// Plan 047 — render API services catalog (lazy by default).
|
|
11419
|
-
...apiConfig !== void 0 && apiConfig.services.length > 0 ? {
|
|
11420
|
-
apiServices: apiConfig.services,
|
|
11421
|
-
apiCatalogMode: apiConfig.mode ?? "lazy",
|
|
11422
|
-
...apiConfig.lazyTokenThreshold !== void 0 ? { apiLazyTokenThreshold: apiConfig.lazyTokenThreshold } : {}
|
|
11423
|
-
} : {}
|
|
11424
|
-
});
|
|
11425
|
-
if (options.outputFormat === "json") {
|
|
11426
|
-
systemPrompt += "\n\n" + buildSchemaPrompt(options.outputSchema);
|
|
11427
|
-
}
|
|
11428
11218
|
const gate = this.resolveGate();
|
|
11429
11219
|
const inspect = this.buildInspectWriter(storage.workspace, logPath);
|
|
11430
|
-
const registry =
|
|
11431
|
-
|
|
11220
|
+
const { systemPrompt: assembledPrompt, registry } = await this.buildPromptAndRegistry({
|
|
11221
|
+
runOptions: options,
|
|
11222
|
+
coordinatorBase,
|
|
11432
11223
|
storage,
|
|
11433
11224
|
client,
|
|
11434
|
-
|
|
11435
|
-
parentAgentId: null,
|
|
11225
|
+
logPath,
|
|
11436
11226
|
subagentRegistry,
|
|
11437
|
-
system: systemPrompt,
|
|
11438
11227
|
agents,
|
|
11439
11228
|
mcpTools,
|
|
11440
11229
|
memory,
|
|
11441
11230
|
inspect,
|
|
11442
|
-
|
|
11443
|
-
|
|
11444
|
-
|
|
11445
|
-
|
|
11446
|
-
|
|
11447
|
-
|
|
11231
|
+
gate,
|
|
11232
|
+
skillSource,
|
|
11233
|
+
skillList,
|
|
11234
|
+
apiConfig,
|
|
11235
|
+
offloadConfig,
|
|
11236
|
+
knowledgeRuntime
|
|
11448
11237
|
});
|
|
11449
|
-
|
|
11238
|
+
let systemPrompt = assembledPrompt;
|
|
11239
|
+
if (options.outputFormat === "json") {
|
|
11240
|
+
systemPrompt += "\n\n" + buildSchemaPrompt(options.outputSchema);
|
|
11241
|
+
}
|
|
11450
11242
|
await inspect.writeStartSnapshot({
|
|
11451
11243
|
systemPrompt,
|
|
11452
11244
|
tools: this.snapshotTools(registry, mcpTools),
|
|
@@ -11615,68 +11407,55 @@ var Engine = class {
|
|
|
11615
11407
|
const memory = createSmartMemory({ storage, config: this.config.memory });
|
|
11616
11408
|
const agents = await this.resolveAgents(storage);
|
|
11617
11409
|
const mcpTools = await this.mcpManager.getTools();
|
|
11618
|
-
const toolNameSet = this.collectToolNames(mcpTools);
|
|
11619
11410
|
const coordinatorBase = isCoordinatorMode(this.config) ? getCoordinatorBasePrompt() : void 0;
|
|
11620
11411
|
const skillSource = this.resolveSkillSource(options.skills, storage);
|
|
11621
11412
|
const skillList = skillSource !== void 0 ? await skillSource.list() : void 0;
|
|
11622
11413
|
const apiConfig = this.resolveApiConfig(options.api);
|
|
11623
11414
|
const offloadConfig = this.resolveOffloadConfig(options.compaction?.toolResultOffload);
|
|
11624
11415
|
const knowledgeRuntime = this.resolveKnowledgeRuntime(options.knowledge, storage);
|
|
11625
|
-
let systemPrompt = await buildSystemPrompt({
|
|
11626
|
-
...coordinatorBase !== void 0 ? { base: coordinatorBase } : {},
|
|
11627
|
-
...options.systemPromptBase !== void 0 ? { staticBase: options.systemPromptBase } : {},
|
|
11628
|
-
...options.systemPromptAppend !== void 0 && options.systemPromptAppend.length > 0 ? { platformAppend: options.systemPromptAppend } : {},
|
|
11629
|
-
memory,
|
|
11630
|
-
storage,
|
|
11631
|
-
// When an override was supplied, skip the legacy disk-scan path.
|
|
11632
|
-
skillsAutoload: options.skills !== void 0 ? false : this.config.skills.autoload,
|
|
11633
|
-
...this.config.skills.path !== void 0 ? { skillsDir: this.config.skills.path } : {},
|
|
11634
|
-
...skillList !== void 0 ? { skillList } : {},
|
|
11635
|
-
modelId: this.config.model.modelId,
|
|
11636
|
-
provider: this.config.model.provider,
|
|
11637
|
-
registeredToolNames: toolNameSet,
|
|
11638
|
-
mcpTools,
|
|
11639
|
-
coordinatorMode: isCoordinatorMode(this.config),
|
|
11640
|
-
// Plan 047 — render API services catalog (lazy by default).
|
|
11641
|
-
...apiConfig !== void 0 && apiConfig.services.length > 0 ? {
|
|
11642
|
-
apiServices: apiConfig.services,
|
|
11643
|
-
apiCatalogMode: apiConfig.mode ?? "lazy",
|
|
11644
|
-
...apiConfig.lazyTokenThreshold !== void 0 ? { apiLazyTokenThreshold: apiConfig.lazyTokenThreshold } : {}
|
|
11645
|
-
} : {}
|
|
11646
|
-
});
|
|
11647
|
-
if (options.outputFormat === "json") {
|
|
11648
|
-
systemPrompt += "\n\n" + buildSchemaPrompt(options.outputSchema);
|
|
11649
|
-
}
|
|
11650
11416
|
const gate = this.resolveGate();
|
|
11651
11417
|
const inspect = this.buildInspectWriter(storage.workspace, logPath);
|
|
11652
|
-
const registry =
|
|
11653
|
-
|
|
11418
|
+
const { systemPrompt: assembledPrompt, registry } = await this.buildPromptAndRegistry({
|
|
11419
|
+
runOptions: options,
|
|
11420
|
+
coordinatorBase,
|
|
11654
11421
|
storage,
|
|
11655
11422
|
client,
|
|
11656
|
-
|
|
11657
|
-
parentAgentId: null,
|
|
11423
|
+
logPath,
|
|
11658
11424
|
subagentRegistry,
|
|
11659
|
-
system: systemPrompt,
|
|
11660
11425
|
agents,
|
|
11661
11426
|
mcpTools,
|
|
11662
11427
|
memory,
|
|
11663
11428
|
inspect,
|
|
11664
|
-
|
|
11665
|
-
|
|
11666
|
-
|
|
11667
|
-
|
|
11668
|
-
|
|
11669
|
-
|
|
11429
|
+
gate,
|
|
11430
|
+
skillSource,
|
|
11431
|
+
skillList,
|
|
11432
|
+
apiConfig,
|
|
11433
|
+
offloadConfig,
|
|
11434
|
+
knowledgeRuntime
|
|
11670
11435
|
});
|
|
11436
|
+
let systemPrompt = assembledPrompt;
|
|
11437
|
+
if (options.outputFormat === "json") {
|
|
11438
|
+
systemPrompt += "\n\n" + buildSchemaPrompt(options.outputSchema);
|
|
11439
|
+
}
|
|
11671
11440
|
await inspect.writeStartSnapshot({
|
|
11672
11441
|
systemPrompt,
|
|
11673
11442
|
tools: this.snapshotTools(registry, mcpTools),
|
|
11443
|
+
// Plan 052 review fix — surface the resume-time effective
|
|
11444
|
+
// policy in `run-options.json` so post-hoc debuggers see
|
|
11445
|
+
// exactly what gating drove the resume's prompt + tool
|
|
11446
|
+
// surface. Otherwise resume's inspect bundle looked like a
|
|
11447
|
+
// fresh run with no restrictions, masking the silent-widening
|
|
11448
|
+
// failure mode documented on `ResumeOptions.tools`.
|
|
11674
11449
|
runOptions: scrubRunOptions({
|
|
11675
11450
|
runId: snapshot.runId,
|
|
11676
11451
|
nodeId: snapshot.nodeId,
|
|
11677
11452
|
task: "[resumed run \u2014 original task in transcript]",
|
|
11678
11453
|
...options.outputFormat !== void 0 ? { outputFormat: options.outputFormat } : {},
|
|
11679
|
-
...options.outputSchema !== void 0 ? { outputSchema: options.outputSchema } : {}
|
|
11454
|
+
...options.outputSchema !== void 0 ? { outputSchema: options.outputSchema } : {},
|
|
11455
|
+
...options.tools !== void 0 ? { tools: options.tools } : {},
|
|
11456
|
+
...options.toolChoice !== void 0 ? { toolChoice: options.toolChoice } : {},
|
|
11457
|
+
...options.systemPromptBase !== void 0 ? { systemPromptBase: options.systemPromptBase } : {},
|
|
11458
|
+
...options.systemPromptAppend !== void 0 ? { systemPromptAppend: options.systemPromptAppend } : {}
|
|
11680
11459
|
}),
|
|
11681
11460
|
modelConfig: scrubModelConfig(
|
|
11682
11461
|
{
|
|
@@ -12325,72 +12104,97 @@ ${inputJson}
|
|
|
12325
12104
|
});
|
|
12326
12105
|
}
|
|
12327
12106
|
/**
|
|
12328
|
-
*
|
|
12329
|
-
*
|
|
12330
|
-
*
|
|
12331
|
-
*
|
|
12332
|
-
*
|
|
12107
|
+
* Plan 052 — two-pass system-prompt + tool-registry build.
|
|
12108
|
+
*
|
|
12109
|
+
* The prompt's API / skill / MCP sections describe only the tools
|
|
12110
|
+
* the model will actually see, so we must know the post-filter
|
|
12111
|
+
* tool set before assembling the prompt. The registry, however,
|
|
12112
|
+
* is what produces that set, AND its `Agent` tool needs the
|
|
12113
|
+
* final system prompt baked in for subagent dispatch.
|
|
12114
|
+
*
|
|
12115
|
+
* The chicken-and-egg is resolved by building twice:
|
|
12116
|
+
*
|
|
12117
|
+
* Pass 1 — placeholder prompt → registry → applyRunToolFilter
|
|
12118
|
+
* → snapshot of visible tool names + visible MCP tools.
|
|
12119
|
+
* Pass 2 — final prompt assembled from those visible surfaces
|
|
12120
|
+
* → rebuild registry → applyRunToolFilter again.
|
|
12121
|
+
*
|
|
12122
|
+
* `applyRunToolFilter` is deterministic given options, so the
|
|
12123
|
+
* second filter pass is identical to the first; the second
|
|
12124
|
+
* registry is the authoritative one returned to the caller.
|
|
12125
|
+
*
|
|
12126
|
+
* Pass 1's prompt is intentionally minimal (placeholder string)
|
|
12127
|
+
* because the only thing we use the first registry for is its
|
|
12128
|
+
* post-filter tool list. The transient prompt never reaches the
|
|
12129
|
+
* model.
|
|
12333
12130
|
*/
|
|
12334
|
-
|
|
12335
|
-
const
|
|
12336
|
-
|
|
12337
|
-
|
|
12338
|
-
|
|
12339
|
-
|
|
12340
|
-
|
|
12341
|
-
|
|
12342
|
-
|
|
12343
|
-
|
|
12344
|
-
|
|
12345
|
-
|
|
12346
|
-
|
|
12347
|
-
|
|
12348
|
-
|
|
12349
|
-
|
|
12350
|
-
|
|
12351
|
-
|
|
12352
|
-
|
|
12353
|
-
|
|
12354
|
-
|
|
12355
|
-
|
|
12356
|
-
|
|
12357
|
-
|
|
12358
|
-
|
|
12359
|
-
|
|
12360
|
-
|
|
12361
|
-
|
|
12362
|
-
|
|
12363
|
-
|
|
12364
|
-
|
|
12365
|
-
|
|
12366
|
-
|
|
12367
|
-
|
|
12368
|
-
|
|
12369
|
-
|
|
12370
|
-
|
|
12371
|
-
|
|
12372
|
-
|
|
12373
|
-
|
|
12374
|
-
|
|
12375
|
-
|
|
12376
|
-
}
|
|
12377
|
-
|
|
12378
|
-
|
|
12379
|
-
|
|
12380
|
-
|
|
12381
|
-
|
|
12382
|
-
|
|
12383
|
-
|
|
12384
|
-
}
|
|
12385
|
-
|
|
12386
|
-
|
|
12387
|
-
|
|
12388
|
-
|
|
12389
|
-
|
|
12390
|
-
|
|
12391
|
-
|
|
12392
|
-
|
|
12393
|
-
|
|
12131
|
+
async buildPromptAndRegistry(args) {
|
|
12132
|
+
const {
|
|
12133
|
+
runOptions,
|
|
12134
|
+
coordinatorBase,
|
|
12135
|
+
storage,
|
|
12136
|
+
client,
|
|
12137
|
+
logPath,
|
|
12138
|
+
subagentRegistry,
|
|
12139
|
+
agents,
|
|
12140
|
+
mcpTools,
|
|
12141
|
+
memory,
|
|
12142
|
+
inspect,
|
|
12143
|
+
gate,
|
|
12144
|
+
skillSource,
|
|
12145
|
+
skillList,
|
|
12146
|
+
apiConfig,
|
|
12147
|
+
offloadConfig,
|
|
12148
|
+
knowledgeRuntime
|
|
12149
|
+
} = args;
|
|
12150
|
+
const baseRegistryArgs = {
|
|
12151
|
+
config: this.config,
|
|
12152
|
+
storage,
|
|
12153
|
+
client,
|
|
12154
|
+
parentLogPath: logPath,
|
|
12155
|
+
parentAgentId: null,
|
|
12156
|
+
subagentRegistry,
|
|
12157
|
+
agents,
|
|
12158
|
+
mcpTools,
|
|
12159
|
+
memory,
|
|
12160
|
+
inspect,
|
|
12161
|
+
...this.config.hooks.propagateGateToSubagents === true && gate !== void 0 ? { subagentGate: gate } : {},
|
|
12162
|
+
...skillSource !== void 0 ? { skillSource } : {},
|
|
12163
|
+
...apiConfig !== void 0 ? { apiConfig } : {},
|
|
12164
|
+
...offloadConfig !== void 0 ? { toolResultOffload: offloadConfig } : {},
|
|
12165
|
+
...knowledgeRuntime !== void 0 ? { knowledge: knowledgeRuntime } : {},
|
|
12166
|
+
...this.internals.fetch !== void 0 ? { fetch: this.internals.fetch } : {}
|
|
12167
|
+
};
|
|
12168
|
+
const tempRegistry = buildToolRegistry({ ...baseRegistryArgs, system: "" });
|
|
12169
|
+
applyRunToolFilter(tempRegistry, runOptions);
|
|
12170
|
+
const visibleToolNames = new Set(tempRegistry.list().map((t) => t.name));
|
|
12171
|
+
const visibleMcpTools = mcpTools.filter((t) => visibleToolNames.has(t.name));
|
|
12172
|
+
const systemPrompt = await buildSystemPrompt({
|
|
12173
|
+
...coordinatorBase !== void 0 ? { base: coordinatorBase } : {},
|
|
12174
|
+
...runOptions.systemPromptBase !== void 0 ? { staticBase: runOptions.systemPromptBase } : {},
|
|
12175
|
+
...runOptions.systemPromptAppend !== void 0 && runOptions.systemPromptAppend.length > 0 ? { platformAppend: runOptions.systemPromptAppend } : {},
|
|
12176
|
+
memory,
|
|
12177
|
+
storage,
|
|
12178
|
+
// When an override was supplied, skip the legacy disk-scan path.
|
|
12179
|
+
skillsAutoload: skillSource !== void 0 ? false : this.config.skills.autoload,
|
|
12180
|
+
...this.config.skills.path !== void 0 ? { skillsDir: this.config.skills.path } : {},
|
|
12181
|
+
...skillList !== void 0 ? { skillList } : {},
|
|
12182
|
+
// Plan 052 — pass the FINAL post-filter visible tool surface
|
|
12183
|
+
// so prompt sections gate correctly.
|
|
12184
|
+
visibleToolNames,
|
|
12185
|
+
mcpTools: visibleMcpTools,
|
|
12186
|
+
coordinatorMode: isCoordinatorMode(this.config),
|
|
12187
|
+
// Plan 047 — render API services catalog (lazy by default).
|
|
12188
|
+
// Gating on `ApiCall` visibility lives inside buildSystemPrompt.
|
|
12189
|
+
...apiConfig !== void 0 && apiConfig.services.length > 0 ? {
|
|
12190
|
+
apiServices: apiConfig.services,
|
|
12191
|
+
apiCatalogMode: apiConfig.mode ?? "lazy",
|
|
12192
|
+
...apiConfig.lazyTokenThreshold !== void 0 ? { apiLazyTokenThreshold: apiConfig.lazyTokenThreshold } : {}
|
|
12193
|
+
} : {}
|
|
12194
|
+
});
|
|
12195
|
+
const registry = buildToolRegistry({ ...baseRegistryArgs, system: systemPrompt });
|
|
12196
|
+
applyRunToolFilter(registry, runOptions);
|
|
12197
|
+
return { systemPrompt, registry };
|
|
12394
12198
|
}
|
|
12395
12199
|
/**
|
|
12396
12200
|
* Resolve the subagent catalogue the Agent tool will dispatch against.
|