@musnows/scriverse 0.6.4 → 0.6.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 +22 -15
- package/dist/ai.js.map +1 -1
- package/dist/app.js +4 -0
- package/dist/app.js.map +1 -1
- package/dist/cli-contract.js +6 -5
- package/dist/cli-contract.js.map +1 -1
- package/dist/database.js +45 -1
- package/dist/database.js.map +1 -1
- package/dist/public/ai-mentions.js +5 -1
- package/dist/public/app.js +102 -52
- package/dist/public/character-version.js +1 -0
- package/dist/public/index.html +6 -10
- package/dist/public/styles.css +82 -49
- package/dist/public/timeline-view.d.ts +50 -0
- package/dist/public/timeline-view.js +119 -0
- package/dist/store.js +40 -25
- package/dist/store.js.map +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
package/dist/ai.js
CHANGED
|
@@ -373,7 +373,7 @@ const AGENT_TOOL_DEFINITIONS = {
|
|
|
373
373
|
type: "function",
|
|
374
374
|
function: {
|
|
375
375
|
name: "search_story_entities",
|
|
376
|
-
description: "按短关键词在结构化作品实体中进行元数据、精确全文和拼音混合检索:设定、人物(含 Markdown
|
|
376
|
+
description: "按短关键词在结构化作品实体中进行元数据、精确全文和拼音混合检索:设定、人物(含 Markdown 档案章节)、种族、组织、时间线、关系、大纲和伏笔。人物、种族、组织结果分别包含权威布尔状态 isDead、isExtinct、isDissolved;只有值为 true 才能判定该角色已死亡、该种族已灭绝或该组织已解散,字段为 false 时必须视为仍存活、未灭绝或未解散,禁止根据正文情节自行改判。不是语义问答;请传入实体名、别名、标题、拼音或短关键词,不要传入自然语言整句。结果按综合相关度排序;人物结果含 sectionId 时可再调用 read_character_sections 精读。无匹配时改用更短关键词,或改用 story_index / grep。",
|
|
377
377
|
parameters: { type: "object", properties: { query: { type: "string", minLength: 1, maxLength: 200 }, categories: { type: "array", items: { type: "string", enum: ["setting", "character", "race", "organization", "timeline", "relationship", "outline", "foreshadow"] }, maxItems: 8 }, limit: { type: "integer", minimum: 1, maximum: 30, default: 30 }, cursor: agentToolCursorParameter }, required: ["query"], additionalProperties: false }
|
|
378
378
|
}
|
|
379
379
|
},
|
|
@@ -381,7 +381,7 @@ const AGENT_TOOL_DEFINITIONS = {
|
|
|
381
381
|
type: "function",
|
|
382
382
|
function: {
|
|
383
383
|
name: "read_character_sections",
|
|
384
|
-
description: "读取指定人物 Markdown
|
|
384
|
+
description: "读取指定人物 Markdown 档案章节的摘要或原文,并返回该人物的权威 isDead 状态。只有 isDead=true 才能判定人物已死亡;isDead=false 时必须视为仍存活,禁止根据章节内容自行改判。先通过 search_story_entities 获取 sectionId;每次最多读取 3 个章节。",
|
|
385
385
|
parameters: { type: "object", properties: { sectionIds: { type: "array", items: { type: "string" }, minItems: 1, maxItems: 3 }, include: { type: "string", enum: ["summary", "content", "both"] }, cursor: agentToolCursorParameter }, required: ["sectionIds"], additionalProperties: false }
|
|
386
386
|
}
|
|
387
387
|
},
|
|
@@ -397,7 +397,7 @@ const AGENT_TOOL_DEFINITIONS = {
|
|
|
397
397
|
type: "function",
|
|
398
398
|
function: {
|
|
399
399
|
name: "recall_self",
|
|
400
|
-
description: "
|
|
400
|
+
description: "回忆与当前扮演角色自身有关的资料。角色、种族、组织状态分别以 isDead、isExtinct、isDissolved 为唯一权威标识;只有值为 true 才能判定已死亡、已灭绝或已解散,字段为 false 时必须视为仍存活、未灭绝或未解散,禁止根据回忆、正文或剧情暗示自行改判。只能读取自己的角色卡、人物档案章节,以及自己参与的关系、时间线和正文片段;不能指定或查询其他角色。",
|
|
401
401
|
parameters: { type: "object", properties: { query: { type: "string", maxLength: 200, default: "", description: "可选的回忆关键词;留空时返回角色自身的核心资料。" }, categories: { type: "array", items: { type: "string", enum: ["profile", "sections", "relationships", "timeline", "chapters"] }, maxItems: 5 }, cursor: agentToolCursorParameter }, additionalProperties: false }
|
|
402
402
|
}
|
|
403
403
|
}
|
|
@@ -1006,10 +1006,8 @@ export class ContextBuilder {
|
|
|
1006
1006
|
const includeAutomaticContext = scope.type !== "none" && scope.suppressAutomaticContext !== true;
|
|
1007
1007
|
const settingsOnly = scope.type === "settings";
|
|
1008
1008
|
const isProseScope = PROSE_CONTEXT_SCOPE_TYPES.has(scope.type);
|
|
1009
|
-
const includeSettingInfo =
|
|
1010
|
-
&& isProseScope
|
|
1011
|
-
&& !settingsOnly
|
|
1012
|
-
&& scope.includeSettingInfo !== false;
|
|
1009
|
+
const includeSettingInfo = !settingsOnly && scope.suppressAutomaticContext !== true && (scope.includeSettingInfo === true
|
|
1010
|
+
|| (includeAutomaticContext && isProseScope && scope.includeSettingInfo !== false));
|
|
1013
1011
|
const constraints = includeAutomaticContext
|
|
1014
1012
|
? [wrapAiContextRegion("work", `作品:${String(work.title)}\n作者:${String(work.author) || "未填写"}`)]
|
|
1015
1013
|
: [];
|
|
@@ -3233,9 +3231,14 @@ export class AiManager {
|
|
|
3233
3231
|
buildContextPlan(input, model, existingBudget, persistKeywordInjections = false) {
|
|
3234
3232
|
const budget = existingBudget ?? this.contextBudget(input, model);
|
|
3235
3233
|
const roleplayCharacterId = this.roleplayCharacterId(input.workId, input.conversationId);
|
|
3234
|
+
const settings = this.store.getWorkAiSettings(input.workId);
|
|
3235
|
+
const configuredScope = {
|
|
3236
|
+
...input.scope,
|
|
3237
|
+
includeSettingInfo: settings.alwaysIncludeSettingInfo === true ? true : input.scope.includeSettingInfo
|
|
3238
|
+
};
|
|
3236
3239
|
const baseScope = roleplayCharacterId
|
|
3237
3240
|
? {
|
|
3238
|
-
...
|
|
3241
|
+
...configuredScope,
|
|
3239
3242
|
type: "none",
|
|
3240
3243
|
suppressAutomaticContext: true,
|
|
3241
3244
|
includeBookSummary: false,
|
|
@@ -3243,9 +3246,8 @@ export class AiManager {
|
|
|
3243
3246
|
volumeId: undefined,
|
|
3244
3247
|
selection: undefined
|
|
3245
3248
|
}
|
|
3246
|
-
:
|
|
3249
|
+
: configuredScope;
|
|
3247
3250
|
const contextWindow = numberValue(model, "context_window") || DEFAULT_CONTEXT_WINDOW;
|
|
3248
|
-
const settings = this.store.getWorkAiSettings(input.workId);
|
|
3249
3251
|
const percentage = Math.min(90, Math.max(1, Number(settings.bookSummaryContextPercent) || 50));
|
|
3250
3252
|
const workContextBudgetTokens = Number(budget.workContextBudgetTokens) || 256;
|
|
3251
3253
|
const bookSummaryMaximumTokens = baseScope.includeBookSummary || baseScope.type === "book" || baseScope.type === "volume"
|
|
@@ -3260,9 +3262,8 @@ export class AiManager {
|
|
|
3260
3262
|
const injected = conversationId
|
|
3261
3263
|
? this.store.getAiConversationInjectedEntities(conversationId, workId)
|
|
3262
3264
|
: { characters: [], races: [], organizations: [] };
|
|
3263
|
-
const proseSettingInfoOn = PROSE_CONTEXT_SCOPE_TYPES.has(scope.type)
|
|
3264
|
-
&& scope.
|
|
3265
|
-
&& scope.includeSettingInfo !== false;
|
|
3265
|
+
const proseSettingInfoOn = scope.suppressAutomaticContext !== true && (scope.includeSettingInfo === true || (PROSE_CONTEXT_SCOPE_TYPES.has(scope.type)
|
|
3266
|
+
&& scope.includeSettingInfo !== false));
|
|
3266
3267
|
const matches = matchKeywordEntities(this.store, workId, instruction, {
|
|
3267
3268
|
excludeCharacterIds: [
|
|
3268
3269
|
...(scope.characterIds ?? []),
|
|
@@ -3314,9 +3315,11 @@ export class AiManager {
|
|
|
3314
3315
|
delete profile.sections;
|
|
3315
3316
|
const roleCard = {
|
|
3316
3317
|
name: character.name,
|
|
3318
|
+
isDead: character.isDead,
|
|
3317
3319
|
code: character.code,
|
|
3318
3320
|
aliases: character.aliases,
|
|
3319
3321
|
species: character.species,
|
|
3322
|
+
race: character.race,
|
|
3320
3323
|
organizations: character.organizations,
|
|
3321
3324
|
attributes: character.attributes,
|
|
3322
3325
|
profile,
|
|
@@ -3460,9 +3463,11 @@ export class AiManager {
|
|
|
3460
3463
|
const record = {
|
|
3461
3464
|
category: "profile",
|
|
3462
3465
|
name: character.name,
|
|
3466
|
+
isDead: character.isDead,
|
|
3463
3467
|
code: character.code,
|
|
3464
3468
|
aliases: character.aliases,
|
|
3465
3469
|
species: character.species,
|
|
3470
|
+
race: character.race,
|
|
3466
3471
|
organizations: character.organizations,
|
|
3467
3472
|
attributes: character.attributes,
|
|
3468
3473
|
profile,
|
|
@@ -3691,6 +3696,7 @@ export class AiManager {
|
|
|
3691
3696
|
sectionId,
|
|
3692
3697
|
characterId: section.characterId,
|
|
3693
3698
|
characterName: character.name,
|
|
3699
|
+
isDead: character.isDead,
|
|
3694
3700
|
title: section.title,
|
|
3695
3701
|
sectionType: section.sectionType,
|
|
3696
3702
|
versionNo: section.versionNo,
|
|
@@ -6422,7 +6428,7 @@ export class AiManager {
|
|
|
6422
6428
|
if (String(item.workId) !== workId)
|
|
6423
6429
|
return null;
|
|
6424
6430
|
return source(`人物档案:${String(item.name)}`, {
|
|
6425
|
-
name: item.name, aliases: item.aliases, code: item.code, species: item.species, race: item.race,
|
|
6431
|
+
name: item.name, isDead: item.isDead, aliases: item.aliases, code: item.code, species: item.species, race: item.race,
|
|
6426
6432
|
organizations: item.organizations, attributes: item.attributes, profile: item.profile,
|
|
6427
6433
|
currentState: item.currentState, lockedFields: item.lockedFields,
|
|
6428
6434
|
profileSections: this.store.listCharacterProfileSections(sourceId).map((section) => ({
|
|
@@ -6439,6 +6445,7 @@ export class AiManager {
|
|
|
6439
6445
|
return null;
|
|
6440
6446
|
return source(`种族设定:${String(item.name)}`, {
|
|
6441
6447
|
name: item.name,
|
|
6448
|
+
isExtinct: item.isExtinct,
|
|
6442
6449
|
description: item.description,
|
|
6443
6450
|
racePath: item.lineage.map((entry) => entry.name).join(" / "),
|
|
6444
6451
|
lineage: item.lineage,
|
|
@@ -6451,7 +6458,7 @@ export class AiManager {
|
|
|
6451
6458
|
if (String(item.workId) !== workId)
|
|
6452
6459
|
return null;
|
|
6453
6460
|
return source(`组织设定:${String(item.name)}`, {
|
|
6454
|
-
name: item.name, description: item.description, settings: item.settings, members: item.members
|
|
6461
|
+
name: item.name, isDissolved: item.isDissolved, description: item.description, settings: item.settings, members: item.members
|
|
6455
6462
|
}, item.versionNo);
|
|
6456
6463
|
}
|
|
6457
6464
|
if (sourceType === "timeline-track") {
|