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';
@@ -300,6 +300,9 @@ function installWIHiddenTagStripper() {
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) {
msg.content = replaceXbGetVarYamlInString(msg.content);
}
} }
if (Array.isArray(msg?.content)) { if (Array.isArray(msg?.content)) {
for (const part of msg.content) { for (const part of msg.content) {
@@ -315,6 +318,9 @@ function installWIHiddenTagStripper() {
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);
}
} }
} }
} }
@@ -330,6 +336,9 @@ function installWIHiddenTagStripper() {
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 {}
@@ -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 {}
}); });