release: v2.2.2 [2026-05-27 11:10:55]

### 新功能
- **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+)
This commit is contained in:
Jenkins CI
2026-05-27 11:10:55 +08:00
parent e00302d04b
commit 2c3072a3d8
29 changed files with 865 additions and 125 deletions

View File

@@ -29,6 +29,7 @@ import { extensionName } from '../../utils/settings.js';
import { log } from './logger.js';
import { executeCommands } from './executor.js';
import { applyOperations } from './actions/applyOperations.js';
import { fillWithSecondaryApi } from './secondary-filler.js';
import { renderTables } from '../../ui/table-bindings.js';
import { updateOrInsertTableInChat } from '../../ui/message-table-renderer.js';
@@ -874,6 +875,65 @@ export async function updateTableFromText(textContent, options = {}) {
document.dispatchEvent(new CustomEvent('amily2-force-ui-reload'));
}
/**
* 直接从 Operation[] 应用变更Function Call 路径),跳过文本解析。
* 后续流程与 updateTableFromText 完全一致。
*
* @param {import('./dto/Operation.js').Operation[]} ops
* @param {Object} options - 同 updateTableFromText 的 options
*/
export async function updateTableFromOps(ops, options = {}) {
const settings = extension_settings[extensionName] || {};
if (settings.table_system_enabled === false) return;
if (!Array.isArray(ops) || ops.length === 0) {
log('Function Call 返回操作列表为空,无需更新表格。', 'info');
return;
}
const { state, changes } = applyOperations(getState(), ops);
if (changes.length === 0) {
log('Function Call 操作未产生任何实质性变更。', 'info');
return;
}
setState(state);
if (options.immediateDelete) {
commitPendingDeletions();
}
changes.forEach(change => {
markTableUpdated(change.tableIndex);
if (change.type === 'update' || change.type === 'insert') {
if (change.rowIndex !== undefined && change.colIndex !== undefined) {
addHighlight(change.tableIndex, change.rowIndex, change.colIndex);
}
}
});
log(`Function Call 成功执行了 ${changes.length} 处变更。`, 'success');
const affectedTables = [...new Set(changes.map(c => c.tableIndex))];
affectedTables.forEach(tableIndex => dispatchTableUpdate(tableIndex));
const context = getContext();
if (context.chat && context.chat.length > 0) {
const lastMessage = context.chat[context.chat.length - 1];
if (_persistSaveStateToMessage(getState(), lastMessage)) {
await saveChat();
toastr.success('已根据AI的指示成功更新表格', '填表完成');
document.dispatchEvent(new CustomEvent('amily2-force-ui-reload'));
return;
}
}
saveChatDebounced();
toastr.success('已根据AI的指示成功更新表格', '填表完成');
document.dispatchEvent(new CustomEvent('amily2-force-ui-reload'));
}
// ── 预设re-export 或 wrapper ─────────────────────────────────────────
export const exportPreset = _presetExportPreset;