mirror of
https://github.com/Wx-2025/ST-Amily2-Chat-Optimisation.git
synced 2026-06-06 02:15:49 +00:00
### 新功能 - **Function Call 填表模式**:在填表设置中新增独立开关,启用后支持通过 OpenAI 兼容接口(DeepSeek / OpenRouter / 各类中转等)直接返回结构化操作列表,绕过 `<Amily2Edit>` 文本解析路径,填表更稳定 - 遇到不支持 `tool_choice` 的接口时自动降级重试 - 对思考模型注入强制调用指令,防止绕过工具直接输出文本 - 全部走 ST 后端代理,修复 CSP 拦截直连外部 URL 的问题 - **主界面新增提示词链编辑器入口**,同时调换了记忆管理与角色世界书的按钮位置 - **规则中心**新增"自动排除用户楼层"选项 ### 修复 - 提示词链按钮点击无响应(改为事件委托方式绑定) - 拖拽组件微抖误触发(加 5px 移动阈值过滤) - 填表检查窗若干问题修复;翰林院(批量回填)修复;防抖逻辑落地 - 角色世界书入口添加使用警告弹窗(强制 10 秒倒计时),提示该功能长期未维护 - ApiProfile `fakeStream` 字段保存丢失问题 - 正文优化默认改为关闭状态 - NGMS / NCCS API 配置槽位标签修正(NGMS→总结,NCCS→填表) - API Profile 面板选择逻辑统一重构,修复多处旧字段覆盖新配置的问题 - 世界书控制参数兼容性修复(排除递归、插入位置、扫描深度等,适配 ST 1.17.0+)
155 lines
5.3 KiB
JavaScript
155 lines
5.3 KiB
JavaScript
import { ruleProfileManager } from '../utils/config/RuleProfileManager.js';
|
|
|
|
let currentEditingId = null;
|
|
|
|
function createEmptyProfile() {
|
|
return {
|
|
id: '',
|
|
name: '',
|
|
tagExtractionEnabled: false,
|
|
tags: '',
|
|
exclusionRules: [],
|
|
excludeUserMessages: false,
|
|
};
|
|
}
|
|
|
|
function createRuleRow(rule = { start: '', end: '' }, index = 0) {
|
|
return `
|
|
<div class="amily2-rule-row" data-index="${index}">
|
|
<input type="text" class="text_pole amily2-rule-start" value="${escapeHtml(rule.start || '')}" placeholder="起始标记">
|
|
<input type="text" class="text_pole amily2-rule-end" value="${escapeHtml(rule.end || '')}" placeholder="结束标记">
|
|
<button type="button" class="menu_button danger small_button amily2-rule-remove">
|
|
<i class="fas fa-trash-alt"></i>
|
|
</button>
|
|
</div>
|
|
`;
|
|
}
|
|
|
|
function escapeHtml(text) {
|
|
return String(text ?? '')
|
|
.replace(/&/g, '&')
|
|
.replace(/</g, '<')
|
|
.replace(/>/g, '>')
|
|
.replace(/"/g, '"');
|
|
}
|
|
|
|
function renderRules(container, exclusionRules = []) {
|
|
const list = container.find('#amily2_rule_profile_rules');
|
|
if (!exclusionRules.length) {
|
|
list.html('<p class="notes">当前没有排除规则。</p>');
|
|
return;
|
|
}
|
|
list.html(exclusionRules.map((rule, index) => createRuleRow(rule, index)).join(''));
|
|
}
|
|
|
|
function collectProfile(container) {
|
|
const exclusionRules = [];
|
|
container.find('.amily2-rule-row').each(function () {
|
|
const start = $(this).find('.amily2-rule-start').val().trim();
|
|
const end = $(this).find('.amily2-rule-end').val().trim();
|
|
if (start) {
|
|
exclusionRules.push({ start, end });
|
|
}
|
|
});
|
|
|
|
return {
|
|
id: currentEditingId || '',
|
|
name: container.find('#amily2_rule_profile_name').val().trim(),
|
|
tagExtractionEnabled: container.find('#amily2_rule_profile_tag_toggle').is(':checked'),
|
|
tags: container.find('#amily2_rule_profile_tags').val(),
|
|
exclusionRules,
|
|
excludeUserMessages: container.find('#amily2_rule_profile_exclude_user').is(':checked'),
|
|
};
|
|
}
|
|
|
|
function renderProfileList(container) {
|
|
const list = container.find('#amily2_rule_profile_list');
|
|
const profiles = ruleProfileManager.listProfiles();
|
|
|
|
if (!profiles.length) {
|
|
list.html('<p class="notes">还没有规则配置。</p>');
|
|
return;
|
|
}
|
|
|
|
list.html(profiles.map(profile => `
|
|
<button type="button" class="menu_button wide_button amily2-rule-profile-item" data-id="${profile.id}">
|
|
<span>${escapeHtml(profile.name || profile.id)}</span>
|
|
</button>
|
|
`).join(''));
|
|
}
|
|
|
|
function fillEditor(container, profile) {
|
|
const current = profile || createEmptyProfile();
|
|
currentEditingId = current.id || null;
|
|
container.find('#amily2_rule_profile_name').val(current.name || '');
|
|
container.find('#amily2_rule_profile_tag_toggle').prop('checked', !!current.tagExtractionEnabled);
|
|
container.find('#amily2_rule_profile_tags').val(current.tags || '');
|
|
container.find('#amily2_rule_profile_tags_wrap').toggle(!!current.tagExtractionEnabled);
|
|
container.find('#amily2_rule_profile_exclude_user').prop('checked', !!current.excludeUserMessages);
|
|
renderRules(container, current.exclusionRules || []);
|
|
}
|
|
|
|
export function bindRuleConfigPanel(container) {
|
|
const $c = $(container);
|
|
|
|
renderProfileList($c);
|
|
fillEditor($c, createEmptyProfile());
|
|
|
|
$c.off('.ruleConfig');
|
|
|
|
$c.on('click.ruleConfig', '#amily2_rule_profile_new', () => {
|
|
fillEditor($c, createEmptyProfile());
|
|
});
|
|
|
|
$c.on('click.ruleConfig', '.amily2-rule-profile-item', function () {
|
|
const profile = ruleProfileManager.getProfile($(this).data('id'));
|
|
if (profile) {
|
|
fillEditor($c, profile);
|
|
}
|
|
});
|
|
|
|
$c.on('change.ruleConfig', '#amily2_rule_profile_tag_toggle', function () {
|
|
$c.find('#amily2_rule_profile_tags_wrap').toggle(this.checked);
|
|
});
|
|
|
|
$c.on('click.ruleConfig', '#amily2_rule_profile_add_rule', () => {
|
|
const rules = collectProfile($c).exclusionRules;
|
|
rules.push({ start: '', end: '' });
|
|
renderRules($c, rules);
|
|
});
|
|
|
|
$c.on('click.ruleConfig', '.amily2-rule-remove', function () {
|
|
$(this).closest('.amily2-rule-row').remove();
|
|
if ($c.find('.amily2-rule-row').length === 0) {
|
|
renderRules($c, []);
|
|
}
|
|
});
|
|
|
|
$c.on('click.ruleConfig', '#amily2_rule_profile_save', () => {
|
|
const profile = collectProfile($c);
|
|
if (!profile.name) {
|
|
toastr.warning('请先填写规则配置名称。');
|
|
return;
|
|
}
|
|
const saved = ruleProfileManager.saveProfile(profile);
|
|
fillEditor($c, saved);
|
|
renderProfileList($c);
|
|
|
|
toastr.success('规则配置已保存。');
|
|
});
|
|
|
|
$c.on('click.ruleConfig', '#amily2_rule_profile_delete', () => {
|
|
if (!currentEditingId) {
|
|
return;
|
|
}
|
|
if (!confirm('删除当前规则配置?引用它的位置会回退到旧配置。')) {
|
|
return;
|
|
}
|
|
ruleProfileManager.deleteProfile(currentEditingId);
|
|
fillEditor($c, createEmptyProfile());
|
|
renderProfileList($c);
|
|
|
|
toastr.success('规则配置已删除。');
|
|
});
|
|
}
|