@musnows/scriverse 0.5.10 → 0.5.12
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 +80 -5
- package/dist/ai.js.map +1 -1
- package/dist/app.js +61 -4
- package/dist/app.js.map +1 -1
- package/dist/cli-contract.js +25 -0
- package/dist/cli-contract.js.map +1 -1
- package/dist/cli-core.js +3 -0
- package/dist/cli-core.js.map +1 -1
- package/dist/database.js +66 -1
- package/dist/database.js.map +1 -1
- package/dist/public/app.js +666 -110
- package/dist/public/entity-version.js +2 -0
- package/dist/public/index.html +10 -2
- package/dist/public/markdown.js +6 -1
- package/dist/public/module-request-cache.d.ts +17 -0
- package/dist/public/module-request-cache.js +35 -0
- package/dist/public/page-route.d.ts +1 -1
- package/dist/public/page-route.js +1 -0
- package/dist/public/stream-typewriter.d.ts +19 -0
- package/dist/public/stream-typewriter.js +83 -0
- package/dist/public/styles.css +70 -6
- package/dist/public/work-permissions.d.ts +2 -2
- package/dist/public/work-permissions.js +8 -0
- package/dist/store.js +164 -18
- package/dist/store.js.map +1 -1
- package/dist/user-auth.js +12 -5
- package/dist/user-auth.js.map +1 -1
- package/dist/version.js +1 -1
- package/dist/work-permissions.js +9 -0
- package/dist/work-permissions.js.map +1 -1
- package/dist/writing-progress-time.js +71 -0
- package/dist/writing-progress-time.js.map +1 -0
- package/package.json +1 -1
package/dist/ai.js
CHANGED
|
@@ -88,7 +88,7 @@ function thinkingParameters(provider, model) {
|
|
|
88
88
|
return {};
|
|
89
89
|
return { thinking: { type: boolValue(model, "thinking_enabled") ? "enabled" : "disabled" } };
|
|
90
90
|
}
|
|
91
|
-
const AGENT_TOOL_IDS = ["story_index", "read_chapters", "grep", "search_story_entities", "read_character_sections"];
|
|
91
|
+
const AGENT_TOOL_IDS = ["story_index", "read_chapters", "grep", "search_story_entities", "read_character_sections", "search_drafts"];
|
|
92
92
|
function traceRecord(value) {
|
|
93
93
|
return value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
94
94
|
}
|
|
@@ -204,6 +204,11 @@ const readCharacterSectionsArguments = z.object({
|
|
|
204
204
|
sectionIds: z.array(z.string().min(1).max(300)).min(1).max(3),
|
|
205
205
|
include: z.enum(["summary", "content", "both"]).default("both")
|
|
206
206
|
}).strict();
|
|
207
|
+
const searchDraftsArguments = z.object({
|
|
208
|
+
query: z.string().trim().max(200).default(""),
|
|
209
|
+
draftType: z.enum(["all", "prose", "setting"]).default("all"),
|
|
210
|
+
limit: z.number().int().min(1).max(30).default(20)
|
|
211
|
+
}).strict();
|
|
207
212
|
const AGENT_TOOL_DEFINITIONS = {
|
|
208
213
|
story_index: {
|
|
209
214
|
type: "function",
|
|
@@ -244,6 +249,14 @@ const AGENT_TOOL_DEFINITIONS = {
|
|
|
244
249
|
description: "读取指定人物 Markdown 档案章节的摘要或原文。先通过 search_story_entities 获取 sectionId;每次最多读取 3 个章节。",
|
|
245
250
|
parameters: { type: "object", properties: { sectionIds: { type: "array", items: { type: "string" }, minItems: 1, maxItems: 3 }, include: { type: "string", enum: ["summary", "content", "both"] } }, required: ["sectionIds"], additionalProperties: false }
|
|
246
251
|
}
|
|
252
|
+
},
|
|
253
|
+
search_drafts: {
|
|
254
|
+
type: "function",
|
|
255
|
+
function: {
|
|
256
|
+
name: "search_drafts",
|
|
257
|
+
description: "搜索当前作品的作者草稿。草稿只是用于记录可能采用、也可能永远不会写入正文或正式设定的临时想法,不是已确认的故事事实,不能当作正文或设定依据。可按关键词和“正文草稿/设定草稿”类型筛选;query 为空时返回最近更新的草稿。",
|
|
258
|
+
parameters: { type: "object", properties: { query: { type: "string", maxLength: 200, default: "" }, draftType: { type: "string", enum: ["all", "prose", "setting"], default: "all" }, limit: { type: "integer", minimum: 1, maximum: 30, default: 20 } }, additionalProperties: false }
|
|
259
|
+
}
|
|
247
260
|
}
|
|
248
261
|
};
|
|
249
262
|
export function estimateAiTokens(value) {
|
|
@@ -1875,7 +1888,29 @@ export class AiManager {
|
|
|
1875
1888
|
const suggestionId = id("suggestion");
|
|
1876
1889
|
this.store.db.run(`INSERT INTO ai_suggestions (id, call_id, work_id, chapter_id, chapter_version, task_type, instruction,
|
|
1877
1890
|
source_text, content, action, status, created_at, created_by_user_id) VALUES (?, ?, ?, ?, ?, 'chat', ?, ?, ?, 'note', 'pending', ?, ?)`, suggestionId, generated.callId, input.workId, chapter ? String(chapter.id) : null, chapter ? Number(chapter.versionNo) : null, input.instruction, input.scope.selection ?? "", generated.content, now(), currentRequestActor()?.userId ?? null);
|
|
1878
|
-
|
|
1891
|
+
const modelDisplayName = typeof generated.model.displayName === "string" ? generated.model.displayName : undefined;
|
|
1892
|
+
const conversationMessage = input.conversationId && input.assistantMessageRequestId
|
|
1893
|
+
? this.store.addAiConversationMessage(input.conversationId, {
|
|
1894
|
+
role: "assistant",
|
|
1895
|
+
content: generated.content,
|
|
1896
|
+
requestId: input.assistantMessageRequestId,
|
|
1897
|
+
metadata: {
|
|
1898
|
+
...(modelDisplayName ? { modelDisplayName } : {}),
|
|
1899
|
+
outputTokens: generated.outputTokens,
|
|
1900
|
+
...(generated.cacheHitPercent === undefined ? {} : { cacheHitPercent: generated.cacheHitPercent }),
|
|
1901
|
+
toolCalls: generated.toolCalls,
|
|
1902
|
+
processSteps: generated.processSteps
|
|
1903
|
+
}
|
|
1904
|
+
})
|
|
1905
|
+
: null;
|
|
1906
|
+
return {
|
|
1907
|
+
...this.getSuggestion(suggestionId),
|
|
1908
|
+
outputTokens: generated.outputTokens,
|
|
1909
|
+
...(generated.cacheHitPercent === undefined ? {} : { cacheHitPercent: generated.cacheHitPercent }),
|
|
1910
|
+
toolCalls: generated.toolCalls,
|
|
1911
|
+
processSteps: generated.processSteps,
|
|
1912
|
+
...(conversationMessage ? { conversationMessage } : {})
|
|
1913
|
+
};
|
|
1879
1914
|
}
|
|
1880
1915
|
async runSuggestionGuard(suggestionId, candidateContent) {
|
|
1881
1916
|
const suggestion = this.getSuggestion(suggestionId);
|
|
@@ -2404,7 +2439,7 @@ export class AiManager {
|
|
|
2404
2439
|
? [
|
|
2405
2440
|
`当前可用作品查询工具:${enabledToolIds.join("、")}。`,
|
|
2406
2441
|
"当作者询问当前作品、项目、章节、情节、人物、关系、世界观或设定,而预加载上下文为空或不足时,必须先调用工具主动查询;不得直接声称没有上下文,也不得先要求作者补充本系统已经能够查询的信息。",
|
|
2407
|
-
"整体介绍、作品基本信息、目录或章节定位优先调用 story_index;按关键字定位正文段落时调用 grep;已知章节 ID 且需要原文事实或精确措辞时调用 read_chapters;查找设定、人物、组织、时间线、关系、大纲或伏笔时调用 search_story_entities(可传入短实体名、拼音或关键词,勿用自然语言整句);人物匹配结果包含 sectionId 且需要背景故事、能力或经历原文时调用 read_character_sections
|
|
2442
|
+
"整体介绍、作品基本信息、目录或章节定位优先调用 story_index;按关键字定位正文段落时调用 grep;已知章节 ID 且需要原文事实或精确措辞时调用 read_chapters;查找设定、人物、组织、时间线、关系、大纲或伏笔时调用 search_story_entities(可传入短实体名、拼音或关键词,勿用自然语言整句);人物匹配结果包含 sectionId 且需要背景故事、能力或经历原文时调用 read_character_sections;作者询问尚未定稿的想法、备选方向或明确提到草稿时调用 search_drafts。草稿可能永远不会进入正文或设定,必须明确标注为未确认想法,不得把它当作故事事实。",
|
|
2408
2443
|
"根据问题选择最少且必要的工具。工具结果仍不足时才说明未知,并明确已经查询过什么;不要重复无效调用。"
|
|
2409
2444
|
].join("\n")
|
|
2410
2445
|
: "";
|
|
@@ -2458,7 +2493,10 @@ export class AiManager {
|
|
|
2458
2493
|
const enabled = new Set(this.store.getWorkAiSettings(workId).agentTools
|
|
2459
2494
|
.filter((item) => typeof item === "string" && AGENT_TOOL_IDS.includes(item)));
|
|
2460
2495
|
const requested = requestedToolIds ? new Set(requestedToolIds) : null;
|
|
2461
|
-
|
|
2496
|
+
const permissions = this.store.getWork(workId).modulePermissions;
|
|
2497
|
+
return AGENT_TOOL_IDS.filter((toolId) => enabled.has(toolId)
|
|
2498
|
+
&& (!requested || requested.has(toolId))
|
|
2499
|
+
&& (toolId !== "search_drafts" || permissions.drafts === "read" || permissions.drafts === "write"));
|
|
2462
2500
|
}
|
|
2463
2501
|
enabledAgentTools(workId, taskType, requestedToolIds) {
|
|
2464
2502
|
return this.enabledAgentToolIds(workId, taskType, requestedToolIds).map((toolId) => AGENT_TOOL_DEFINITIONS[toolId]);
|
|
@@ -2490,7 +2528,8 @@ export class AiManager {
|
|
|
2490
2528
|
: name === "grep" ? grepArguments
|
|
2491
2529
|
: name === "search_story_entities" ? searchStoryEntitiesArguments
|
|
2492
2530
|
: name === "read_character_sections" ? readCharacterSectionsArguments
|
|
2493
|
-
:
|
|
2531
|
+
: name === "search_drafts" ? searchDraftsArguments
|
|
2532
|
+
: null;
|
|
2494
2533
|
if (!schema) {
|
|
2495
2534
|
return {
|
|
2496
2535
|
id: toolCall.id,
|
|
@@ -2647,6 +2686,42 @@ export class AiManager {
|
|
|
2647
2686
|
});
|
|
2648
2687
|
return { id: toolCall.id, name, calledAt, arguments: { sectionIds, include }, status: "completed", result: { ok: true, data: { sections, contentLimitChars: 48_000 } } };
|
|
2649
2688
|
}
|
|
2689
|
+
if (name === "search_drafts") {
|
|
2690
|
+
const { query, draftType, limit } = args;
|
|
2691
|
+
let remainingChars = 36_000;
|
|
2692
|
+
const matches = this.store.searchDrafts(workId, query, draftType === "all" ? undefined : draftType, limit).map((draft) => {
|
|
2693
|
+
const content = collapseAiBlankLines(String(draft.content));
|
|
2694
|
+
const excerpt = content.slice(0, Math.max(0, Math.min(12_000, remainingChars)));
|
|
2695
|
+
remainingChars -= excerpt.length;
|
|
2696
|
+
return {
|
|
2697
|
+
id: draft.id,
|
|
2698
|
+
draftType: draft.draftType,
|
|
2699
|
+
draftTypeLabel: draft.draftType === "prose" ? "正文草稿" : "设定草稿",
|
|
2700
|
+
title: draft.title,
|
|
2701
|
+
content: excerpt,
|
|
2702
|
+
contentTruncated: excerpt.length < content.length,
|
|
2703
|
+
versionNo: draft.versionNo,
|
|
2704
|
+
updatedAt: draft.updatedAt
|
|
2705
|
+
};
|
|
2706
|
+
});
|
|
2707
|
+
return {
|
|
2708
|
+
id: toolCall.id,
|
|
2709
|
+
name,
|
|
2710
|
+
calledAt,
|
|
2711
|
+
arguments: { query, draftType, limit },
|
|
2712
|
+
status: "completed",
|
|
2713
|
+
result: {
|
|
2714
|
+
ok: true,
|
|
2715
|
+
data: {
|
|
2716
|
+
meaning: "这些内容是作者记录的未确认临时想法,可能采用,也可能永远不会写入正文或正式设定;不得视为故事事实。",
|
|
2717
|
+
query,
|
|
2718
|
+
draftType,
|
|
2719
|
+
matches,
|
|
2720
|
+
contentLimitChars: 36_000
|
|
2721
|
+
}
|
|
2722
|
+
}
|
|
2723
|
+
};
|
|
2724
|
+
}
|
|
2650
2725
|
throw new Error(`Unhandled agent tool: ${name}`);
|
|
2651
2726
|
}
|
|
2652
2727
|
constrainParametersForContext(model, messages, parameters) {
|