Initial commit with CC BY-NC-ND 4.0 license

This commit is contained in:
2026-02-13 09:59:19 +08:00
commit 2c31e1cbc8
140 changed files with 44625 additions and 0 deletions

176
core/utils/context-utils.js Normal file
View File

@@ -0,0 +1,176 @@
'use strict';
const migrationNoticeShown = new Set();
export function getCharacterId() {
const context = SillyTavern.getContext();
if (!context) return null;
if (context.characterId !== undefined && context.characterId !== null) return context.characterId;
if (typeof this_chid !== 'undefined' && this_chid !== null) return this_chid;
if (context.chat && context.chat.length > 0) {
const lastMessage = context.chat[context.chat.length - 1];
if (lastMessage && lastMessage.character_id !== undefined) return lastMessage.character_id;
}
console.error('[翰林院-典籍库] 无法稳定获取当前角色ID。');
return null;
}
export function getChatId() {
const context = SillyTavern.getContext();
if (!context) return null;
if (typeof context.getCurrentChatId === 'function') return context.getCurrentChatId();
if (context.chatId) return context.chatId;
const charId = getCharacterId();
if (charId !== null && context.characters && context.characters[charId]) {
return context.characters[charId].chat;
}
console.error('[翰林院-典籍库] 无法稳定获取当前聊天ID。');
return null;
}
export function getCharacterName() {
const context = SillyTavern.getContext();
if (!context) return '未指定';
const charId = getCharacterId();
if (charId !== null && context.characters && context.characters[charId]) {
return context.characters[charId].name || '未命名角色';
}
return '未指定';
}
export function getCharacterStableId() {
const charName = getCharacterName();
const sanitize = (id) => String(id).replace(/[^a-zA-Z0-9\u4e00-\u9fff_-]/g, '_');
return sanitize(charName);
}
async function checkCollectionData(collectionId) {
if (!collectionId) return false;
const context = SillyTavern.getContext();
if (!context) return false;
try {
const response = await fetch('/api/vector/list', {
method: 'POST',
headers: context.getRequestHeaders(),
body: JSON.stringify({ collectionId, source: 'webllm', embeddings: {} }),
});
if (!response.ok) return false;
const result = await response.json();
if (Array.isArray(result)) return result.length > 0;
if (result && result.hashes) return result.hashes.length > 0;
return false;
} catch (error) {
console.error(`[翰林院-典籍库] 检查集合 ${collectionId} 数据时出错:`, error);
return false;
}
}
function showMigrationNotification(oldId) {
if (migrationNoticeShown.has(oldId)) return;
const tutorialLink = 'https://docs.google.com/document/d/11E7HIFg59up0afv-lV0cAF5G3jzJXCkZK8cBCOMZ9zo/edit?usp=sharing';
const htmlMessage = `
<div class="toast-message-content">
<p>当前使用的是旧版翰林院数据格式,为确保数据稳定,请手动迁移。</p>
<p><strong>如不迁移,后续该角色的向量化操作可能会导致旧数据被清零。</strong></p>
<p>(请挂魔法后打开此链接查看教程)</p>
</div>
`;
const $toast = toastr.warning('', '翰林院数据迁移提醒', {
timeOut: 0,
extendedTimeOut: 0,
closeButton: true,
tapToDismiss: false,
onclick: null,
onShown: function() {
const toastElement = $(this);
const titleElement = toastElement.find('.toast-title');
const messageContainer = $(htmlMessage);
const buttonContainer = $('<div class="mt-2"></div>');
const copyBtn = $('<button class="btn btn-info btn-sm mr-1">复制教程链接</button>');
copyBtn.on('click', (e) => {
e.stopPropagation();
navigator.clipboard.writeText(tutorialLink);
toastr.success('链接已复制到剪贴板');
});
const approveBtn = $('<button class="btn btn-secondary btn-sm">我知道了</button>');
approveBtn.on('click', (e) => {
e.stopPropagation();
toastr.remove($toast);
migrationNoticeShown.add(oldId);
});
buttonContainer.append(copyBtn).append(approveBtn);
if (titleElement.length) {
titleElement.after(messageContainer, buttonContainer);
} else {
toastElement.append(messageContainer, buttonContainer);
}
},
onCloseClick: function() {
migrationNoticeShown.add(oldId);
}
});
migrationNoticeShown.add(oldId);
}
export function getCollectionIdInfo() {
const charId = getCharacterId();
const chatId = getChatId();
const charName = getCharacterName();
const sanitize = (id) => String(id).replace(/[^a-zA-Z0-9\u4e00-\u9fff_-]/g, '_');
let oldCollectionId = null;
if (charId !== null && chatId) {
oldCollectionId = `char_${charId}_chat_${chatId}`;
} else if (charId !== null) {
oldCollectionId = `char_${charId}_global`;
}
const finalOldId = oldCollectionId ? sanitize(oldCollectionId) : null;
let newCollectionId = null;
if (charName !== '未指定' && charName !== '未命名角色' && chatId) {
newCollectionId = `char_${charName}_chat_${chatId}`;
} else if (charName !== '未指定' && charName !== '未命名角色') {
newCollectionId = `char_${charName}_global`;
}
const finalNewId = newCollectionId ? sanitize(newCollectionId) : null;
return { oldId: finalOldId, newId: finalNewId || finalOldId || 'default_collection' };
}
export async function getCollectionId() {
const { oldId, newId } = getCollectionIdInfo();
if (oldId === newId) {
return newId || 'default_collection';
}
if (newId && await checkCollectionData(newId)) {
return newId;
}
if (oldId && await checkCollectionData(oldId)) {
showMigrationNotification(oldId);
return oldId;
}
return newId || 'default_collection';
}

View File

@@ -0,0 +1 @@
function _0x2003(){const _0x262052=['4AcCkkG','Connection\x20successful!\x20API\x20endpoint\x20is\x20valid.','slice','Connection\x20failed:\x20','trim','3177507RNmXZF','API\x20URL\x20or\x20Key\x20is\x20not\x20provided.','1261632VQmIPE','message','localeCompare','GET','Invalid\x20response\x20format\x20from\x20models\x20API:\x20\x27data\x27\x20array\x20not\x20found.','status','2134198faGeNE','endsWith','text','85127EohiQl','isArray','3221840BInRET','11buyHDb','765zvzuyQ','sort','Failed\x20to\x20fetch\x20models\x20(','json','17129510bPrLGT','750rkDFpM','/v1/models','114088qjSqPj','application/json','data'];_0x2003=function(){return _0x262052;};return _0x2003();}(function(_0x55af80,_0x2d43e0){const _0x33592e=_0x4686,_0x47d490=_0x55af80();while(!![]){try{const _0x2e369a=-parseInt(_0x33592e(0x13f))/0x1+parseInt(_0x33592e(0x145))/0x2+parseInt(_0x33592e(0x13d))/0x3*(-parseInt(_0x33592e(0x138))/0x4)+parseInt(_0x33592e(0x14a))/0x5+-parseInt(_0x33592e(0x133))/0x6*(parseInt(_0x33592e(0x148))/0x7)+-parseInt(_0x33592e(0x135))/0x8*(-parseInt(_0x33592e(0x14c))/0x9)+parseInt(_0x33592e(0x132))/0xa*(parseInt(_0x33592e(0x14b))/0xb);if(_0x2e369a===_0x2d43e0)break;else _0x47d490['push'](_0x47d490['shift']());}catch(_0x54cbc4){_0x47d490['push'](_0x47d490['shift']());}}}(_0x2003,0xc241d));function getSanitizedBaseUrl(_0x290691){const _0x2e6701=_0x4686;let _0x507aff=_0x290691[_0x2e6701(0x13c)]();return _0x507aff[_0x2e6701(0x146)]('/')&&(_0x507aff=_0x507aff[_0x2e6701(0x13a)](0x0,-0x1)),_0x507aff[_0x2e6701(0x146)]('/v1')&&(_0x507aff=_0x507aff['slice'](0x0,-0x3)),_0x507aff;}function _0x4686(_0x4a70e4,_0x38094a){const _0x200337=_0x2003();return _0x4686=function(_0x468631,_0x2e7f16){_0x468631=_0x468631-0x131;let _0x3828ba=_0x200337[_0x468631];return _0x3828ba;},_0x4686(_0x4a70e4,_0x38094a);}export async function fetchEmbeddingModels(_0x112441,_0x27b76c){const _0xaa1738=_0x4686;if(!_0x112441||!_0x27b76c)throw new Error(_0xaa1738(0x13e));const _0x5f1807=getSanitizedBaseUrl(_0x112441),_0x517e35=_0x5f1807+_0xaa1738(0x134);console['log']('[Embedding\x20Adapter]\x20Fetching\x20models\x20from:\x20'+_0x517e35);const _0x4da766=await fetch(_0x517e35,{'method':_0xaa1738(0x142),'headers':{'Authorization':'Bearer\x20'+_0x27b76c,'Content-Type':_0xaa1738(0x136)}});if(!_0x4da766['ok']){const _0x48ce89=await _0x4da766[_0xaa1738(0x147)]();throw new Error(_0xaa1738(0x14e)+_0x4da766[_0xaa1738(0x144)]+'):\x20'+_0x48ce89);}const _0x5dbdf4=await _0x4da766[_0xaa1738(0x131)]();if(!_0x5dbdf4[_0xaa1738(0x137)]||!Array[_0xaa1738(0x149)](_0x5dbdf4['data']))throw new Error(_0xaa1738(0x143));return _0x5dbdf4[_0xaa1738(0x137)][_0xaa1738(0x14d)]((_0x2acdad,_0x4efac8)=>_0x2acdad['id'][_0xaa1738(0x141)](_0x4efac8['id']));}export async function testEmbeddingConnection(_0x981051,_0x456762){const _0x2ef137=_0x4686;try{return await fetchEmbeddingModels(_0x981051,_0x456762),{'success':!![],'message':_0x2ef137(0x139)};}catch(_0x5d7faf){return console['error']('[Embedding\x20Adapter]\x20Connection\x20test\x20failed:',_0x5d7faf),{'success':![],'message':_0x2ef137(0x13b)+_0x5d7faf[_0x2ef137(0x140)]};}}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long