Update TTS domain and adjust story summary injection
This commit is contained in:
@@ -561,7 +561,7 @@ html, body {
|
|||||||
配置
|
配置
|
||||||
══════════════════════════════════════════════════════════════════════════════ */
|
══════════════════════════════════════════════════════════════════════════════ */
|
||||||
|
|
||||||
const TTS_WORKER_URL = 'https://hstts.velure.top';
|
const TTS_WORKER_URL = 'https://hstts.velure.codes';
|
||||||
|
|
||||||
const VALID_EMOTIONS = ['happy', 'sad', 'angry', 'surprise', 'scare', 'hate'];
|
const VALID_EMOTIONS = ['happy', 'sad', 'angry', 'surprise', 'scare', 'hate'];
|
||||||
const EMOTION_ICONS = {
|
const EMOTION_ICONS = {
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
// 语音模块 - TTS 合成服务
|
// 语音模块 - TTS 合成服务
|
||||||
// ════════════════════════════════════════════════════════════════════════════
|
// ════════════════════════════════════════════════════════════════════════════
|
||||||
|
|
||||||
export const TTS_WORKER_URL = 'https://hstts.velure.top';
|
export const TTS_WORKER_URL = 'https://hstts.velure.codes';
|
||||||
export const DEFAULT_VOICE = 'female_1';
|
export const DEFAULT_VOICE = 'female_1';
|
||||||
export const DEFAULT_SPEED = 1.0;
|
export const DEFAULT_SPEED = 1.0;
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
// ═══════════════════════════════════════════════════════════════════════════
|
// ═══════════════════════════════════════════════════════════════════════════
|
||||||
// Story Summary - Prompt Injection (Final Clean Version)
|
// Story Summary - Prompt Injection (Final Clean Version)
|
||||||
// - 仅负责“构建注入文本”,不负责写入 extension_prompts
|
// - 仅负责“构建注入文本”,不负责写入 extension_prompts
|
||||||
// - 注入发生在 story-summary.js 的 CHAT_COMPLETION_PROMPT_READY(最终 messages 已裁剪)
|
// - 注入发生在 story-summary.js:GENERATION_STARTED 时写入 extension_prompts(IN_CHAT + depth)
|
||||||
// ═══════════════════════════════════════════════════════════════════════════
|
// ═══════════════════════════════════════════════════════════════════════════
|
||||||
|
|
||||||
import { getContext } from "../../../../../../extensions.js";
|
import { getContext } from "../../../../../../extensions.js";
|
||||||
|
|||||||
@@ -6,11 +6,17 @@
|
|||||||
// 2) 关闭隐藏 = 暴力全量 unhide,确保立刻恢复
|
// 2) 关闭隐藏 = 暴力全量 unhide,确保立刻恢复
|
||||||
// 3) 开启隐藏 / 改Y / 切Chat / 收新消息:先全量 unhide,再按边界重新 hide
|
// 3) 开启隐藏 / 改Y / 切Chat / 收新消息:先全量 unhide,再按边界重新 hide
|
||||||
// 4) Prompt 注入位置稳定:永远插在"最后一条 user 消息"之前
|
// 4) Prompt 注入位置稳定:永远插在"最后一条 user 消息"之前
|
||||||
// 5) 注入不依赖 extension_prompts/depth,不受 ST 裁剪/隐藏参照系影响
|
// 5) 注入回归 extension_prompts + IN_CHAT + depth(动态计算)
|
||||||
// ═══════════════════════════════════════════════════════════════════════════
|
// ═══════════════════════════════════════════════════════════════════════════
|
||||||
|
|
||||||
import { getContext } from "../../../../../extensions.js";
|
import { getContext } from "../../../../../extensions.js";
|
||||||
import { eventSource, event_types } from "../../../../../../script.js";
|
import {
|
||||||
|
eventSource,
|
||||||
|
event_types,
|
||||||
|
extension_prompts,
|
||||||
|
extension_prompt_types,
|
||||||
|
extension_prompt_roles,
|
||||||
|
} from "../../../../../../script.js";
|
||||||
import { extensionFolderPath } from "../../core/constants.js";
|
import { extensionFolderPath } from "../../core/constants.js";
|
||||||
import { xbLog, CacheRegistry } from "../../core/debug-core.js";
|
import { xbLog, CacheRegistry } from "../../core/debug-core.js";
|
||||||
import { postToIframe, isTrustedMessage } from "../../core/iframe-messaging.js";
|
import { postToIframe, isTrustedMessage } from "../../core/iframe-messaging.js";
|
||||||
@@ -95,8 +101,6 @@ let vectorGenerating = false;
|
|||||||
let vectorCancelled = false;
|
let vectorCancelled = false;
|
||||||
let vectorAbortController = null;
|
let vectorAbortController = null;
|
||||||
|
|
||||||
let pendingInjectText = "";
|
|
||||||
|
|
||||||
// ★ 用户消息缓存(解决 GENERATION_STARTED 时 chat 尚未包含用户消息的问题)
|
// ★ 用户消息缓存(解决 GENERATION_STARTED 时 chat 尚未包含用户消息的问题)
|
||||||
let lastSentUserMessage = null;
|
let lastSentUserMessage = null;
|
||||||
let lastSentTimestamp = 0;
|
let lastSentTimestamp = 0;
|
||||||
@@ -106,6 +110,8 @@ const HIDE_APPLY_DEBOUNCE_MS = 250;
|
|||||||
|
|
||||||
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
||||||
|
|
||||||
|
const EXT_PROMPT_KEY = "LittleWhiteBox_StorySummary";
|
||||||
|
|
||||||
// ═══════════════════════════════════════════════════════════════════════════
|
// ═══════════════════════════════════════════════════════════════════════════
|
||||||
// 工具:执行斜杠命令
|
// 工具:执行斜杠命令
|
||||||
// ═══════════════════════════════════════════════════════════════════════════
|
// ═══════════════════════════════════════════════════════════════════════════
|
||||||
@@ -1110,6 +1116,10 @@ function handleMessageSentForRecall() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function clearExtensionPrompt() {
|
||||||
|
delete extension_prompts[EXT_PROMPT_KEY];
|
||||||
|
}
|
||||||
|
|
||||||
// ═══════════════════════════════════════════════════════════════════════════
|
// ═══════════════════════════════════════════════════════════════════════════
|
||||||
// Prompt 注入
|
// Prompt 注入
|
||||||
// ═══════════════════════════════════════════════════════════════════════════
|
// ═══════════════════════════════════════════════════════════════════════════
|
||||||
@@ -1121,9 +1131,9 @@ async function handleGenerationStarted(type, _params, isDryRun) {
|
|||||||
const excludeLastAi = type === "swipe" || type === "regenerate";
|
const excludeLastAi = type === "swipe" || type === "regenerate";
|
||||||
const vectorCfg = getVectorConfig();
|
const vectorCfg = getVectorConfig();
|
||||||
|
|
||||||
pendingInjectText = "";
|
clearExtensionPrompt();
|
||||||
|
|
||||||
// ★ 判断是否使用缓存的用户消息(30秒内有效)
|
// ★ 保留:判断是否使用缓存的用户消息(30秒内有效)
|
||||||
let pendingUserMessage = null;
|
let pendingUserMessage = null;
|
||||||
if (type === "normal" && lastSentUserMessage && (Date.now() - lastSentTimestamp < 30000)) {
|
if (type === "normal" && lastSentUserMessage && (Date.now() - lastSentTimestamp < 30000)) {
|
||||||
pendingUserMessage = lastSentUserMessage;
|
pendingUserMessage = lastSentUserMessage;
|
||||||
@@ -1132,51 +1142,50 @@ async function handleGenerationStarted(type, _params, isDryRun) {
|
|||||||
lastSentUserMessage = null;
|
lastSentUserMessage = null;
|
||||||
lastSentTimestamp = 0;
|
lastSentTimestamp = 0;
|
||||||
|
|
||||||
|
const { chat, chatId } = getContext();
|
||||||
|
const chatLen = Array.isArray(chat) ? chat.length : 0;
|
||||||
|
if (chatLen === 0) return;
|
||||||
|
|
||||||
|
const store = getSummaryStore();
|
||||||
|
|
||||||
|
// 1) boundary:
|
||||||
|
// - 向量开:meta.lastChunkFloor(若无则回退 lastSummarizedMesId)
|
||||||
|
// - 向量关:lastSummarizedMesId
|
||||||
|
let boundary = -1;
|
||||||
|
if (vectorCfg?.enabled) {
|
||||||
|
const meta = chatId ? await getMeta(chatId) : null;
|
||||||
|
boundary = meta?.lastChunkFloor ?? -1;
|
||||||
|
if (boundary < 0) boundary = store?.lastSummarizedMesId ?? -1;
|
||||||
|
} else {
|
||||||
|
boundary = store?.lastSummarizedMesId ?? -1;
|
||||||
|
}
|
||||||
|
if (boundary < 0) return;
|
||||||
|
|
||||||
|
// 2) depth:倒序插入,从末尾往前数
|
||||||
|
const depth = chatLen - boundary - 1;
|
||||||
|
if (depth < 0) return;
|
||||||
|
|
||||||
|
// 3) 构建注入文本(保持原逻辑)
|
||||||
|
let text = "";
|
||||||
if (vectorCfg?.enabled) {
|
if (vectorCfg?.enabled) {
|
||||||
const r = await buildVectorPromptText(excludeLastAi, {
|
const r = await buildVectorPromptText(excludeLastAi, {
|
||||||
postToFrame,
|
postToFrame,
|
||||||
echo: executeSlashCommand,
|
echo: executeSlashCommand,
|
||||||
pendingUserMessage,
|
pendingUserMessage,
|
||||||
});
|
});
|
||||||
pendingInjectText = r?.text || "";
|
text = r?.text || "";
|
||||||
return;
|
} else {
|
||||||
|
text = buildNonVectorPromptText() || "";
|
||||||
}
|
}
|
||||||
|
if (!text.trim()) return;
|
||||||
|
|
||||||
pendingInjectText = buildNonVectorPromptText() || "";
|
// 4) 写入 extension_prompts
|
||||||
}
|
extension_prompts[EXT_PROMPT_KEY] = {
|
||||||
|
value: text,
|
||||||
function clearPendingInject() {
|
position: extension_prompt_types.IN_CHAT,
|
||||||
pendingInjectText = "";
|
depth,
|
||||||
}
|
role: extension_prompt_roles.SYSTEM,
|
||||||
|
};
|
||||||
function findInsertIndexBeforeLastUserMessage(chat) {
|
|
||||||
if (!Array.isArray(chat) || !chat.length) return 0;
|
|
||||||
for (let i = chat.length - 1; i >= 0; i--) {
|
|
||||||
if (chat[i]?.role === "user") return i;
|
|
||||||
}
|
|
||||||
// 没有 user,退化为末尾前一位
|
|
||||||
return Math.max(0, chat.length - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleChatCompletionPromptReady(eventData) {
|
|
||||||
try {
|
|
||||||
if (!pendingInjectText?.trim()) return;
|
|
||||||
if (!eventData || eventData.dryRun) return;
|
|
||||||
if (!Array.isArray(eventData.chat)) return;
|
|
||||||
|
|
||||||
// 永远插在最后一条 user 消息之前,保证三段结构稳定
|
|
||||||
const insertAt = findInsertIndexBeforeLastUserMessage(eventData.chat);
|
|
||||||
|
|
||||||
eventData.chat.splice(insertAt, 0, {
|
|
||||||
role: "assistant",
|
|
||||||
content: pendingInjectText,
|
|
||||||
});
|
|
||||||
|
|
||||||
clearPendingInject();
|
|
||||||
} catch (e) {
|
|
||||||
xbLog.error(MODULE_ID, "Prompt inject failed", e);
|
|
||||||
clearPendingInject();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ═══════════════════════════════════════════════════════════════════════════
|
// ═══════════════════════════════════════════════════════════════════════════
|
||||||
@@ -1218,9 +1227,8 @@ function registerEvents() {
|
|||||||
|
|
||||||
// 注入链路
|
// 注入链路
|
||||||
eventSource.on(event_types.GENERATION_STARTED, handleGenerationStarted);
|
eventSource.on(event_types.GENERATION_STARTED, handleGenerationStarted);
|
||||||
eventSource.on(event_types.GENERATION_STOPPED, clearPendingInject);
|
eventSource.on(event_types.GENERATION_STOPPED, clearExtensionPrompt);
|
||||||
eventSource.on(event_types.GENERATION_ENDED, clearPendingInject);
|
eventSource.on(event_types.GENERATION_ENDED, clearExtensionPrompt);
|
||||||
eventSource.on(event_types.CHAT_COMPLETION_PROMPT_READY, handleChatCompletionPromptReady);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function unregisterEvents() {
|
function unregisterEvents() {
|
||||||
@@ -1230,7 +1238,7 @@ function unregisterEvents() {
|
|||||||
$(".xiaobaix-story-summary-btn").remove();
|
$(".xiaobaix-story-summary-btn").remove();
|
||||||
hideOverlay();
|
hideOverlay();
|
||||||
|
|
||||||
clearPendingInject();
|
clearExtensionPrompt();
|
||||||
}
|
}
|
||||||
|
|
||||||
// ═══════════════════════════════════════════════════════════════════════════
|
// ═══════════════════════════════════════════════════════════════════════════
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
const V3_URL = 'https://openspeech.bytedance.com/api/v3/tts/unidirectional';
|
const V3_URL = 'https://openspeech.bytedance.com/api/v3/tts/unidirectional';
|
||||||
const FREE_V1_URL = 'https://hstts.velure.top';
|
const FREE_V1_URL = 'https://hstts.velure.codes';
|
||||||
|
|
||||||
export const FREE_VOICES = [
|
export const FREE_VOICES = [
|
||||||
{ key: 'female_1', name: '桃夭', tag: '甜蜜仙子', gender: 'female' },
|
{ key: 'female_1', name: '桃夭', tag: '甜蜜仙子', gender: 'female' },
|
||||||
|
|||||||
Reference in New Issue
Block a user