mirror of
https://github.com/volcengine/OpenViking.git
synced 2026-10-02 18:10:30 +08:00
findVikingUri() checked the path-like keys and then swept every remaining
argument value, so a local write or edit whose CONTENT merely mentioned a
viking URI was denied and no file was created:
write { file_path: "/home/me/notes.md",
content: "docs say viking://user/default/ is virtual" } -> deny
The sweep still runs — it is what catches an unusual or nested path key — but
it now skips arguments that carry content rather than a location
(content, new_string, old_string, file_text, ...). A URI in file_path, path,
uri, an unknown nested path key, or a bash command still denies.
Vendored copies regenerated with examples/memory-plugin-shared/sync.mjs.
79 lines
2.2 KiB
JavaScript
79 lines
2.2 KiB
JavaScript
// GENERATED FROM examples/memory-plugin-shared/lib. DO NOT EDIT.
|
|
const DEFAULT_URI_KEYS = [
|
|
"filePath",
|
|
"file_path",
|
|
"filepath",
|
|
"path",
|
|
"uri",
|
|
"target_uri",
|
|
"targetUri",
|
|
"pattern",
|
|
];
|
|
|
|
export function normalizeToolName(value) {
|
|
return String(value || "").trim().toLowerCase();
|
|
}
|
|
|
|
// Arguments that carry file CONTENT rather than a location. The sweep below
|
|
// looks past the known path keys so an unusual one (`paths`, a nested target)
|
|
// is still caught, but text a tool is asked to WRITE is not a path: a local
|
|
// `write` whose body merely mentions viking://user/default/ was denied, and no
|
|
// file was created. Skipped by name at any depth.
|
|
const DEFAULT_CONTENT_KEYS = [
|
|
"content",
|
|
"contents",
|
|
"text",
|
|
"body",
|
|
"old_string",
|
|
"oldString",
|
|
"new_string",
|
|
"newString",
|
|
"old_str",
|
|
"new_str",
|
|
"file_text",
|
|
"insert_line",
|
|
"replacement",
|
|
];
|
|
|
|
export function findVikingUri(args = {}, keys = DEFAULT_URI_KEYS, contentKeys = DEFAULT_CONTENT_KEYS) {
|
|
if (!args || typeof args !== "object") return null;
|
|
for (const key of keys) {
|
|
const uri = findVikingUriInValue(args[key]);
|
|
if (uri) return uri;
|
|
}
|
|
return findVikingUriInValue(args, new Set(contentKeys));
|
|
}
|
|
|
|
export function findVikingUriInValue(value, skipKeys) {
|
|
if (typeof value === "string") {
|
|
const match = value.match(/\bviking:\/\/[^\s"'`<>)]*/i);
|
|
return match?.[0] || null;
|
|
}
|
|
if (Array.isArray(value)) {
|
|
for (const item of value) {
|
|
const uri = findVikingUriInValue(item, skipKeys);
|
|
if (uri) return uri;
|
|
}
|
|
return null;
|
|
}
|
|
if (value && typeof value === "object") {
|
|
for (const [key, item] of Object.entries(value)) {
|
|
if (skipKeys?.has(key)) continue;
|
|
const uri = findVikingUriInValue(item, skipKeys);
|
|
if (uri) return uri;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
export function buildGuardMessage(uri, hint = {}) {
|
|
const tool = hint.tool || "the OpenViking MCP tools";
|
|
const example = typeof hint.example === "function" ? hint.example(uri) : hint.example;
|
|
const lines = [
|
|
"viking:// URIs are OpenViking virtual paths, not local filesystem paths.",
|
|
`Use ${tool} instead.`,
|
|
];
|
|
if (example) lines.push(`Example: ${example}`);
|
|
return lines.join("\n");
|
|
}
|