@musnows/scriverse 1.0.5 → 1.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ai-tool-results.js +14 -8
- package/dist/ai-tool-results.js.map +1 -1
- package/dist/ai.js +33 -19
- package/dist/ai.js.map +1 -1
- package/dist/app.js +5 -2
- package/dist/app.js.map +1 -1
- package/dist/public/app.js +66 -15
- package/dist/public/icon-dev.svg +10 -0
- package/dist/public/index.html +2 -1
- package/dist/store.js +7 -7
- package/dist/store.js.map +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
package/dist/public/app.js
CHANGED
|
@@ -5393,6 +5393,26 @@ function addSelectedLinesAsCitation() {
|
|
|
5393
5393
|
toast(`已引用《${citation.chapterTitle}》第 ${citation.startLine}${citation.startLine === citation.endLine ? "" : `-${citation.endLine}`} 行`);
|
|
5394
5394
|
}
|
|
5395
5395
|
|
|
5396
|
+
function addChapterAsAiReference(chapterId) {
|
|
5397
|
+
if (!state.work || !canWritePermissionModule(state.work, "ai-chat")) return toast("当前账户没有创作助手编辑权限", "error");
|
|
5398
|
+
const volume = state.work.volumes.find((item) => item.chapters.some((chapter) => chapter.id === chapterId));
|
|
5399
|
+
const chapter = volume?.chapters.find((item) => item.id === chapterId);
|
|
5400
|
+
if (!volume || !chapter) return toast("章节不存在或已被删除", "error");
|
|
5401
|
+
const reference = { kind: "chapter", id: String(chapter.id), name: `${volume.title} / ${chapter.title}` };
|
|
5402
|
+
if (state.aiReferences.some((item) => aiReferenceKey(item) === aiReferenceKey(reference))) {
|
|
5403
|
+
ensureAiPanelExpanded();
|
|
5404
|
+
renderAiReferences();
|
|
5405
|
+
return toast(`《${chapter.title}》已在助手引用中`);
|
|
5406
|
+
}
|
|
5407
|
+
const chapterReferenceCount = state.aiReferences.filter((item) => item.kind === "chapter").length;
|
|
5408
|
+
if (chapterReferenceCount >= 20) return toast("一次最多添加 20 个章节助手引用", "error");
|
|
5409
|
+
state.aiReferences.push(reference);
|
|
5410
|
+
ensureAiPanelExpanded();
|
|
5411
|
+
renderAiReferences();
|
|
5412
|
+
persistActiveAiChatTab();
|
|
5413
|
+
toast(`已将《${chapter.title}》添加到助手引用`);
|
|
5414
|
+
}
|
|
5415
|
+
|
|
5396
5416
|
async function createSelectedLineAnnotation(kind) {
|
|
5397
5417
|
const permissionModule = kind === "todo" ? "todos" : "comments";
|
|
5398
5418
|
if (!state.chapter || !chapterLineSelection || !canWritePermissionModule(state.work, permissionModule)) return;
|
|
@@ -5909,6 +5929,7 @@ function createClientError(payload, fallbackMessage, fallbackStatus = null) {
|
|
|
5909
5929
|
const error = new Error(typeof source.message === "string" ? source.message : fallbackMessage);
|
|
5910
5930
|
error.code = typeof source.code === "string" ? source.code : undefined;
|
|
5911
5931
|
error.status = Number.isInteger(source.status) ? source.status : fallbackStatus;
|
|
5932
|
+
error.failureOrigin = source.failureOrigin === "platform" || source.failureOrigin === "provider" ? source.failureOrigin : undefined;
|
|
5912
5933
|
error.details = source.details;
|
|
5913
5934
|
error.failure = typeof source.failure === "string" ? source.failure : undefined;
|
|
5914
5935
|
error.callId = typeof source.callId === "string" ? source.callId : undefined;
|
|
@@ -5946,21 +5967,31 @@ function formatAiFailureMessage(error) {
|
|
|
5946
5967
|
const providerName = typeof error?.providerName === "string" ? error.providerName : typeof details.providerName === "string" ? details.providerName : "";
|
|
5947
5968
|
const providerId = typeof error?.providerId === "string" ? error.providerId : typeof details.providerId === "string" ? details.providerId : "";
|
|
5948
5969
|
const modelId = typeof error?.modelId === "string" ? error.modelId : typeof details.modelId === "string" ? details.modelId : "";
|
|
5970
|
+
const failureOrigin = aiFailureOrigin(error, details);
|
|
5971
|
+
const providerLabel = providerName || providerId;
|
|
5949
5972
|
if (code) lines.push(`错误码:${code}`);
|
|
5950
|
-
|
|
5973
|
+
lines.push(`错误来源:${failureOrigin === "provider" ? `LLM 供应商${providerLabel ? `(${providerLabel})` : ""}` : "叙界平台"}`);
|
|
5974
|
+
if (status) lines.push(`叙界响应状态:HTTP ${status}`);
|
|
5951
5975
|
if (details.platformLimited === true) {
|
|
5952
5976
|
const limitSource = details.limitScope === "provider"
|
|
5953
5977
|
? `配置的供应商额度${providerName ? `(${providerName})` : ""}`
|
|
5954
5978
|
: "单个小说额度";
|
|
5955
5979
|
lines.push(`叙界平台限制来源:${limitSource}`);
|
|
5956
5980
|
}
|
|
5957
|
-
if (
|
|
5958
|
-
if (modelId) lines.push(
|
|
5981
|
+
if (failureOrigin === "platform" && providerLabel) lines.push(`请求模型供应商:${providerLabel}`);
|
|
5982
|
+
if (modelId) lines.push(`请求模型 ID:${modelId}`);
|
|
5959
5983
|
if (callId) lines.push(`调用 ID:${callId}`);
|
|
5960
|
-
if (failure && failure !== message) lines.push(
|
|
5984
|
+
if (failure && failure !== message) lines.push(`${failureOrigin === "provider" ? "LLM 供应商详情" : "平台详情"}:${failure}`);
|
|
5961
5985
|
return lines.join("\n");
|
|
5962
5986
|
}
|
|
5963
5987
|
|
|
5988
|
+
function aiFailureOrigin(error, details) {
|
|
5989
|
+
if (error?.failureOrigin === "platform" || error?.failureOrigin === "provider") return error.failureOrigin;
|
|
5990
|
+
if (details.failureOrigin === "platform" || details.failureOrigin === "provider") return details.failureOrigin;
|
|
5991
|
+
if (details.platformLimited === true || error?.code !== "AI_CALL_FAILED") return "platform";
|
|
5992
|
+
return "provider";
|
|
5993
|
+
}
|
|
5994
|
+
|
|
5964
5995
|
function aiFailureMessageMetadata(error) {
|
|
5965
5996
|
const details = error?.details && typeof error.details === "object" && !Array.isArray(error.details) ? error.details : {};
|
|
5966
5997
|
return {
|
|
@@ -6074,6 +6105,12 @@ function invalidateModuleRequestsAfterMutation(path, method) {
|
|
|
6074
6105
|
function applyProductHealthMetadata(health) {
|
|
6075
6106
|
const version = String(health?.version ?? "").trim();
|
|
6076
6107
|
const versionLabel = String(health?.versionLabel ?? "").trim();
|
|
6108
|
+
const iconPath = health?.development === true ? "/icon-dev.svg?v=20260910" : "/icon.svg?v=20260712";
|
|
6109
|
+
document.querySelectorAll(".brand-mark").forEach((element) => {
|
|
6110
|
+
element.src = iconPath;
|
|
6111
|
+
});
|
|
6112
|
+
const favicon = document.querySelector('link[rel="icon"]');
|
|
6113
|
+
if (favicon) favicon.href = iconPath;
|
|
6077
6114
|
document.querySelectorAll("[data-product-footer-version]").forEach((element) => {
|
|
6078
6115
|
element.textContent = versionLabel || (version ? `v${version}` : "v—");
|
|
6079
6116
|
});
|
|
@@ -8833,10 +8870,17 @@ function renderTree() {
|
|
|
8833
8870
|
}
|
|
8834
8871
|
});
|
|
8835
8872
|
button.addEventListener("contextmenu", (event) => {
|
|
8836
|
-
if (!canEditProse()) return;
|
|
8873
|
+
if (!canEditProse() && !canWritePermissionModule(state.work, "ai-chat")) return;
|
|
8837
8874
|
event.preventDefault();
|
|
8838
8875
|
openChapterTypeMenu(button.dataset.chapterId, event.clientX, event.clientY);
|
|
8839
8876
|
});
|
|
8877
|
+
button.addEventListener("keydown", (event) => {
|
|
8878
|
+
if (!canEditProse() && !canWritePermissionModule(state.work, "ai-chat")) return;
|
|
8879
|
+
if (event.key !== "ContextMenu" && !(event.shiftKey && event.key === "F10")) return;
|
|
8880
|
+
event.preventDefault();
|
|
8881
|
+
const rect = button.getBoundingClientRect();
|
|
8882
|
+
openChapterTypeMenu(button.dataset.chapterId, rect.left, rect.bottom);
|
|
8883
|
+
});
|
|
8840
8884
|
if (proseEditable) {
|
|
8841
8885
|
button.addEventListener("dragstart", (event) => {
|
|
8842
8886
|
event.dataTransfer?.setData("text/plain", button.dataset.chapterId);
|
|
@@ -9059,7 +9103,11 @@ function openChapterTypeMenu(chapterId, clientX, clientY) {
|
|
|
9059
9103
|
if (!chapter) return;
|
|
9060
9104
|
state.contextChapterId = chapterId;
|
|
9061
9105
|
const menu = $("#chapter-type-menu");
|
|
9062
|
-
|
|
9106
|
+
const canManageChapter = canEditProse();
|
|
9107
|
+
const canAddAiReference = canWritePermissionModule(state.work, "ai-chat");
|
|
9108
|
+
menu.querySelector("strong").textContent = `操作“${chapter.title}”`;
|
|
9109
|
+
menu.querySelectorAll("[data-chapter-type], [data-delete-chapter]").forEach((button) => button.classList.toggle("hidden", !canManageChapter));
|
|
9110
|
+
menu.querySelector("[data-add-chapter-ai-reference]")?.classList.toggle("hidden", !canAddAiReference);
|
|
9063
9111
|
menu.querySelectorAll("[data-chapter-type]").forEach((button) => {
|
|
9064
9112
|
button.classList.toggle("active", button.dataset.chapterType === (chapter.chapterType || "正文"));
|
|
9065
9113
|
button.setAttribute("aria-checked", String(button.classList.contains("active")));
|
|
@@ -13973,7 +14021,7 @@ async function renderBookAiSettings() {
|
|
|
13973
14021
|
const remoteMcpStatusText = remoteMcpServers.length > 0
|
|
13974
14022
|
? `已验证 ${remoteMcpServers.length} 个远程 MCP Server,共发现 ${remoteMcpToolCount} 个工具。`
|
|
13975
14023
|
: "尚未配置远程 MCP Server。";
|
|
13976
|
-
const maximumAgentToolCallLimit = Math.max(
|
|
14024
|
+
const maximumAgentToolCallLimit = Math.max(10, Number(settings.agentToolCallLimitMaximum) || 300);
|
|
13977
14025
|
const agentTools = new Set(settings.agentTools ?? ["story_index", "read_chapters", "grep", "search_story_entities", "read_character_sections", "search_drafts", "image", "calculate_time"]);
|
|
13978
14026
|
const dailyTokenQuota = settings.dailyTokenQuota === null ? null : Number(settings.dailyTokenQuota);
|
|
13979
14027
|
const quotaUsedTokens = Number(usage?.quota?.usedTokens) || 0;
|
|
@@ -13995,7 +14043,7 @@ async function renderBookAiSettings() {
|
|
|
13995
14043
|
host.innerHTML = `<section class="config-section">${tokenUsageOverviewMarkup(usage, {
|
|
13996
14044
|
title: "本书 Token 用量",
|
|
13997
14045
|
description: `仅统计《${state.work.title}》迄今产生的 AI Token 消耗与缓存命中情况。`
|
|
13998
|
-
})}</section><section class="config-section"><div class="config-section-header"><div><h2>每日 Token 额度</h2><p>限制本书在后端部署时区(${esc(quotaTimezone)})每个自然日可使用的输入与输出 Token 总量。额度必须设置为大于 0 的整数;低于 10,000 时仅提示风险;达到额度后,新的 AI 请求会等到后端时区的次日零点重置后再执行。</p></div></div><div class="config-inline-save"><label class="checkbox-field config-checkbox-field"><input id="daily-token-quota-enabled" type="checkbox" ${dailyTokenQuota === null ? "" : "checked"}>启用每日额度</label><label class="daily-token-quota-field">每日额度<input id="daily-token-quota" type="number" min="1" max="2000000000" step="1" value="${esc(String(dailyTokenQuota ?? 10000))}" aria-label="本书每日 Token 额度" ${dailyTokenQuota === null ? "disabled" : ""}></label><button id="save-daily-token-quota" class="ghost-button config-save-button" type="button">保存</button></div><p id="daily-token-quota-status" class="usage-measurement-note" role="status">${esc(quotaStatusText)}</p></section><section class="config-section"><div class="config-section-header"><div><h2>本书系统提示词</h2><p>会追加在内置系统提示词和平台全局系统提示词之后,只影响《${esc(state.work.title)}》的 AI 请求。</p></div></div><div class="field-label"><textarea id="work-system-prompt" rows="8" aria-label="本书系统提示词" placeholder="例如:叙事使用第三人称,哥斯拉不得离开地球。">${esc(settings.systemPrompt)}</textarea></div><div class="card-actions"><button id="save-work-system-prompt" class="ghost-button config-save-button" type="button">保存本书提示词</button></div></section><section class="config-section"><div class="config-section-header"><div><h2>人物关系拼音索引</h2><p>平时由系统记录增量任务;“同步增量队列”只处理发生变化的来源,“完整重建索引”会将本书全部正文和设定来源重新排队。</p></div></div><div id="relationship-search-index-status" role="status" aria-live="polite">${relationshipIndexStatusMarkup(relationshipIndex)}</div><div class="relationship-index-actions"><button id="sync-relationship-search-index" class="primary-button config-save-button" type="button">同步增量队列</button><button id="refresh-relationship-search-index" class="ghost-button" type="button">刷新状态</button><button id="rebuild-relationship-search-index" class="ghost-button config-save-button" type="button">完整重建索引</button></div></section><section class="config-section"><div class="config-section-header"><div><h2>全书概要引用配额</h2><p>引用全书概要时按分卷保留覆盖,并优先加入与当前问题相关的章节概要;该比例控制概要可使用的上下文预算。</p></div></div><div class="config-inline-save"><label class="book-summary-context-percent-field">上下文占比(%)<input id="book-summary-context-percent" type="number" min="1" max="90" value="${esc(String(settings.bookSummaryContextPercent ?? 50))}" aria-label="全书概要引用上下文占比"></label><button id="save-book-summary-context-percent" class="ghost-button config-save-button" type="button">保存</button></div></section><section class="config-section"><div class="config-section-header"><div><h2>对话上下文 Compact</h2><p>该阈值按对话历史的独立预算计算,用于显示可选择压缩或忽略的提醒;整次请求达到模型上下文窗口 95% 时仍会强制压缩较早消息,并尽量保留最近八条原文。</p></div></div><div class="config-inline-save"><label class="context-compact-threshold-field">Compact 阈值(%)<input id="context-compact-threshold" type="number" min="50" max="90" value="${esc(String(settings.contextCompactThreshold ?? 85))}" aria-label="对话上下文 compact 阈值"></label><button id="save-context-compact-threshold" class="ghost-button config-save-button" type="button">保存</button></div></section><section class="config-section"><div class="config-section-header"><div><h2>设定上下文注入</h2><p>开启后,本书的普通 AI 请求会自动注入锁定设定、组织、种族与相关约束;即使本轮同时使用“@注入上下文设定”,也只会注入一次。</p></div></div><div class="config-inline-save"><label class="checkbox-field config-checkbox-field"><input id="always-include-setting-info" type="checkbox" ${settings.alwaysIncludeSettingInfo ? "checked" : ""}>是否注入设定</label><button id="save-always-include-setting-info" class="ghost-button config-save-button" type="button">保存</button></div></section><section class="config-section"><div class="config-section-header"><div><h2>Agent 工具调用上限</h2><p>限制单次回答里 Agent 可调用工具的次数,并用「全局倍数」给整次回答加一道不会因 Compact 重置的熔断阀,防止工具死循环空耗 Token。调用上限
|
|
14046
|
+
})}</section><section class="config-section"><div class="config-section-header"><div><h2>每日 Token 额度</h2><p>限制本书在后端部署时区(${esc(quotaTimezone)})每个自然日可使用的输入与输出 Token 总量。额度必须设置为大于 0 的整数;低于 10,000 时仅提示风险;达到额度后,新的 AI 请求会等到后端时区的次日零点重置后再执行。</p></div></div><div class="config-inline-save"><label class="checkbox-field config-checkbox-field"><input id="daily-token-quota-enabled" type="checkbox" ${dailyTokenQuota === null ? "" : "checked"}>启用每日额度</label><label class="daily-token-quota-field">每日额度<input id="daily-token-quota" type="number" min="1" max="2000000000" step="1" value="${esc(String(dailyTokenQuota ?? 10000))}" aria-label="本书每日 Token 额度" ${dailyTokenQuota === null ? "disabled" : ""}></label><button id="save-daily-token-quota" class="ghost-button config-save-button" type="button">保存</button></div><p id="daily-token-quota-status" class="usage-measurement-note" role="status">${esc(quotaStatusText)}</p></section><section class="config-section"><div class="config-section-header"><div><h2>本书系统提示词</h2><p>会追加在内置系统提示词和平台全局系统提示词之后,只影响《${esc(state.work.title)}》的 AI 请求。</p></div></div><div class="field-label"><textarea id="work-system-prompt" rows="8" aria-label="本书系统提示词" placeholder="例如:叙事使用第三人称,哥斯拉不得离开地球。">${esc(settings.systemPrompt)}</textarea></div><div class="card-actions"><button id="save-work-system-prompt" class="ghost-button config-save-button" type="button">保存本书提示词</button></div></section><section class="config-section"><div class="config-section-header"><div><h2>人物关系拼音索引</h2><p>平时由系统记录增量任务;“同步增量队列”只处理发生变化的来源,“完整重建索引”会将本书全部正文和设定来源重新排队。</p></div></div><div id="relationship-search-index-status" role="status" aria-live="polite">${relationshipIndexStatusMarkup(relationshipIndex)}</div><div class="relationship-index-actions"><button id="sync-relationship-search-index" class="primary-button config-save-button" type="button">同步增量队列</button><button id="refresh-relationship-search-index" class="ghost-button" type="button">刷新状态</button><button id="rebuild-relationship-search-index" class="ghost-button config-save-button" type="button">完整重建索引</button></div></section><section class="config-section"><div class="config-section-header"><div><h2>全书概要引用配额</h2><p>引用全书概要时按分卷保留覆盖,并优先加入与当前问题相关的章节概要;该比例控制概要可使用的上下文预算。</p></div></div><div class="config-inline-save"><label class="book-summary-context-percent-field">上下文占比(%)<input id="book-summary-context-percent" type="number" min="1" max="90" value="${esc(String(settings.bookSummaryContextPercent ?? 50))}" aria-label="全书概要引用上下文占比"></label><button id="save-book-summary-context-percent" class="ghost-button config-save-button" type="button">保存</button></div></section><section class="config-section"><div class="config-section-header"><div><h2>对话上下文 Compact</h2><p>该阈值按对话历史的独立预算计算,用于显示可选择压缩或忽略的提醒;整次请求达到模型上下文窗口 95% 时仍会强制压缩较早消息,并尽量保留最近八条原文。</p></div></div><div class="config-inline-save"><label class="context-compact-threshold-field">Compact 阈值(%)<input id="context-compact-threshold" type="number" min="50" max="90" value="${esc(String(settings.contextCompactThreshold ?? 85))}" aria-label="对话上下文 compact 阈值"></label><button id="save-context-compact-threshold" class="ghost-button config-save-button" type="button">保存</button></div></section><section class="config-section"><div class="config-section-header"><div><h2>设定上下文注入</h2><p>开启后,本书的普通 AI 请求会自动注入锁定设定、组织、种族与相关约束;即使本轮同时使用“@注入上下文设定”,也只会注入一次。</p></div></div><div class="config-inline-save"><label class="checkbox-field config-checkbox-field"><input id="always-include-setting-info" type="checkbox" ${settings.alwaysIncludeSettingInfo ? "checked" : ""}>是否注入设定</label><button id="save-always-include-setting-info" class="ghost-button config-save-button" type="button">保存</button></div></section><section class="config-section"><div class="config-section-header"><div><h2>Agent 工具调用上限</h2><p>限制单次回答里 Agent 可调用工具的次数,并用「全局倍数」给整次回答加一道不会因 Compact 重置的熔断阀,防止工具死循环空耗 Token。调用上限 10–${maximumAgentToolCallLimit}(默认 20);全局倍数 1–6(默认 3,全局上限 = 调用上限 × 倍数)。<a class="config-doc-link" href="https://scriverse.top/docs/global-tool-call-limit.html" target="_blank" rel="noopener noreferrer">了解原理与推荐设置</a></p></div></div><div class="config-inline-save"><label class="agent-tool-call-limit-field">调用上限<input id="agent-tool-call-limit" type="number" min="10" max="${maximumAgentToolCallLimit}" value="${esc(String(settings.agentToolCallLimit ?? 20))}" aria-label="Agent 工具调用上限"></label><div class="agent-tool-call-global-multiplier-field"><span id="agent-tool-call-global-multiplier-label">全局倍数</span><div class="settings-layout-toggle agent-tool-call-global-multiplier-toggle" role="group" aria-labelledby="agent-tool-call-global-multiplier-label">${[1, 2, 3, 4, 5, 6].map((value) => `<button type="button" data-global-multiplier="${value}" aria-pressed="${Number(settings.agentToolCallGlobalMultiplier ?? 3) === value}">${value}</button>`).join("")}</div><input id="agent-tool-call-global-multiplier" type="hidden" value="${esc(String(Math.min(6, Math.max(1, Number(settings.agentToolCallGlobalMultiplier ?? 3) || 3))))}" aria-label="Agent 工具调用全局倍数"></div><button id="save-agent-tool-call-limit" class="ghost-button config-save-button" type="button">保存</button></div></section><section class="config-section ai-agent-tools-section"><div class="config-section-header"><div><h2>AI 查询工具</h2><p>工具默认可用,作为已有上下文的补充。关闭后模型不会看到对应能力;所有工具只读且有数量、篇幅与调用轮次限制。已开始的对话会锁定创建时的工具集,修改后仅对新对话生效,避免打断 prompt cache。</p></div></div><div class="ai-agent-tools"><label><input name="agent-tool" type="checkbox" value="story_index" ${agentTools.has("story_index") ? "checked" : ""}><span><strong>作品目录与章节概要</strong><small>分页获取卷章、章节 ID 和当前概要,不返回正文。</small></span></label><label><input name="agent-tool" type="checkbox" value="read_chapters" ${agentTools.has("read_chapters") ? "checked" : ""}><span><strong>读取章节</strong><small>按章节 ID 获取概要或正文,每次最多 3 章。</small></span></label><label><input name="agent-tool" type="checkbox" value="search_story_entities" ${agentTools.has("search_story_entities") ? "checked" : ""}><span><strong>搜索作品实体</strong><small>按实体名、拼音或短关键词混合检索设定、人物、组织、时间线、关系、大纲和伏笔;非语义问答。</small></span></label></div><div class="card-actions"><button id="save-agent-tools" class="ghost-button config-save-button" type="button">保存工具设置</button></div></section>${renderTaskDefaults(models, providers, taskDefaults, settings)}`;
|
|
13999
14047
|
const workSystemPromptSection = host.querySelector("#work-system-prompt")?.closest(".config-section");
|
|
14000
14048
|
workSystemPromptSection?.insertAdjacentHTML("afterend", `<section class="config-section remote-mcp-settings"><div class="config-section-header"><div><h2>远程 MCP 工具</h2><p>填写标准的 <code>mcpServers</code> JSON 配置。保存前会逐个检查 JSON、远程传输、安全地址、MCP 握手与工具列表;任一 Server 失败时都不会覆盖当前配置。</p></div></div><label class="field-label remote-mcp-config-field"><span>mcpServers JSON</span><textarea id="remote-mcp-config" rows="12" spellcheck="false" autocapitalize="off" autocomplete="off" aria-describedby="remote-mcp-config-help remote-mcp-status" placeholder='{"mcpServers":{"example":{"url":"https://example.com/mcp"}}}'>${esc(remoteMcpConfigText)}</textarea></label><small id="remote-mcp-config-help" class="remote-mcp-config-help">仅支持远程 MCP 工具(SSE / Streamable HTTP),不支持会执行本地命令的 stdio 配置。敏感 Header 会加密保存,页面中的 ${esc("********")} 掩码再次保存时会保留原值。</small><p id="remote-mcp-status" class="remote-mcp-status" role="status" aria-live="polite">${esc(remoteMcpStatusText)}</p><div class="card-actions"><button id="save-remote-mcp-config" class="ghost-button config-save-button" type="button">测试并保存 MCP 配置</button></div></section>`);
|
|
14001
14049
|
const semanticModelOptions = (kind, selectedId) => semanticModels
|
|
@@ -14035,10 +14083,6 @@ async function renderBookAiSettings() {
|
|
|
14035
14083
|
};
|
|
14036
14084
|
configureTokenQuotaInput(host.querySelector("#daily-token-quota"), "daily-token-quota-warning", 10_000);
|
|
14037
14085
|
configureTokenQuotaInput(host.querySelector("#monthly-token-quota"), "monthly-token-quota-warning", 1_000_000);
|
|
14038
|
-
const agentToolCallLimitInput = host.querySelector("#agent-tool-call-limit");
|
|
14039
|
-
agentToolCallLimitInput?.setAttribute("max", String(maximumAgentToolCallLimit));
|
|
14040
|
-
const agentToolCallDescription = agentToolCallLimitInput?.closest(".config-section")?.querySelector(".config-section-header p");
|
|
14041
|
-
if (agentToolCallDescription?.firstChild) agentToolCallDescription.firstChild.nodeValue = agentToolCallDescription.firstChild.nodeValue.replace("5–48", `5–${maximumAgentToolCallLimit}`);
|
|
14042
14086
|
host.querySelectorAll(".config-section").forEach((section) => {
|
|
14043
14087
|
if (section.querySelector("h2")?.textContent === "Agent 工具调用上限") section.id = "agent-tool-call-limit-settings";
|
|
14044
14088
|
});
|
|
@@ -14398,9 +14442,9 @@ async function renderBookAiSettings() {
|
|
|
14398
14442
|
const button = $("#save-agent-tool-call-limit");
|
|
14399
14443
|
const input = $("#agent-tool-call-limit");
|
|
14400
14444
|
const value = Number(input.value);
|
|
14401
|
-
const maximum = Number(input.max) ||
|
|
14402
|
-
if (!Number.isInteger(value) || value <
|
|
14403
|
-
toast(`Agent 工具调用上限必须是
|
|
14445
|
+
const maximum = Number(input.max) || 300;
|
|
14446
|
+
if (!Number.isInteger(value) || value < 10) {
|
|
14447
|
+
toast(`Agent 工具调用上限必须是 10 到 ${maximum} 之间的整数`, "error");
|
|
14404
14448
|
input.focus();
|
|
14405
14449
|
return;
|
|
14406
14450
|
}
|
|
@@ -21051,6 +21095,13 @@ $("#cover-file").addEventListener("change", async (event) => {
|
|
|
21051
21095
|
}
|
|
21052
21096
|
});
|
|
21053
21097
|
$("#chapter-type-menu").addEventListener("click", async (event) => {
|
|
21098
|
+
const aiReferenceButton = event.target.closest("[data-add-chapter-ai-reference]");
|
|
21099
|
+
if (aiReferenceButton) {
|
|
21100
|
+
const chapterId = state.contextChapterId;
|
|
21101
|
+
closeChapterTypeMenu();
|
|
21102
|
+
if (chapterId) addChapterAsAiReference(chapterId);
|
|
21103
|
+
return;
|
|
21104
|
+
}
|
|
21054
21105
|
const deleteButton = event.target.closest("[data-delete-chapter]");
|
|
21055
21106
|
if (deleteButton) {
|
|
21056
21107
|
const chapterId = state.contextChapterId;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" role="img" aria-labelledby="title description">
|
|
2
|
+
<title id="title">叙界</title>
|
|
3
|
+
<desc id="description">一本展开的书与一颗星,代表小说创作与灵感</desc>
|
|
4
|
+
<rect width="64" height="64" rx="14" fill="#bb911a"/>
|
|
5
|
+
<path d="M10 16.5c8.7-1.6 15.7.4 21 6v29c-5.4-4.8-12.4-6.5-21-5.1V16.5Z" fill="#fffaf0"/>
|
|
6
|
+
<path d="M54 16.5c-8.7-1.6-15.7.4-21 6v29c5.4-4.8 12.4-6.5 21-5.1V16.5Z" fill="#fffaf0"/>
|
|
7
|
+
<path d="M31 22.5h2V52h-2z" fill="#c79b32"/>
|
|
8
|
+
<path d="m48 9.5 1.7 4.1 4.3 1.7-4.3 1.7-1.7 4.1-1.7-4.1-4.3-1.7 4.3-1.7L48 9.5Z" fill="#ffe6a0"/>
|
|
9
|
+
<path d="M15.5 25.5c4.2-.3 7.8.6 10.8 2.7M15.5 32c4.2-.3 7.8.6 10.8 2.7M48.5 25.5c-4.2-.3-7.8.6-10.8 2.7M48.5 32c-4.2-.3-7.8.6-10.8 2.7" fill="none" stroke="#b69048" stroke-linecap="round" stroke-width="2"/>
|
|
10
|
+
</svg>
|
package/dist/public/index.html
CHANGED
|
@@ -522,6 +522,7 @@
|
|
|
522
522
|
<button type="button" role="menuitemradio" data-chapter-type="设定">设定</button>
|
|
523
523
|
<button type="button" role="menuitemradio" data-chapter-type="作者的话">作者的话</button>
|
|
524
524
|
<button type="button" role="menuitemradio" data-chapter-type="其他">其他</button>
|
|
525
|
+
<button type="button" role="menuitem" data-add-chapter-ai-reference>添加到助手引用</button>
|
|
525
526
|
<button class="danger-button" type="button" role="menuitem" data-delete-chapter>删除章节</button>
|
|
526
527
|
</div>
|
|
527
528
|
</div>
|
|
@@ -1425,6 +1426,6 @@
|
|
|
1425
1426
|
</dialog>
|
|
1426
1427
|
|
|
1427
1428
|
<div id="auth-loading" class="auth-loading" role="status" aria-label="正在载入工作台"></div>
|
|
1428
|
-
<script type="module" src="/app.js?v=20260816-extended-thinking-effort-v1&feature=ai-history-rename-v1&feature=ai-tool-call-copy-feedback-v2&feature=ai-send-control-v2&feature=analysis-task-queue-refresh-v1&feature=character-gender-v1&feature=character-filter-state-v1&feature=relationship-canvas-scale-v1&feature=relationship-table-scroll-v1&feature=ai-session-id-copy-v2&feature=galaxy-motion-mode-v3&feature=galaxy-edge-label-threshold-v1&feature=calculate-time-tool-v2&feature=analysis-task-expired-toast-v1&feature=global-replace-volume-v1&feature=chapter-search-replace-v1&feature=chapter-save-toast-v1&feature=character-relationship-delete-v1&feature=character-relationship-group-v1&feature=analysis-task-stability-delay-v1&feature=ai-assistant-workspace-v2&feature=volume-detail-icon-v1&feature=volume-story-order-v1&feature=reader-manual-chapter-navigation-v1&feature=ai-message-reference-badges-v1&feature=ai-roleplay-message-reference-v1&feature=ai-message-actions-v1&feature=assistant-responsive-navigation-v3&feature=annotation-permissions-v1&feature=annotation-line-counts-v1&feature=ai-relationship-roleplay-v1&feature=ai-roleplay-user-character-visibility-v1&feature=ai-roleplay-story-recall-v1&feature=ai-model-picker-v1&feature=ai-fork-model-unlock-v1&feature=context-percent-format-v1&feature=annotation-precise-locate-v1&feature=markdown-word-count-stable-v1&feature=ai-stream-character-count-stable-v2&feature=ai-process-empty-intermediate-v1&feature=ai-feed-scroll-follow-v2&feature=ai-message-retry-v1&feature=ai-stream-idle-timeout-v2&feature=ai-config-delete-v1&feature=ai-provider-protocol-options-v1&feature=ai-provider-thinking-type-v1&feature=ai-chat-image-attachments-v8&feature=ai-message-image-preview-v1&feature=ai-thinking-scroll-v2&feature=ai-image-conversation-model-lock-v1&feature=toast-click-dismiss-v2&feature=system-restart-dialog-delay-v1&feature=character-avatar-v6&feature=character-death-position-v1&feature=admin-ai-conversations-v1&feature=ai-usage-pricing-v1&feature=ai-usage-pricing-badge-v2&feature=ai-usage-pricing-label-v1&feature=ai-usage-token-breakdown-v1&feature=ai-usage-pricing-cache-v2&feature=ai-usage-pricing-manual-refresh-v1&feature=ai-monthly-token-quota-v1&feature=ai-provider-token-quota-v1&feature=ai-token-quota-positive-v6&feature=ai-model-thinking-label-v1&feature=ai-model-picker-focus-v1&feature=ai-provider-model-import-v1&feature=ai-assistant-brain-icon-v1&feature=ai-token-usage-details-v1&feature=ai-token-usage-details-centered-v1&feature=ai-token-usage-raw-input-v1&feature=ai-stream-connection-seconds-v1&feature=phone-client-entry-v1&feature=ai-usage-pricing-cache-v1&feature=ai-model-thinking-label-v3&feature=ai-roleplay-speaker-label-v1&feature=toast-modal-host-v1&feature=api-key-copy-existing-v1&feature=character-favorite-v1&feature=record-favorites-v1&feature=ai-token-usage-estimated-price-v1&feature=entity-detail-favorites-v1&feature=entity-pin-v1&feature=entity-pin-icon-v1&feature=roleplay-favorite-label-v1&feature=ai-roleplay-knowledge-tools-v1&feature=character-persona-summary-v1&feature=ai-roleplay-scene-turn-v2&feature=admin-account-identity-v2&feature=ai-provider-analysis-timeout-v1&feature=task-detail-failure-orange-v1&feature=book-import-progress-v1&feature=presence-multiple-users-v1&feature=ai-context-input-output-v1&feature=editor-blank-lines-preserved-v1&feature=reader-first-frame-v1&feature=vditor-lazy-load-v1&feature=ui-module-preload-v1&feature=reader-initial-prefetch-v1&feature=editor-preview-toggle-v2&feature=vditor-fullscreen-disabled-v1&feature=chapter-auto-indent-v1&feature=chapter-centered-scroll-v1&feature=work-editor-preferences-v1&feature=ai-context-output-usage-v1&feature=ai-roleplay-memory-v4&feature=ai-roleplay-memory-v5&feature=roleplay-memory-header-actions-v1&feature=roleplay-memory-header-toolbar-v1&feature=roleplay-memory-action-icons-v1&feature=roleplay-memory-action-colors-v1&feature=annotation-line-anchor-v1&feature=stable-line-ids-v1&feature=live-annotation-anchors-v1&feature=chapter-comment-filters-v1&feature=ai-write-tools-v3&feature=ai-question-option-supplement-v1&feature=ai-question-selection-highlight-v1&feature=ai-question-continuation-ui-v3&feature=ai-background-stream-v1&feature=ai-question-tool-result-v1&feature=ai-question-tool-summary-v1&feature=ai-question-submit-guidance-v1&feature=ai-question-batch-v1&feature=ai-question-answer-limit-v1&feature=semantic-search-v6&feature=chapter-title-renumber-v1&feature=ai-writing-skills-v3&feature=ai-cancel-preserve-process-v2&feature=remote-mcp-v1&feature=character-alias-chips-v2&feature=character-title-input-v1&feature=character-detail-value-wrap-v2&feature=chapter-batch-editor-refresh-v1&feature=ai-usage-stat-display-v1&feature=ai-usage-year-v1&feature=semantic-search-rag-label-v1&feature=ai-skill-slash-menu-v1&feature=ai-roleplay-scene-bubble-v1&feature=ai-roleplay-scene-collapse-v1&feature=markdown-adjacent-blockquotes-v1&feature=chapter-save-shortcut-v2&feature=ai-message-citation-popover-v1&feature=line-citation-menu-separator-v1&feature=global-im-v106&feature=im-sidebar-compact-v1&feature=ai-fork-progress-toast-v1&feature=im-settings-gear-v1&feature=compact-sidebar-directory-v2&feature=chapter-word-count-consistency-v1&feature=continuation-guard-failure-details-v1&feature=ai-all-message-references-v2&feature=ai-question-render-recovery-v3&feature=ai-suggestion-editor-boundary-v1&feature=setting-category-preservation-v1&feature=toast-stack-v1&feature=toast-stack-label-v2"></script>
|
|
1429
|
+
<script type="module" src="/app.js?v=20260816-extended-thinking-effort-v1&feature=ai-history-rename-v1&feature=ai-tool-call-copy-feedback-v2&feature=ai-send-control-v2&feature=analysis-task-queue-refresh-v1&feature=character-gender-v1&feature=character-filter-state-v1&feature=relationship-canvas-scale-v1&feature=relationship-table-scroll-v1&feature=ai-session-id-copy-v2&feature=galaxy-motion-mode-v3&feature=galaxy-edge-label-threshold-v1&feature=calculate-time-tool-v2&feature=analysis-task-expired-toast-v1&feature=global-replace-volume-v1&feature=chapter-search-replace-v1&feature=chapter-save-toast-v1&feature=character-relationship-delete-v1&feature=character-relationship-group-v1&feature=analysis-task-stability-delay-v1&feature=ai-assistant-workspace-v2&feature=volume-detail-icon-v1&feature=volume-story-order-v1&feature=reader-manual-chapter-navigation-v1&feature=ai-message-reference-badges-v1&feature=ai-roleplay-message-reference-v1&feature=ai-message-actions-v1&feature=assistant-responsive-navigation-v3&feature=annotation-permissions-v1&feature=annotation-line-counts-v1&feature=ai-relationship-roleplay-v1&feature=ai-roleplay-user-character-visibility-v1&feature=ai-roleplay-story-recall-v1&feature=ai-model-picker-v1&feature=ai-fork-model-unlock-v1&feature=context-percent-format-v1&feature=annotation-precise-locate-v1&feature=markdown-word-count-stable-v1&feature=ai-stream-character-count-stable-v2&feature=ai-process-empty-intermediate-v1&feature=ai-feed-scroll-follow-v2&feature=ai-message-retry-v1&feature=ai-stream-idle-timeout-v2&feature=ai-config-delete-v1&feature=ai-provider-protocol-options-v1&feature=ai-provider-thinking-type-v1&feature=ai-chat-image-attachments-v8&feature=ai-message-image-preview-v1&feature=ai-thinking-scroll-v2&feature=ai-image-conversation-model-lock-v1&feature=toast-click-dismiss-v2&feature=system-restart-dialog-delay-v1&feature=character-avatar-v6&feature=character-death-position-v1&feature=admin-ai-conversations-v1&feature=ai-usage-pricing-v1&feature=ai-usage-pricing-badge-v2&feature=ai-usage-pricing-label-v1&feature=ai-usage-token-breakdown-v1&feature=ai-usage-pricing-cache-v2&feature=ai-usage-pricing-manual-refresh-v1&feature=ai-monthly-token-quota-v1&feature=ai-provider-token-quota-v1&feature=ai-token-quota-positive-v6&feature=ai-model-thinking-label-v1&feature=ai-model-picker-focus-v1&feature=ai-provider-model-import-v1&feature=ai-assistant-brain-icon-v1&feature=ai-token-usage-details-v1&feature=ai-token-usage-details-centered-v1&feature=ai-token-usage-raw-input-v1&feature=ai-stream-connection-seconds-v1&feature=phone-client-entry-v1&feature=ai-usage-pricing-cache-v1&feature=ai-model-thinking-label-v3&feature=ai-roleplay-speaker-label-v1&feature=toast-modal-host-v1&feature=api-key-copy-existing-v1&feature=character-favorite-v1&feature=record-favorites-v1&feature=ai-token-usage-estimated-price-v1&feature=entity-detail-favorites-v1&feature=entity-pin-v1&feature=entity-pin-icon-v1&feature=roleplay-favorite-label-v1&feature=ai-roleplay-knowledge-tools-v1&feature=character-persona-summary-v1&feature=ai-roleplay-scene-turn-v2&feature=admin-account-identity-v2&feature=ai-provider-analysis-timeout-v1&feature=task-detail-failure-orange-v1&feature=book-import-progress-v1&feature=presence-multiple-users-v1&feature=ai-context-input-output-v1&feature=editor-blank-lines-preserved-v1&feature=reader-first-frame-v1&feature=vditor-lazy-load-v1&feature=ui-module-preload-v1&feature=reader-initial-prefetch-v1&feature=editor-preview-toggle-v2&feature=vditor-fullscreen-disabled-v1&feature=chapter-auto-indent-v1&feature=chapter-centered-scroll-v1&feature=work-editor-preferences-v1&feature=ai-context-output-usage-v1&feature=ai-roleplay-memory-v4&feature=ai-roleplay-memory-v5&feature=roleplay-memory-header-actions-v1&feature=roleplay-memory-header-toolbar-v1&feature=roleplay-memory-action-icons-v1&feature=roleplay-memory-action-colors-v1&feature=annotation-line-anchor-v1&feature=stable-line-ids-v1&feature=live-annotation-anchors-v1&feature=chapter-comment-filters-v1&feature=ai-write-tools-v3&feature=ai-question-option-supplement-v1&feature=ai-question-selection-highlight-v1&feature=ai-question-continuation-ui-v3&feature=ai-background-stream-v1&feature=ai-question-tool-result-v1&feature=ai-question-tool-summary-v1&feature=ai-question-submit-guidance-v1&feature=ai-question-batch-v1&feature=ai-question-answer-limit-v1&feature=semantic-search-v6&feature=chapter-title-renumber-v1&feature=ai-writing-skills-v3&feature=ai-cancel-preserve-process-v2&feature=remote-mcp-v1&feature=character-alias-chips-v2&feature=character-title-input-v1&feature=character-detail-value-wrap-v2&feature=chapter-batch-editor-refresh-v1&feature=ai-usage-stat-display-v1&feature=ai-usage-year-v1&feature=semantic-search-rag-label-v1&feature=ai-skill-slash-menu-v1&feature=ai-roleplay-scene-bubble-v1&feature=ai-roleplay-scene-collapse-v1&feature=markdown-adjacent-blockquotes-v1&feature=chapter-save-shortcut-v2&feature=ai-message-citation-popover-v1&feature=line-citation-menu-separator-v1&feature=global-im-v106&feature=im-sidebar-compact-v1&feature=ai-fork-progress-toast-v1&feature=im-settings-gear-v1&feature=compact-sidebar-directory-v2&feature=chapter-word-count-consistency-v1&feature=continuation-guard-failure-details-v1&feature=ai-all-message-references-v2&feature=ai-question-render-recovery-v3&feature=ai-suggestion-editor-boundary-v1&feature=setting-category-preservation-v1&feature=toast-stack-v1&feature=toast-stack-label-v2&feature=agent-tool-limits-300-v1&feature=server-dev-logo-v1&feature=chapter-directory-ai-reference-v2&feature=ai-error-origin-v1"></script>
|
|
1429
1430
|
</body>
|
|
1430
1431
|
</html>
|
package/dist/store.js
CHANGED
|
@@ -11,7 +11,7 @@ import { currentRequestActor } from "./request-context.js";
|
|
|
11
11
|
import { canReadWorkModule, canWriteWorkModule, classifyWorkModulePermissions, emptyWorkModulePermissions, fullWorkModulePermissions, storedWorkModulePermissions } from "./work-permissions.js";
|
|
12
12
|
import { countWords, documentShortSearchTerms, escapeSqlLikePattern, id, json, normalizeDocumentSearchText, now, splitDocumentParagraphs } from "./utils.js";
|
|
13
13
|
import { buildWritingCalendar, writingDateKey } from "./writing-progress-time.js";
|
|
14
|
-
import { resolveMaxAgentToolCallLimit } from "./ai-tool-results.js";
|
|
14
|
+
import { DEFAULT_AGENT_TOOL_CALL_LIMIT, MIN_AGENT_TOOL_CALL_LIMIT, resolveMaxAgentToolCallLimit } from "./ai-tool-results.js";
|
|
15
15
|
import { DEFAULT_AI_STREAM_IDLE_TIMEOUT_SECONDS, normalizeAiStreamIdleTimeoutSeconds } from "./ai-stream-timeout.js";
|
|
16
16
|
import { normalizeRoleplayScenePin, roleplayUserTurnDisplayText, roleplayUserTurnTitleSource } from "./roleplay-turn.js";
|
|
17
17
|
import { chapterAnnotationLineHashes, createChapterLineIds, MAX_CHAPTER_LINE_IDS, parseChapterAnnotationLineIds, parseChapterAnnotationLineHashes, parseChapterLineIds, reconcileChapterLineIds, reanchorChapterAnnotations } from "./chapter-annotation-anchor.js";
|
|
@@ -1104,7 +1104,7 @@ export class Store {
|
|
|
1104
1104
|
bookSummaryContextPercent: Math.min(90, Math.max(1, Number(row?.book_summary_context_percent ?? 50) || 50)),
|
|
1105
1105
|
contextCompactThreshold: Math.min(90, Math.max(50, Number(row?.context_compact_threshold ?? 85) || 85)),
|
|
1106
1106
|
agentToolCallLimitMaximum: maximumAgentToolCallLimit,
|
|
1107
|
-
agentToolCallLimit: Math.min(maximumAgentToolCallLimit, Math.max(
|
|
1107
|
+
agentToolCallLimit: Math.min(maximumAgentToolCallLimit, Math.max(MIN_AGENT_TOOL_CALL_LIMIT, Number(row?.agent_tool_call_limit ?? DEFAULT_AGENT_TOOL_CALL_LIMIT) || DEFAULT_AGENT_TOOL_CALL_LIMIT)),
|
|
1108
1108
|
agentToolCallGlobalMultiplier: Math.min(6, Math.max(1, Number(row?.agent_tool_call_global_multiplier ?? 3) || 3)),
|
|
1109
1109
|
agentTools: normalizeWorkAgentTools(row?.agent_tools_json),
|
|
1110
1110
|
imageToolModelId: row?.image_tool_model_id === null || row?.image_tool_model_id === undefined
|
|
@@ -1190,7 +1190,7 @@ export class Store {
|
|
|
1190
1190
|
title_generation_model_id = excluded.title_generation_model_id,
|
|
1191
1191
|
image_tool_model_id = excluded.image_tool_model_id,
|
|
1192
1192
|
always_include_setting_info = excluded.always_include_setting_info,
|
|
1193
|
-
updated_at = excluded.updated_at`, workId, nextPrompt, nextSystemPromptOverride ? 1 : 0, nextDailyTokenQuota, nextMonthlyTokenQuota, nextEnabled ? 1 : 0, Math.min(8, Math.max(1, nextConcurrency)), Math.min(200, Math.max(1, nextBatchLimit)), Math.min(10_000, Math.max(0, nextDailyTaskLimit)), Math.min(10, Math.max(1, nextFailureThreshold)), Math.min(120, Math.max(1, nextStabilityDelayMinutes)), current.autoRunPaused ? 1 : 0, String(current.autoRunPauseReason ?? ""), current.autoRunResumeAt === null ? null : String(current.autoRunResumeAt), Math.max(0, Number(current.autoRunConsecutiveFailures) || 0), Math.min(90, Math.max(1, nextBookSummaryContextPercent)), Math.min(90, Math.max(50, nextContextCompactThreshold)), Math.min(maximumAgentToolCallLimit, Math.max(
|
|
1193
|
+
updated_at = excluded.updated_at`, workId, nextPrompt, nextSystemPromptOverride ? 1 : 0, nextDailyTokenQuota, nextMonthlyTokenQuota, nextEnabled ? 1 : 0, Math.min(8, Math.max(1, nextConcurrency)), Math.min(200, Math.max(1, nextBatchLimit)), Math.min(10_000, Math.max(0, nextDailyTaskLimit)), Math.min(10, Math.max(1, nextFailureThreshold)), Math.min(120, Math.max(1, nextStabilityDelayMinutes)), current.autoRunPaused ? 1 : 0, String(current.autoRunPauseReason ?? ""), current.autoRunResumeAt === null ? null : String(current.autoRunResumeAt), Math.max(0, Number(current.autoRunConsecutiveFailures) || 0), Math.min(90, Math.max(1, nextBookSummaryContextPercent)), Math.min(90, Math.max(50, nextContextCompactThreshold)), Math.min(maximumAgentToolCallLimit, Math.max(MIN_AGENT_TOOL_CALL_LIMIT, nextAgentToolCallLimit)), Math.min(6, Math.max(1, nextAgentToolCallGlobalMultiplier)), JSON.stringify(nextAgentTools), nextTitleGenerationModelId, nextImageToolModelId, nextAlwaysIncludeSettingInfo ? 1 : 0, timestamp);
|
|
1194
1194
|
this.audit(workId, "work.ai-settings.updated", "work-ai-settings", workId, {
|
|
1195
1195
|
systemPromptChanged: input.systemPrompt !== undefined,
|
|
1196
1196
|
systemPromptOverride: nextSystemPromptOverride,
|
|
@@ -1204,7 +1204,7 @@ export class Store {
|
|
|
1204
1204
|
autoRunStabilityDelayMinutes: Math.min(120, Math.max(1, nextStabilityDelayMinutes)),
|
|
1205
1205
|
bookSummaryContextPercent: Math.min(90, Math.max(1, nextBookSummaryContextPercent)),
|
|
1206
1206
|
contextCompactThreshold: Math.min(90, Math.max(50, nextContextCompactThreshold)),
|
|
1207
|
-
agentToolCallLimit: Math.min(maximumAgentToolCallLimit, Math.max(
|
|
1207
|
+
agentToolCallLimit: Math.min(maximumAgentToolCallLimit, Math.max(MIN_AGENT_TOOL_CALL_LIMIT, nextAgentToolCallLimit)),
|
|
1208
1208
|
agentToolCallGlobalMultiplier: Math.min(6, Math.max(1, nextAgentToolCallGlobalMultiplier)),
|
|
1209
1209
|
agentTools: nextAgentTools,
|
|
1210
1210
|
imageToolModelId: nextImageToolModelId,
|
|
@@ -1233,8 +1233,8 @@ export class Store {
|
|
|
1233
1233
|
this.db.run(`INSERT INTO work_ai_settings (
|
|
1234
1234
|
work_id, semantic_search_enabled, semantic_embedding_model_id, semantic_rerank_model_id,
|
|
1235
1235
|
semantic_vector_dimension, semantic_recall_limit, semantic_result_limit,
|
|
1236
|
-
semantic_budget_tokens, semantic_channel_weight, updated_at
|
|
1237
|
-
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
1236
|
+
semantic_budget_tokens, semantic_channel_weight, updated_at, agent_tool_call_limit
|
|
1237
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
1238
1238
|
ON CONFLICT(work_id) DO UPDATE SET
|
|
1239
1239
|
semantic_search_enabled = excluded.semantic_search_enabled,
|
|
1240
1240
|
semantic_embedding_model_id = excluded.semantic_embedding_model_id,
|
|
@@ -1244,7 +1244,7 @@ export class Store {
|
|
|
1244
1244
|
semantic_result_limit = excluded.semantic_result_limit,
|
|
1245
1245
|
semantic_budget_tokens = excluded.semantic_budget_tokens,
|
|
1246
1246
|
semantic_channel_weight = excluded.semantic_channel_weight,
|
|
1247
|
-
updated_at = excluded.updated_at`, workId, enabled ? 1 : 0, embeddingModelId, rerankModelId, vectorDimension, recallLimit, resultLimit, budgetTokens, channelWeight, timestamp);
|
|
1247
|
+
updated_at = excluded.updated_at`, workId, enabled ? 1 : 0, embeddingModelId, rerankModelId, vectorDimension, recallLimit, resultLimit, budgetTokens, channelWeight, timestamp, Number(current.agentToolCallLimit));
|
|
1248
1248
|
this.audit(workId, "semantic.settings.updated", "work-ai-settings", workId, {
|
|
1249
1249
|
enabled,
|
|
1250
1250
|
embeddingModelId,
|