Add YAML macro for variables

This commit is contained in:
2026-01-28 00:28:01 +08:00
parent 1dfa9f95f2
commit d1caf01334
3 changed files with 3938 additions and 24 deletions

3851
libs/js-yaml.mjs Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -6,6 +6,7 @@
import { getContext } from "../../../../../extensions.js"; import { getContext } from "../../../../../extensions.js";
import { getLocalVariable, setLocalVariable } from "../../../../../variables.js"; import { getLocalVariable, setLocalVariable } from "../../../../../variables.js";
import { createModuleEvents, event_types } from "../../core/event-manager.js"; import { createModuleEvents, event_types } from "../../core/event-manager.js";
import jsYaml from "../../libs/js-yaml.mjs";
import { import {
lwbSplitPathWithBrackets, lwbSplitPathWithBrackets,
lwbSplitPathAndValue, lwbSplitPathAndValue,
@@ -19,6 +20,7 @@ import {
const MODULE_ID = 'varCommands'; const MODULE_ID = 'varCommands';
const TAG_RE_XBGETVAR = /\{\{xbgetvar::([^}]+)\}\}/gi; const TAG_RE_XBGETVAR = /\{\{xbgetvar::([^}]+)\}\}/gi;
const TAG_RE_XBGETVAR_YAML = /\{\{xbgetvar_yaml::([^}]+)\}\}/gi;
let events = null; let events = null;
let initialized = false; let initialized = false;
@@ -94,12 +96,22 @@ function setDeepBySegments(target, segs, value) {
cur[key] = value; cur[key] = value;
} else { } else {
const nxt = cur[key]; const nxt = cur[key];
if (typeof nxt === 'object' && nxt && !Array.isArray(nxt)) { const nextSeg = segs[i + 1];
const wantArray = (typeof nextSeg === 'number');
// 已存在且类型正确:继续深入
if (wantArray && Array.isArray(nxt)) {
cur = nxt; cur = nxt;
} else { continue;
cur[key] = {};
cur = cur[key];
} }
if (!wantArray && (nxt && typeof nxt === 'object') && !Array.isArray(nxt)) {
cur = nxt;
continue;
}
// 不存在或类型不匹配:创建正确的容器
cur[key] = wantArray ? [] : {};
cur = cur[key];
} }
} }
} }
@@ -139,6 +151,38 @@ export function replaceXbGetVarInString(s) {
return s.replace(TAG_RE_XBGETVAR, (_, p) => lwbResolveVarPath(p)); return s.replace(TAG_RE_XBGETVAR, (_, p) => lwbResolveVarPath(p));
} }
/**
* 将 {{xbgetvar_yaml::路径}} 替换为 YAML 格式的值
* @param {string} s
* @returns {string}
*/
export function replaceXbGetVarYamlInString(s) {
s = String(s ?? '');
if (!s || s.indexOf('{{xbgetvar_yaml::') === -1) return s;
TAG_RE_XBGETVAR_YAML.lastIndex = 0;
return s.replace(TAG_RE_XBGETVAR_YAML, (_, p) => {
const value = lwbResolveVarPath(p);
if (!value) return '';
// 尝试解析为对象/数组,然后转 YAML
try {
const parsed = JSON.parse(value);
if (typeof parsed === 'object' && parsed !== null) {
return jsYaml.dump(parsed, {
indent: 2,
lineWidth: -1,
noRefs: true,
quotingType: '"',
}).trim();
}
return value;
} catch {
return value;
}
});
}
export function replaceXbGetVarInChat(chat) { export function replaceXbGetVarInChat(chat) {
if (!Array.isArray(chat)) return; if (!Array.isArray(chat)) return;
@@ -148,9 +192,13 @@ export function replaceXbGetVarInChat(chat) {
if (!key) continue; if (!key) continue;
const old = String(msg[key] ?? ''); const old = String(msg[key] ?? '');
if (old.indexOf('{{xbgetvar::') === -1) continue; const hasJson = old.indexOf('{{xbgetvar::') !== -1;
const hasYaml = old.indexOf('{{xbgetvar_yaml::') !== -1;
if (!hasJson && !hasYaml) continue;
msg[key] = replaceXbGetVarInString(old); let result = hasJson ? replaceXbGetVarInString(old) : old;
result = hasYaml ? replaceXbGetVarYamlInString(result) : result;
msg[key] = result;
} catch {} } catch {}
} }
} }
@@ -165,9 +213,12 @@ export function applyXbGetVarForMessage(messageId, writeback = true) {
if (!key) return; if (!key) return;
const old = String(msg[key] ?? ''); const old = String(msg[key] ?? '');
if (old.indexOf('{{xbgetvar::') === -1) return; const hasJson = old.indexOf('{{xbgetvar::') !== -1;
const hasYaml = old.indexOf('{{xbgetvar_yaml::') !== -1;
if (!hasJson && !hasYaml) return;
const out = replaceXbGetVarInString(old); let out = hasJson ? replaceXbGetVarInString(old) : old;
out = hasYaml ? replaceXbGetVarYamlInString(out) : out;
if (writeback && out !== old) { if (writeback && out !== old) {
msg[key] = out; msg[key] = out;
} }

View File

@@ -6,7 +6,7 @@
import { getContext } from "../../../../../extensions.js"; import { getContext } from "../../../../../extensions.js";
import { getLocalVariable } from "../../../../../variables.js"; import { getLocalVariable } from "../../../../../variables.js";
import { createModuleEvents } from "../../core/event-manager.js"; import { createModuleEvents } from "../../core/event-manager.js";
import { replaceXbGetVarInString } from "./var-commands.js"; import { replaceXbGetVarInString, replaceXbGetVarYamlInString } from "./var-commands.js";
const MODULE_ID = 'vareventEditor'; const MODULE_ID = 'vareventEditor';
const LWB_EXT_ID = 'LittleWhiteBox'; const LWB_EXT_ID = 'LittleWhiteBox';
@@ -297,12 +297,15 @@ function installWIHiddenTagStripper() {
} }
msg.content = await replaceVareventInString(msg.content, false, false); msg.content = await replaceVareventInString(msg.content, false, false);
} }
if (msg.content.indexOf('{{xbgetvar::') !== -1) { if (msg.content.indexOf('{{xbgetvar::') !== -1) {
msg.content = replaceXbGetVarInString(msg.content); msg.content = replaceXbGetVarInString(msg.content);
} }
} if (msg.content.indexOf('{{xbgetvar_yaml::') !== -1) {
if (Array.isArray(msg?.content)) { msg.content = replaceXbGetVarYamlInString(msg.content);
for (const part of msg.content) { }
}
if (Array.isArray(msg?.content)) {
for (const part of msg.content) {
if (part?.type === 'text' && typeof part.text === 'string') { if (part?.type === 'text' && typeof part.text === 'string') {
if (part.text.includes('<varevent')) { if (part.text.includes('<varevent')) {
TAG_RE_VAREVENT.lastIndex = 0; TAG_RE_VAREVENT.lastIndex = 0;
@@ -312,12 +315,15 @@ function installWIHiddenTagStripper() {
} }
part.text = await replaceVareventInString(part.text, false, false); part.text = await replaceVareventInString(part.text, false, false);
} }
if (part.text.indexOf('{{xbgetvar::') !== -1) { if (part.text.indexOf('{{xbgetvar::') !== -1) {
part.text = replaceXbGetVarInString(part.text); part.text = replaceXbGetVarInString(part.text);
}
if (part.text.indexOf('{{xbgetvar_yaml::') !== -1) {
part.text = replaceXbGetVarYamlInString(part.text);
}
}
} }
} }
}
}
if (typeof msg?.mes === 'string') { if (typeof msg?.mes === 'string') {
if (msg.mes.includes('<varevent')) { if (msg.mes.includes('<varevent')) {
TAG_RE_VAREVENT.lastIndex = 0; TAG_RE_VAREVENT.lastIndex = 0;
@@ -327,12 +333,15 @@ function installWIHiddenTagStripper() {
} }
msg.mes = await replaceVareventInString(msg.mes, false, false); msg.mes = await replaceVareventInString(msg.mes, false, false);
} }
if (msg.mes.indexOf('{{xbgetvar::') !== -1) { if (msg.mes.indexOf('{{xbgetvar::') !== -1) {
msg.mes = replaceXbGetVarInString(msg.mes); msg.mes = replaceXbGetVarInString(msg.mes);
}
if (msg.mes.indexOf('{{xbgetvar_yaml::') !== -1) {
msg.mes = replaceXbGetVarYamlInString(msg.mes);
}
}
} }
} } catch {}
}
} catch {}
}; };
try { try {
if (eventSource && typeof eventSource.makeLast === 'function') { if (eventSource && typeof eventSource.makeLast === 'function') {
@@ -361,6 +370,9 @@ function installWIHiddenTagStripper() {
if (data.prompt.indexOf('{{xbgetvar::') !== -1) { if (data.prompt.indexOf('{{xbgetvar::') !== -1) {
data.prompt = replaceXbGetVarInString(data.prompt); data.prompt = replaceXbGetVarInString(data.prompt);
} }
if (data.prompt.indexOf('{{xbgetvar_yaml::') !== -1) {
data.prompt = replaceXbGetVarYamlInString(data.prompt);
}
} }
} catch {} } catch {}
}); });