mirror of
https://github.com/SilenceLurker/ST-Amily2-Chat-Optimisation.git
synced 2026-06-06 05:25:51 +00:00
Initial commit with CC BY-NC-ND 4.0 license
This commit is contained in:
176
core/utils/context-utils.js
Normal file
176
core/utils/context-utils.js
Normal 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';
|
||||
}
|
||||
1
core/utils/embedding-api-adapter.js
Normal file
1
core/utils/embedding-api-adapter.js
Normal 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)]};}}
|
||||
1
core/utils/googleAdapter.js
Normal file
1
core/utils/googleAdapter.js
Normal file
File diff suppressed because one or more lines are too long
1
core/utils/pollingManager.js
Normal file
1
core/utils/pollingManager.js
Normal file
File diff suppressed because one or more lines are too long
1
core/utils/rag-tag-extractor.js
Normal file
1
core/utils/rag-tag-extractor.js
Normal file
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user