Patch 6: Add {f:} file inclusion to system prompt variable resolver

This commit is contained in:
PQ32 Developer 2026-05-15 00:04:15 -07:00
parent acbf66c5bf
commit c546d23bc7

View File

@ -1,5 +1,16 @@
const prisma = require("../utils/prisma");
const moment = require("moment");
const fs = require("fs");
const path = require("path");
// ── Merlyn {f:} include root ──────────────────────────────────────────────────
const MERLYN_INCLUDES_ROOT = path.resolve(
path.join(
process.env.STORAGE_DIR || "/app/server/storage",
"anythingllm-fs",
"includes"
)
);
/**
* @typedef {Object} SystemPromptVariable
@ -216,6 +227,30 @@ const SystemPromptVariables = {
}
},
/**
* Resolves a {f:path} file reference against the Merlyn include root.
* Security: path traversal above the include root is blocked.
* @param {string} filePath - the path after "f:"
* @returns {string} - file contents, or empty string if not found
*/
_resolveFileVariable: function (filePath) {
const resolved = path.resolve(MERLYN_INCLUDES_ROOT, filePath);
if (!resolved.startsWith(MERLYN_INCLUDES_ROOT)) {
console.warn(`[{f:}] Path traversal blocked: ${filePath}`);
return "";
}
if (!fs.existsSync(resolved)) {
console.warn(`[{f:}] File not found: ${resolved}`);
return "";
}
try {
return fs.readFileSync(resolved, "utf-8");
} catch (e) {
console.error(`[{f:}] Error reading ${resolved}:`, e.message);
return "";
}
},
/**
* Injects variables into a string based on the user ID and workspace ID (if provided) and the variables available
* @param {string} str - the input string to expand variables into
@ -239,6 +274,12 @@ const SystemPromptVariables = {
// Process each match
for (const match of matches) {
// ── {f:path} file inclusion ───────────────────────────────────────────────
if (key.startsWith("f:")) {
result = result.replace(match, this._resolveFileVariable(key.substring(2).trim()));
continue;
}
const key = match.substring(1, match.length - 1); // Remove { and }
// Determine if the variable is a class-based variable (workspace.X or user.X)