@musnows/scriverse 0.7.5 → 0.7.6
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.js +49 -7
- package/dist/ai.js.map +1 -1
- package/dist/app.js +44 -45
- package/dist/app.js.map +1 -1
- package/dist/epub-export.js +42 -38
- package/dist/epub-export.js.map +1 -1
- package/dist/public/app.js +101 -38
- package/dist/public/index.html +3 -3
- package/dist/public/outline-board.d.ts +16 -10
- package/dist/public/outline-board.js +11 -105
- package/dist/store.js +239 -63
- package/dist/store.js.map +1 -1
- package/dist/version.js +1 -1
- package/dist/zip-stream.js +149 -0
- package/dist/zip-stream.js.map +1 -0
- package/package.json +1 -1
package/dist/ai.js
CHANGED
|
@@ -50,6 +50,7 @@ const AUTO_RUN_MAX_ATTEMPTS = 3;
|
|
|
50
50
|
const AUTO_RUN_RETRY_DELAYS_MS = [5_000, 30_000];
|
|
51
51
|
const AI_INTERACTIVE_TIMEOUT_MS = 60_000;
|
|
52
52
|
const AI_LONG_RUNNING_TIMEOUT_MS = 300_000;
|
|
53
|
+
const FORCE_CONVERSATION_COMPACTION_USAGE_PERCENT = 95;
|
|
53
54
|
const analysisTaskTypes = new Set(ANALYSIS_TASK_TYPES);
|
|
54
55
|
const interactiveStreamErrorCodes = new Set([
|
|
55
56
|
"AI_STREAM_IDLE_TIMEOUT",
|
|
@@ -1950,6 +1951,23 @@ export class AiManager {
|
|
|
1950
1951
|
runningCount: this.store.countRunningTasks(workId)
|
|
1951
1952
|
};
|
|
1952
1953
|
}
|
|
1954
|
+
deleteWork(workId, expectedVersionNo) {
|
|
1955
|
+
const taskIds = this.store.deleteWork(workId, expectedVersionNo);
|
|
1956
|
+
const autoRunTimer = this.autoRunTimers.get(workId);
|
|
1957
|
+
if (autoRunTimer)
|
|
1958
|
+
clearTimeout(autoRunTimer);
|
|
1959
|
+
this.autoRunTimers.delete(workId);
|
|
1960
|
+
this.autoRunStarting.delete(workId);
|
|
1961
|
+
const relationshipIndexTimer = this.relationshipIndexSyncTimers.get(workId);
|
|
1962
|
+
if (relationshipIndexTimer)
|
|
1963
|
+
clearTimeout(relationshipIndexTimer);
|
|
1964
|
+
this.relationshipIndexSyncTimers.delete(workId);
|
|
1965
|
+
for (const taskId of taskIds) {
|
|
1966
|
+
this.taskControllers.get(taskId)?.abort(new Error("作品已移入回收站"));
|
|
1967
|
+
}
|
|
1968
|
+
logger.info("ai.work_tasks.expired", { workId, taskCount: taskIds.length });
|
|
1969
|
+
return taskIds;
|
|
1970
|
+
}
|
|
1953
1971
|
dispose() {
|
|
1954
1972
|
logger.info("ai.manager.disposing", { scheduledWorks: this.autoRunTimers.size, activeTasks: this.taskControllers.size });
|
|
1955
1973
|
if (this.autoRunStartupTimer)
|
|
@@ -3621,6 +3639,7 @@ export class AiManager {
|
|
|
3621
3639
|
leftTokens: remainingTokens
|
|
3622
3640
|
},
|
|
3623
3641
|
compactThreshold: threshold,
|
|
3642
|
+
compactableMessageCount,
|
|
3624
3643
|
compactRecommended: compactableMessageCount > 0 && conversationUsagePercent >= threshold,
|
|
3625
3644
|
contextWarningPending: conversation?.warningPending ?? false,
|
|
3626
3645
|
compactedMessageCount: conversation?.compactedMessageCount ?? 0,
|
|
@@ -3658,14 +3677,18 @@ export class AiManager {
|
|
|
3658
3677
|
}
|
|
3659
3678
|
inspectConversationContext(input) {
|
|
3660
3679
|
const usage = this.getContextUsage({ ...input, taskType: "chat" });
|
|
3661
|
-
const
|
|
3680
|
+
const usagePercent = Number(usage.usagePercent) || 0;
|
|
3681
|
+
const compactableMessageCount = Number(usage.compactableMessageCount) || 0;
|
|
3682
|
+
if (usagePercent >= FORCE_CONVERSATION_COMPACTION_USAGE_PERCENT) {
|
|
3683
|
+
if (compactableMessageCount <= 0) {
|
|
3684
|
+
throw new AppError(409, "AI_CONTEXT_COMPACTION_UNAVAILABLE", "当前请求已占满模型上下文,但没有可压缩的较早对话;请缩短问题、减少引用或新开对话");
|
|
3685
|
+
}
|
|
3686
|
+
return { action: "compact", usage };
|
|
3687
|
+
}
|
|
3662
3688
|
if (!usage.compactRecommended) {
|
|
3663
3689
|
return { action: "ready", usage: { ...usage, contextWarningPending: false } };
|
|
3664
3690
|
}
|
|
3665
|
-
|
|
3666
|
-
return { action: "warn", usage: { ...usage, contextWarningPending: true } };
|
|
3667
|
-
}
|
|
3668
|
-
return { action: "compact", usage };
|
|
3691
|
+
return { action: "warn", usage: { ...usage, contextWarningPending: true } };
|
|
3669
3692
|
}
|
|
3670
3693
|
async prepareConversationContext(input, options = {}) {
|
|
3671
3694
|
const inspection = this.inspectConversationContext(input);
|
|
@@ -3675,13 +3698,32 @@ export class AiManager {
|
|
|
3675
3698
|
this.store.setAiConversationContextWarning(input.conversationId, false);
|
|
3676
3699
|
return inspection;
|
|
3677
3700
|
}
|
|
3678
|
-
if (inspection.action === "warn" && !options.
|
|
3701
|
+
if (inspection.action === "warn" && !options.ignoreWarning) {
|
|
3679
3702
|
this.store.setAiConversationContextWarning(input.conversationId, true);
|
|
3680
3703
|
return inspection;
|
|
3681
3704
|
}
|
|
3705
|
+
if (inspection.action === "warn") {
|
|
3706
|
+
this.store.setAiConversationContextWarning(input.conversationId, false);
|
|
3707
|
+
return {
|
|
3708
|
+
action: "ready",
|
|
3709
|
+
reason: "warning_ignored",
|
|
3710
|
+
usage: { ...inspection.usage, contextWarningPending: false }
|
|
3711
|
+
};
|
|
3712
|
+
}
|
|
3682
3713
|
const compaction = await this.compactConversation(input);
|
|
3714
|
+
if (compaction.changed !== true) {
|
|
3715
|
+
throw new AppError(409, "AI_CONTEXT_COMPACTION_UNAVAILABLE", "当前请求已占满模型上下文,但没有可压缩的较早对话;请缩短问题、减少引用或新开对话");
|
|
3716
|
+
}
|
|
3683
3717
|
const compactedUsage = this.getContextUsage({ ...input, taskType: "chat" });
|
|
3684
|
-
|
|
3718
|
+
if ((Number(compactedUsage.usagePercent) || 0) >= FORCE_CONVERSATION_COMPACTION_USAGE_PERCENT) {
|
|
3719
|
+
throw new AppError(413, "AI_CONTEXT_STILL_OVER_LIMIT", "自动压缩后当前请求仍占满模型上下文;请缩短问题、减少引用或新开对话");
|
|
3720
|
+
}
|
|
3721
|
+
return {
|
|
3722
|
+
action: "compacted",
|
|
3723
|
+
reason: "forced_usage_threshold",
|
|
3724
|
+
usage: compactedUsage,
|
|
3725
|
+
compaction
|
|
3726
|
+
};
|
|
3685
3727
|
}
|
|
3686
3728
|
/** 解析本轮消息中的自动角色提及;不使用会话累计排除集,也不改写累计注入状态。 */
|
|
3687
3729
|
resolveInstructionMentions(input) {
|