+
+ #${idx + 1} · ${title} · ${t} · ${model}
+ ${log.ok ? '✅' : '❌'}
+
+ ${err ? `
${escapeHtml(err)}
` : ''}
+
+
+ 发出去的 messages(完整)
+ ${escapeHtml(reqDisplay)}
+
+
+
+ 规划 AI 原始完整回复(含 <think>)
+ ${escapeHtml(String(log.rawReply ?? ''))}
+
+
+
+ 写回输入框的版本(已剔除 think,只保留 plot+note)
+ ${escapeHtml(String(log.filteredReply ?? ''))}
+
+
`;
+ }).join('');
+
+ body.innerHTML = html;
+}
+
+function openLogModal() {
+ const m = document.getElementById('ep_log_modal');
+ if (!m) return;
+ m.classList.add('open');
+ renderLogs();
+}
+function closeLogModal() {
+ const m = document.getElementById('ep_log_modal');
+ if (!m) return;
+ m.classList.remove('open');
+}
+
+/** -------------------------
+ * Settings UI — Issue #1: use inline-drawer for collapsible
+ * --------------------------*/
+function createSettingsHTML() {
+ const s = ensureSettings();
+ const channel = s.api.channel;
+
+ return `
+
+
+
+ Ena Planner
+
+
+ ${s.enabled ? 'Enabled' : 'Disabled'}
+
+
+
+
+
+
+
+
+
+
+
+
开启后:你点发送/回车,会先走"规划模型",把规划结果写回输入框再发送。
+
+
+
+
+
防止"原始+规划文本"再次被拦截规划。
+
+
+
+
+
+
+
+
+
+
角色绑定的世界书总是会读取。这里选择是否额外包含全局世界书。
+
+
+
+
+
+
+
+
+
+
+
+
条目名称/备注包含这些字符串的条目会被排除。
+
+
+
+
+
+
+
+
+
+
+
+ 自动行为说明:
+ · 聊天片段:自动读取所有未隐藏的 AI 回复(不含用户输入)
+ · 自动剔除 <think> 以前的内容(含未包裹的思考段落)
+ · 角色卡字段(desc/personality/scenario):有就全部加入
+ · 向量召回(extensionPrompts):有就自动加入
+ · 世界书激活:常驻(蓝灯)+ 关键词触发(绿灯)
+
+
+
+
+
+
+
+
+
这些 XML 标签及其内容会从聊天历史中剔除。自闭合标签(如 <Tag/>)也会被移除。
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
影响默认前缀:OpenAI/Claude → /v1,Gemini → /v1beta
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
新增多条提示词块,选择 role(system/user/assistant)。系统块放最前面;assistant 块放最后。
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 工作原理:
+ · 规划时会锁定发送按钮
+ · Log 静默记录,只有出错才弹提示
+ · 写回版本:剔除 <think>,只保留 <plot>+<note>
+ · 前文自动剔除 <think> 以前内容和排除标签内容
+
+
+
+
+
+
+
+
`;
+}
+
+function renderPromptDesigner() {
+ const s = ensureSettings();
+ const list = document.getElementById('ep_prompt_list');
+ if (!list) return;
+
+ const blocks = s.promptBlocks || [];
+ const rows = blocks.map((b, idx) => {
+ const role = b.role || 'system';
+ return `
+