@musnows/scriverse 0.7.11 → 0.7.13

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/app.js CHANGED
@@ -551,6 +551,7 @@ const contextSchema = z.object({
551
551
  volumeId: identifier.optional(),
552
552
  selection: z.string().max(200_000).optional(),
553
553
  chapterIds: z.array(identifier).max(20).optional(),
554
+ volumeIds: z.array(identifier).max(20).optional(),
554
555
  characterIds: optionalStrings,
555
556
  mentionCharacterIds: optionalStrings,
556
557
  settingIds: optionalStrings,
@@ -567,8 +568,11 @@ const relationshipSourceRefSchema = z.object({
567
568
  sourceVersion: z.string().trim().min(1).max(200)
568
569
  }).strict();
569
570
  const relationshipAnalysisScopeSchema = z.object({
570
- type: z.enum(["chapter", "book", "settings"]),
571
+ type: z.enum(["chapter", "volume", "book", "settings"]),
571
572
  chapterId: identifier.optional(),
573
+ chapterIds: z.array(identifier).min(1).max(100).optional(),
574
+ volumeId: identifier.optional(),
575
+ volumeIds: z.array(identifier).min(1).max(50).optional(),
572
576
  includeAllSettings: z.boolean().optional(),
573
577
  additionalPrompt: z.string().trim().max(10_000).optional(),
574
578
  characterIds: z.array(identifier).max(20).optional(),
@@ -577,9 +581,30 @@ const relationshipAnalysisScopeSchema = z.object({
577
581
  relationshipSourceRefs: z.array(relationshipSourceRefSchema).max(5_000).optional(),
578
582
  replaceExistingRelationships: z.boolean().optional()
579
583
  }).strict().superRefine((scope, context) => {
580
- if (scope.type === "chapter" && !scope.chapterId) {
584
+ if (scope.type === "chapter" && !scope.chapterId && !scope.chapterIds?.length) {
581
585
  context.addIssue({ code: z.ZodIssueCode.custom, path: ["chapterId"], message: "指定章节分析必须提供章节标识" });
582
586
  }
587
+ if (scope.type === "chapter" && (scope.volumeId !== undefined || scope.volumeIds !== undefined)) {
588
+ context.addIssue({ code: z.ZodIssueCode.custom, path: ["volumeId"], message: "指定章节分析不能同时提供分卷标识" });
589
+ }
590
+ if (scope.type === "volume" && !scope.volumeId && !scope.volumeIds?.length) {
591
+ context.addIssue({ code: z.ZodIssueCode.custom, path: ["volumeId"], message: "指定分卷分析必须提供分卷标识" });
592
+ }
593
+ if (scope.type === "volume" && (scope.chapterId !== undefined || scope.chapterIds !== undefined)) {
594
+ context.addIssue({ code: z.ZodIssueCode.custom, path: ["chapterId"], message: "指定分卷分析不能同时提供章节标识" });
595
+ }
596
+ if (scope.type === "book" && (scope.chapterId !== undefined || scope.chapterIds !== undefined || scope.volumeId !== undefined || scope.volumeIds !== undefined)) {
597
+ context.addIssue({ code: z.ZodIssueCode.custom, path: ["type"], message: "全书分析不能同时提供章节或分卷标识" });
598
+ }
599
+ if (scope.type === "settings" && (scope.chapterId !== undefined || scope.chapterIds !== undefined || scope.volumeId !== undefined || scope.volumeIds !== undefined)) {
600
+ context.addIssue({ code: z.ZodIssueCode.custom, path: ["type"], message: "设定集分析不能同时提供章节或分卷标识" });
601
+ }
602
+ if (scope.chapterIds && new Set(scope.chapterIds).size !== scope.chapterIds.length) {
603
+ context.addIssue({ code: z.ZodIssueCode.custom, path: ["chapterIds"], message: "章节不能重复选择" });
604
+ }
605
+ if (scope.volumeIds && new Set(scope.volumeIds).size !== scope.volumeIds.length) {
606
+ context.addIssue({ code: z.ZodIssueCode.custom, path: ["volumeIds"], message: "分卷不能重复选择" });
607
+ }
583
608
  if (scope.includeAllSettings && scope.type !== "book") {
584
609
  context.addIssue({ code: z.ZodIssueCode.custom, path: ["includeAllSettings"], message: "包含所有设定仅支持全书人物关系分析" });
585
610
  }
@@ -605,6 +630,35 @@ const relationshipAnalysisScopeSchema = z.object({
605
630
  const analysisTaskSchema = z.union([
606
631
  z.object({ taskType: z.literal("relationship-analysis"), scope: relationshipAnalysisScopeSchema.optional(), modelId: identifier.optional() }).strict(),
607
632
  z.object({ taskType: creatableAnalysisTaskTypeSchema, scope: jsonObject.optional(), modelId: identifier.optional() }).strict().superRefine((input, context) => {
633
+ const scope = input.scope;
634
+ const chapterIds = scope?.chapterIds;
635
+ const volumeIds = scope?.volumeIds;
636
+ const validChapterIds = Array.isArray(chapterIds) && chapterIds.every((value) => typeof value === "string" && value.trim().length > 0 && value.length <= 200);
637
+ const validVolumeIds = Array.isArray(volumeIds) && volumeIds.every((value) => typeof value === "string" && value.trim().length > 0 && value.length <= 200);
638
+ if (chapterIds !== undefined && (!validChapterIds || chapterIds.length < 1 || chapterIds.length > 100)) {
639
+ context.addIssue({ code: z.ZodIssueCode.custom, path: ["scope", "chapterIds"], message: "章节选择必须是 1 至 100 个有效标识" });
640
+ }
641
+ if (volumeIds !== undefined && (!validVolumeIds || volumeIds.length < 1 || volumeIds.length > 50)) {
642
+ context.addIssue({ code: z.ZodIssueCode.custom, path: ["scope", "volumeIds"], message: "分卷选择必须是 1 至 50 个有效标识" });
643
+ }
644
+ if (validChapterIds && new Set(chapterIds).size !== chapterIds.length) {
645
+ context.addIssue({ code: z.ZodIssueCode.custom, path: ["scope", "chapterIds"], message: "章节不能重复选择" });
646
+ }
647
+ if (validVolumeIds && new Set(volumeIds).size !== volumeIds.length) {
648
+ context.addIssue({ code: z.ZodIssueCode.custom, path: ["scope", "volumeIds"], message: "分卷不能重复选择" });
649
+ }
650
+ if (validChapterIds && scope?.type !== "chapter") {
651
+ context.addIssue({ code: z.ZodIssueCode.custom, path: ["scope", "type"], message: "章节选择只能用于章节分析范围" });
652
+ }
653
+ if (validVolumeIds && scope?.type !== "volume") {
654
+ context.addIssue({ code: z.ZodIssueCode.custom, path: ["scope", "type"], message: "分卷选择只能用于分卷分析范围" });
655
+ }
656
+ if (scope?.type === "chapter" && typeof scope.chapterId !== "string" && !validChapterIds) {
657
+ context.addIssue({ code: z.ZodIssueCode.custom, path: ["scope", "chapterId"], message: "指定章节分析必须提供章节标识" });
658
+ }
659
+ if (scope?.type === "volume" && typeof scope.volumeId !== "string" && !validVolumeIds) {
660
+ context.addIssue({ code: z.ZodIssueCode.custom, path: ["scope", "volumeId"], message: "指定分卷分析必须提供分卷标识" });
661
+ }
608
662
  if (input.scope?.includeAllSettings !== undefined) {
609
663
  context.addIssue({ code: z.ZodIssueCode.custom, path: ["scope", "includeAllSettings"], message: "包含所有设定仅支持人物关系分析" });
610
664
  }
@@ -2094,6 +2148,17 @@ export function createRuntime(options) {
2094
2148
  const permissions = requestPermissions(request, request.params.workId);
2095
2149
  data(response, mapRecords(store.listTaskSummariesPage(request.params.workId, parsePagination(request.query) ?? { page: 1, limit: 30, offset: 0 }), (task) => redactTaskCharacterNames(task, permissions)));
2096
2150
  });
2151
+ app.post("/api/works/:workId/tasks/context-preview", (request, response) => {
2152
+ const input = parse(analysisTaskSchema, request.body);
2153
+ const permissions = requestPermissions(request, request.params.workId);
2154
+ const deniedModules = analysisTaskReadModules(input.taskType, input.scope).filter((module) => permissions[module] === "none");
2155
+ if (deniedModules.length > 0) {
2156
+ throw new AppError(403, "WORK_MODULE_READ_DENIED", "你没有读取 AI 分析上下文预检所需资料模块的权限", {
2157
+ modules: deniedModules
2158
+ });
2159
+ }
2160
+ data(response, ai.previewAnalysisTaskContext(request.params.workId, input));
2161
+ });
2097
2162
  app.post("/api/works/:workId/tasks/relationship-source-preview", async (request, response) => {
2098
2163
  const input = parse(z.object({
2099
2164
  scope: relationshipAnalysisScopeSchema,