@waterwx/dsh-novel-forge 1.6.0 → 1.7.2
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/lib/client.js +37690 -2269
- package/lib/client.js.map +1 -1
- package/lib/index.js +767 -56
- package/lib/index.js.map +1 -1
- package/lib/types/client/api.d.ts +3 -0
- package/lib/types/client/locales.d.ts +0 -1
- package/lib/types/client/panel/FlowGuide.d.ts +21 -0
- package/lib/types/client/panel/MangaRoleLibrary.d.ts +18 -0
- package/lib/types/client/panel/MangaWorkspace.d.ts +6 -4
- package/lib/types/client/panel/RoleVisualPanel.d.ts +5 -3
- package/lib/types/client/panel/SceneLibrary.d.ts +1 -1
- package/lib/types/client/panel/StoryboardTab.d.ts +6 -2
- package/lib/types/engine.d.ts +23 -9
- package/lib/types/index.d.ts +6 -4
- package/lib/types/protocol.d.ts +171 -3
- package/package.json +100 -98
- package/src/client/api.ts +9 -0
- package/src/client/locales.ts +0 -1
- package/src/client/panel/AssetsTab.tsx +22 -22
- package/src/client/panel/AssistantTab.tsx +3 -3
- package/src/client/panel/BookshelfBar.tsx +1 -1
- package/src/client/panel/CreateBookView.tsx +10 -10
- package/src/client/panel/FlowGuide.tsx +83 -0
- package/src/client/panel/MangaRoleLibrary.tsx +810 -0
- package/src/client/panel/MangaWorkspace.tsx +359 -293
- package/src/client/panel/NovelPanel.tsx +465 -307
- package/src/client/panel/ReaderView.tsx +4 -4
- package/src/client/panel/RunPanel.tsx +9 -9
- package/src/client/panel/SceneLibrary.tsx +69 -68
- package/src/client/panel/ShelfView.tsx +28 -35
- package/src/client/panel/StoryboardTab.tsx +106 -42
- package/src/client/panel/StyleCard.tsx +13 -13
- package/src/client/panel/StyleGallery.tsx +2 -2
- package/src/client/panel/WorldTab.tsx +5 -5
- package/src/client/panel/panel.module.css +1189 -454
- package/src/client/panel/views.tsx +24 -24
- package/src/engine.ts +530 -59
- package/src/index.ts +37 -6
- package/src/protocol.ts +175 -3
- package/src/routes.ts +229 -1
- package/src/client/panel/RoleVisualPanel.tsx +0 -468
|
@@ -98,7 +98,10 @@ export declare class NovelApi {
|
|
|
98
98
|
no: number;
|
|
99
99
|
}>;
|
|
100
100
|
/** 角色库:AI 提炼 / 采纳 / 更新 / 删除。 */
|
|
101
|
+
imageTest(req: import('../protocol.ts').ImageTestRequest): Promise<import('../protocol.ts').ImageTestResponse>;
|
|
101
102
|
roles(req: import('../protocol.ts').RolesRequest): Promise<import('../protocol.ts').RolesResponse>;
|
|
103
|
+
/** 漫剧角色库:从分镜提名 / 建卡 / 更新 / 删除 / 形象锚点 / 精修提示词。 */
|
|
104
|
+
mangaRoles(req: import('../protocol.ts').MangaRolesRequest): Promise<import('../protocol.ts').MangaRolesResponse>;
|
|
102
105
|
/** 场景库:AI 提炼 / 采纳 / 更新 / 删除 / 图集。 */
|
|
103
106
|
scenes(req: import('../protocol.ts').ScenesRequest): Promise<import('../protocol.ts').ScenesResponse>;
|
|
104
107
|
/** 视觉世界观规则:提炼 / 保存。 */
|
|
@@ -153,7 +153,6 @@ export declare const zh: {
|
|
|
153
153
|
readonly 'settings.reasoning.max': "max · 最高思考(质检/推演)";
|
|
154
154
|
readonly 'settings.theme': "主题";
|
|
155
155
|
readonly 'settings.themeLiquid': "iOS 液态玻璃(绿)";
|
|
156
|
-
readonly 'settings.themeClassic': "经典毛玻璃(蓝)";
|
|
157
156
|
readonly 'settings.themeNeumorph': "新拟物(双阴影)";
|
|
158
157
|
readonly 'settings.themeHint': "存于浏览器本地,即时生效";
|
|
159
158
|
readonly 'settings.chapterChars': "每章目标字数";
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 漫剧工作台·全流程步骤条(唯一导航,方案X):
|
|
3
|
+
* ①创建方案 → ②视觉规则 → ③剧情骨架 → ④分镜表 → ⑤导入角色 → ⑥角色定妆 → ⑦视频提示词 → ⑧场景库 → ⑨导出使用。
|
|
4
|
+
* 每个步骤对应一个独立页面主体;完成度自动判定(读 project 现有字段)。
|
|
5
|
+
*/
|
|
6
|
+
import type { ProjectState } from '../../protocol.ts';
|
|
7
|
+
/** 步骤 → 页面主体的一一对应目标。 */
|
|
8
|
+
export type FlowTarget = 'plan' | 'rules' | 'skeleton' | 'table' | 'import' | 'makeup' | 'prompts' | 'scenes' | 'export';
|
|
9
|
+
export interface FlowStep {
|
|
10
|
+
no: number;
|
|
11
|
+
label: string;
|
|
12
|
+
hint: string;
|
|
13
|
+
done: boolean;
|
|
14
|
+
target: FlowTarget;
|
|
15
|
+
}
|
|
16
|
+
/** 依据 project 数据计算 9 步完成度(与存储顺序无关,按生产顺序排列)。 */
|
|
17
|
+
export declare function computeFlowSteps(project: ProjectState | null): FlowStep[];
|
|
18
|
+
export declare function FlowGuide({ project, onNavigate, }: {
|
|
19
|
+
project: ProjectState | null;
|
|
20
|
+
onNavigate: (target: FlowTarget) => void;
|
|
21
|
+
}): import("react").JSX.Element;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { NovelApi } from '../api.ts';
|
|
2
|
+
import type { ImageModelConfig, ProjectState } from '../../protocol.ts';
|
|
3
|
+
export declare function MangaRoleLibrary({ api, project, refresh, styleId, filterId, imageApiEnabled, imageModels, focus, showCards, onProgress, }: {
|
|
4
|
+
api: NovelApi;
|
|
5
|
+
project: ProjectState | null;
|
|
6
|
+
refresh: () => void | Promise<void>;
|
|
7
|
+
styleId?: string;
|
|
8
|
+
filterId?: string;
|
|
9
|
+
/** 是否启用生图(豆包等出定妆图)。 */
|
|
10
|
+
imageApiEnabled?: boolean;
|
|
11
|
+
/** 生图模型库(出定妆图时可选择用哪条)。 */
|
|
12
|
+
imageModels?: ImageModelConfig[];
|
|
13
|
+
/** 步骤页聚焦:import=展开并滚动到导入区;cards=滚动到已建漫剧卡列表。 */
|
|
14
|
+
focus?: 'import' | 'cards';
|
|
15
|
+
/** 是否显示「已建漫剧卡」列表(第⑤步导入页可隐藏,只留导入区)。 */
|
|
16
|
+
showCards?: boolean;
|
|
17
|
+
onProgress?: (text: string, kind?: 'info' | 'done' | 'error') => void;
|
|
18
|
+
}): import("react").JSX.Element;
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import type { NovelApi } from '../api.ts';
|
|
2
|
-
import type { ChapterPlan, ProjectState } from '../../protocol.ts';
|
|
3
|
-
export declare function MangaWorkspace({ api, project, chapters, onProjectChanged, imageApiEnabled, onProgress, }: {
|
|
2
|
+
import type { ChapterPlan, ImageModelConfig, ProjectState } from '../../protocol.ts';
|
|
3
|
+
export declare function MangaWorkspace({ api, project, chapters, onProjectChanged, imageApiEnabled, imageModels, onProgress, }: {
|
|
4
4
|
api: NovelApi;
|
|
5
5
|
project: ProjectState | null;
|
|
6
6
|
chapters: ChapterPlan[];
|
|
7
7
|
/** 方案/资产变更已持久化后触发(刷新项目)。 */
|
|
8
8
|
onProjectChanged?: () => void | Promise<void>;
|
|
9
|
-
/**
|
|
9
|
+
/** 是否启用生图(漫剧卡出定妆图)。 */
|
|
10
10
|
imageApiEnabled?: boolean;
|
|
11
|
-
/**
|
|
11
|
+
/** 生图模型库(出定妆图时可选择模型)。 */
|
|
12
|
+
imageModels?: ImageModelConfig[];
|
|
13
|
+
/** 上报到「AI进度」控制台(漫剧工作台内所有 LLM/方案操作)。 */
|
|
12
14
|
onProgress?: (text: string, kind?: 'info' | 'done' | 'error') => void;
|
|
13
15
|
}): import("react").JSX.Element;
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import type { NovelApi } from '../api.ts';
|
|
2
|
-
import type { ProjectState } from '../../protocol.ts';
|
|
3
|
-
export declare function RoleVisualPanel({ api, project, refresh, styleId, filterId, imageApiEnabled, onGotoRoles, onProgress, }: {
|
|
2
|
+
import type { ImageModelConfig, ProjectState } from '../../protocol.ts';
|
|
3
|
+
export declare function RoleVisualPanel({ api, project, refresh, styleId, filterId, imageApiEnabled, imageModels, onGotoRoles, onProgress, }: {
|
|
4
4
|
api: NovelApi;
|
|
5
5
|
project: ProjectState | null;
|
|
6
6
|
refresh: () => void | Promise<void>;
|
|
7
7
|
styleId?: string;
|
|
8
8
|
filterId?: string;
|
|
9
9
|
imageApiEnabled?: boolean;
|
|
10
|
+
/** 生图模型库(AI 生图时可选择用哪条)。 */
|
|
11
|
+
imageModels?: ImageModelConfig[];
|
|
10
12
|
onGotoRoles?: () => void;
|
|
11
|
-
/**
|
|
13
|
+
/** 上报到「AI进度」控制台(角色形象页 / 漫剧工作台共用)。 */
|
|
12
14
|
onProgress?: (text: string, kind?: 'info' | 'done' | 'error') => void;
|
|
13
15
|
}): import("react").JSX.Element;
|
|
@@ -9,6 +9,6 @@ export declare function SceneLibrary({ api, project, refresh, styleId, filterId,
|
|
|
9
9
|
styleId?: string;
|
|
10
10
|
/** 可选滤镜风格 id。 */
|
|
11
11
|
filterId?: string;
|
|
12
|
-
/**
|
|
12
|
+
/** 上报到「AI进度」控制台。 */
|
|
13
13
|
onProgress?: (text: string, kind?: 'info' | 'done' | 'error') => void;
|
|
14
14
|
}): import("react").JSX.Element;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { NovelApi } from '../api.ts';
|
|
2
2
|
import type { ChapterPlan, ProjectState } from '../../protocol.ts';
|
|
3
|
-
export declare function StoryboardTab({ api, project, chapters, onProjectChanged, styleId, filterId, onProgress, }: {
|
|
3
|
+
export declare function StoryboardTab({ api, project, chapters, onProjectChanged, styleId, filterId, mode, onGoStep, onProgress, }: {
|
|
4
4
|
api: NovelApi;
|
|
5
5
|
project: ProjectState | null;
|
|
6
6
|
chapters: ChapterPlan[];
|
|
@@ -10,6 +10,10 @@ export declare function StoryboardTab({ api, project, chapters, onProjectChanged
|
|
|
10
10
|
styleId?: string;
|
|
11
11
|
/** 可选滤镜风格 id。 */
|
|
12
12
|
filterId?: string;
|
|
13
|
-
/**
|
|
13
|
+
/** 页面模式:auto=按本章实际进度显示;skeleton/table/prompts=固定显示该步骤(前置不足显示提示,不降级)。 */
|
|
14
|
+
mode?: 'auto' | 'skeleton' | 'table' | 'prompts';
|
|
15
|
+
/** 「下一步」按钮回调(1=骨架→2=分镜表→3=提示词),供外层切步骤页。 */
|
|
16
|
+
onGoStep?: (n: 1 | 2 | 3) => void;
|
|
17
|
+
/** 上报到「AI进度」控制台(分镜三步生成)。 */
|
|
14
18
|
onProgress?: (text: string, kind?: 'info' | 'done' | 'error') => void;
|
|
15
19
|
}): import("react").JSX.Element;
|
package/lib/types/engine.d.ts
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
*/
|
|
13
13
|
export declare const COMPLIANCE_REDLINES: ReadonlyArray<string>;
|
|
14
14
|
import type { Context } from '@deepseek-ai/cordis';
|
|
15
|
-
import type { AuditIssue, AuthorReview, BreakdownResponse, ChapterPlan, Foreshadow, NovelConfig, OutlineCandidate, Plotline, PlotlineHealthReport, PlotlinePlan, ProjectState, ReviewReport, RoleRecord, RoleStatusCard, SceneCard, StoryBible, StoryboardSkeleton, StoryboardTable, StoryboardPrompt, Volume, WorldState } from './protocol.ts';
|
|
15
|
+
import type { AuditIssue, AuthorReview, BreakdownResponse, ChapterPlan, Foreshadow, NovelConfig, OutlineCandidate, Plotline, PlotlineHealthReport, PlotlinePlan, ProjectState, ReviewReport, RoleRecord, RoleStatusCard, SceneCard, StoryBible, StoryboardSkeleton, StoryboardTable, StoryboardPrompt, MangaRoleCandidate, Volume, WorldState } from './protocol.ts';
|
|
16
16
|
/** Project state file name inside the output dir. */
|
|
17
17
|
export declare const PROJECT_FILE = "novel-project.json";
|
|
18
18
|
/** Chapter output file name, e.g. 第001章_开篇.md */
|
|
@@ -109,16 +109,20 @@ export interface RoleVisualPrompt {
|
|
|
109
109
|
/** 四类精修提示词(立绘/四视图/表情/细节,一次提炼直接产出)。 */
|
|
110
110
|
promptKit?: RoleRecord['promptKit'];
|
|
111
111
|
}
|
|
112
|
-
/**
|
|
113
|
-
* 为单个角色提炼「动漫形象描述词」:扫描该角色出场的已写章节正文,
|
|
114
|
-
* 截取含外貌描写的段落,交给 LLM 提炼中文描述 + 英文绘图标签。
|
|
115
|
-
*/
|
|
112
|
+
/** 小说角色库:提炼单个角色的形象锚点并写回角色卡。 */
|
|
116
113
|
export declare function extractRoleVisual(ctx: Context, config: NovelConfig, project: ProjectState, outputDir: string, roleName: string, styleId?: string, filterId?: string): Promise<RoleVisualPrompt>;
|
|
114
|
+
/** 漫剧角色卡:提炼形象锚点并写回漫剧卡(status → anchored)。 */
|
|
115
|
+
export declare function extractMangaRoleVisual(ctx: Context, config: NovelConfig, project: ProjectState, outputDir: string, cardId: string, styleId?: string, filterId?: string): Promise<RoleVisualPrompt>;
|
|
116
|
+
/** 小说角色库:角色四类生图提示词精修包(写回角色卡)。 */
|
|
117
|
+
export declare function generateRolePromptKit(ctx: Context, config: NovelConfig, project: ProjectState, roleName: string, styleId?: string, filterId?: string): Promise<RoleRecord['promptKit']>;
|
|
118
|
+
/** 漫剧角色卡:四类生图提示词精修包(写回漫剧卡,status → anchored)。 */
|
|
119
|
+
export declare function generateMangaRolePromptKit(ctx: Context, config: NovelConfig, project: ProjectState, cardId: string, styleId?: string, filterId?: string): Promise<RoleRecord['promptKit']>;
|
|
117
120
|
/**
|
|
118
|
-
*
|
|
119
|
-
*
|
|
121
|
+
* 漫剧角色库·提名(两段式):从某章分镜的 characters 提名候选角色名 →
|
|
122
|
+
* 规则过滤(精确名 + 身份/简称匹配,短名单 ≤5)→ LLM 确认(是/否 + 选哪个,不做开放检索)→
|
|
123
|
+
* 返回带漫剧卡建议的候选(未匹配时给出「回小说库补提炼 / 漫剧直接创建」判定)。
|
|
120
124
|
*/
|
|
121
|
-
export declare function
|
|
125
|
+
export declare function nominateMangaRoles(ctx: Context, config: NovelConfig, project: ProjectState, outputDir: string, chapterNo: number): Promise<MangaRoleCandidate[]>;
|
|
122
126
|
/** ✨ 从道藏/红线提炼「视觉世界观规则」:生图/生视频必须遵守的设定纠偏(如"商品=人,禁止常规超市商品")。 */
|
|
123
127
|
export declare function extractVisualRules(ctx: Context, config: NovelConfig, project: ProjectState): Promise<string[]>;
|
|
124
128
|
/**
|
|
@@ -136,7 +140,17 @@ export declare function suggestOutlines(ctx: Context, config: NovelConfig, idea:
|
|
|
136
140
|
* @param budgetTokens token 预算上限(超过即截断章节取样)。
|
|
137
141
|
*/
|
|
138
142
|
export declare function breakdownBook(ctx: Context, config: NovelConfig, project: ProjectState, outputDir: string, scope?: string, preset?: 'quick' | 'standard', budgetTokens?: number): Promise<BreakdownResponse>;
|
|
139
|
-
|
|
143
|
+
/** 生图接口连通性测试(设置页模型条目用):GET {baseURL}/models,计时返回延迟。 */
|
|
144
|
+
export declare function testImageEndpoint(baseURL: string, apiKey: string, model?: string): Promise<{
|
|
145
|
+
ok: boolean;
|
|
146
|
+
ms: number;
|
|
147
|
+
message?: string;
|
|
148
|
+
modelFound?: boolean;
|
|
149
|
+
}>;
|
|
150
|
+
/** 小说角色库:生成角色定妆图并写回角色卡(imageUrl)。 */
|
|
151
|
+
export declare function generateRoleReferenceImage(ctx: Context, config: NovelConfig, project: ProjectState, outputDir: string, name: string, style?: string, modelId?: string): Promise<string>;
|
|
152
|
+
/** 漫剧角色卡:生成定妆图并写回漫剧卡(imageUrl)。 */
|
|
153
|
+
export declare function generateMangaRoleReferenceImage(ctx: Context, config: NovelConfig, project: ProjectState, outputDir: string, cardId: string, style?: string, modelId?: string): Promise<string>;
|
|
140
154
|
/** 🩺 剧情健康检查:基于已写章节数/各线状态/编年录,判断是否需要新线及添加时机。 */
|
|
141
155
|
export declare function analyzePlotlineHealth(ctx: Context, config: NovelConfig, project: ProjectState): Promise<PlotlineHealthReport>;
|
|
142
156
|
/** ✨ AI 剧情方案:基于健康检查结果设计下一阶段方向与建议新线。 */
|
package/lib/types/index.d.ts
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
*/
|
|
9
9
|
import type { Context } from '@deepseek-ai/cordis';
|
|
10
10
|
import z from 'schemastery';
|
|
11
|
-
import type { NovelConfig } from './protocol.ts';
|
|
11
|
+
import type { ImageModelConfig, NovelConfig } from './protocol.ts';
|
|
12
12
|
/** Stable cordis plugin name. */
|
|
13
13
|
export declare const name = "novel-forge";
|
|
14
14
|
/** Services required before the novel-forge surfaces can mount. */
|
|
@@ -49,11 +49,13 @@ export interface Config {
|
|
|
49
49
|
autoAuthorReview?: boolean;
|
|
50
50
|
/** 修订/润色产出草稿后自动附带一次 AI 审查(默认开,可在设置页关闭省 token)。 */
|
|
51
51
|
autoReviewAfterRevise?: boolean;
|
|
52
|
-
/**
|
|
52
|
+
/** 生图模型库(多套并存,启用一条生效)。 */
|
|
53
|
+
imageModels?: ImageModelConfig[];
|
|
54
|
+
/** 豆包/Seedream 生图 API Key(旧字段,兼容迁移用)。 */
|
|
53
55
|
imageApiKey?: string;
|
|
54
|
-
/** 豆包/Seedream 生图模型 ID
|
|
56
|
+
/** 豆包/Seedream 生图模型 ID(旧字段,兼容迁移用)。 */
|
|
55
57
|
imageApiModel?: string;
|
|
56
|
-
/**
|
|
58
|
+
/** 是否启用豆包生图(旧字段,兼容迁移用)。 */
|
|
57
59
|
imageApiEnabled?: boolean;
|
|
58
60
|
}
|
|
59
61
|
export declare const Config: z<Config>;
|
package/lib/types/protocol.d.ts
CHANGED
|
@@ -43,12 +43,16 @@ export declare const NOVEL_API: {
|
|
|
43
43
|
readonly bookshelfImportTextPreview: "/api/dsh-novel-forge/bookshelf/import-text/preview";
|
|
44
44
|
/** 漫剧方案管理:create/remove/activate。 */
|
|
45
45
|
readonly manhuaPlans: "/api/dsh-novel-forge/manhua/plans";
|
|
46
|
+
/** 漫剧角色库:从分镜提名(规则+LLM两段式)/ 建卡 / 更新 / 删除 / 形象锚点 / 精修提示词。 */
|
|
47
|
+
readonly mangaRoles: "/api/dsh-novel-forge/manga/roles";
|
|
46
48
|
/** 分镜·编剧级:单章 → 剧情骨架(节拍链)。 */
|
|
47
49
|
readonly storyboardSkeleton: "/api/dsh-novel-forge/storyboard/skeleton";
|
|
48
50
|
/** 分镜·导演级:骨架 → 分镜表(镜头级)。 */
|
|
49
51
|
readonly storyboardTable: "/api/dsh-novel-forge/storyboard/table";
|
|
50
52
|
/** 分镜·提示词级:分镜表 → 即梦可粘贴视频提示词。 */
|
|
51
53
|
readonly storyboardPrompts: "/api/dsh-novel-forge/storyboard/prompts";
|
|
54
|
+
/** 生图接口连通性测试(设置页每个模型条目用)。 */
|
|
55
|
+
readonly imageTest: "/api/dsh-novel-forge/image-test";
|
|
52
56
|
/** 重置项目(可选携带新大纲):清空设定/卷/章节/伏笔/资产/事实库。 */
|
|
53
57
|
readonly reset: "/api/dsh-novel-forge/reset";
|
|
54
58
|
/** 全书一致性质检:LLM 扫描已生成章节,输出矛盾问题清单。 */
|
|
@@ -218,6 +222,8 @@ export interface StoryboardSkeleton {
|
|
|
218
222
|
arc: string;
|
|
219
223
|
/** 剧情节拍链(时间顺序,因果连贯)。 */
|
|
220
224
|
beats: StoryboardBeat[];
|
|
225
|
+
/** 本章全部出镜角色(正文中的确切称谓,去重;漫剧角色库提名地基)。 */
|
|
226
|
+
characters?: string[];
|
|
221
227
|
}
|
|
222
228
|
/** POST /storyboard/skeleton 请求:生成单章剧情骨架。 */
|
|
223
229
|
export interface StoryboardSkeletonRequest {
|
|
@@ -251,6 +257,10 @@ export interface StoryboardShot {
|
|
|
251
257
|
prevState: string;
|
|
252
258
|
/** 本镜头结束状态。 */
|
|
253
259
|
nextState: string;
|
|
260
|
+
/** 本镜头出镜角色(引用小说库规范名/漫剧卡名,1-4 个;漫剧角色库提名地基)。 */
|
|
261
|
+
characters?: string[];
|
|
262
|
+
/** 本镜头已绑定漫剧卡的 id(定妆图引用,供出图/生视频时按卡取参考图)。 */
|
|
263
|
+
mangaRoleIds?: string[];
|
|
254
264
|
}
|
|
255
265
|
/** 分镜·导演级:单章分镜表。 */
|
|
256
266
|
export interface StoryboardTable {
|
|
@@ -258,6 +268,10 @@ export interface StoryboardTable {
|
|
|
258
268
|
shots: StoryboardShot[];
|
|
259
269
|
/** 生成时注入的场景卡名称(前端标注消费关系)。 */
|
|
260
270
|
usedScenes?: string[];
|
|
271
|
+
/** 本章全部出镜角色(各镜头 characters 去重汇总;骨架有则兜底)。 */
|
|
272
|
+
characters?: string[];
|
|
273
|
+
/** 本章已绑定漫剧卡的 id(去重汇总,定妆图引用)。 */
|
|
274
|
+
mangaRoleIds?: string[];
|
|
261
275
|
}
|
|
262
276
|
/** POST /storyboard/table 请求:骨架 → 分镜表。 */
|
|
263
277
|
export interface StoryboardTableRequest {
|
|
@@ -279,6 +293,8 @@ export interface StoryboardPrompt {
|
|
|
279
293
|
shotId: string;
|
|
280
294
|
/** 即梦/视频模型可粘贴的中文提示词(画面+运镜+光效+风格词块)。 */
|
|
281
295
|
text: string;
|
|
296
|
+
/** 本镜头绑定的漫剧卡 id(定妆图引用:出图/生视频时按卡取 imageUrl/立绘)。 */
|
|
297
|
+
mangaRoleIds?: string[];
|
|
282
298
|
}
|
|
283
299
|
/** 分镜持久化:单章的分镜产出(骨架 + 分镜表 + 视频提示词,可分别存在)。 */
|
|
284
300
|
export interface ChapterStoryboard {
|
|
@@ -333,6 +349,112 @@ export interface MangaPlansRequest {
|
|
|
333
349
|
export interface MangaPlansResponse {
|
|
334
350
|
plans: MangaPlan[];
|
|
335
351
|
}
|
|
352
|
+
/** 漫剧角色卡:制作角色(要建模/出图/锁一致性的「上镜角色」),与小说角色库弱关联。 */
|
|
353
|
+
export interface MangaRoleCard {
|
|
354
|
+
/** 稳定 id。 */
|
|
355
|
+
id: string;
|
|
356
|
+
/** 来源小说角色名(只读追溯,非强外键;禁止反向写回小说库)。 */
|
|
357
|
+
sourceRoleName?: string;
|
|
358
|
+
/** 漫剧用名(可短剧化改名)。 */
|
|
359
|
+
name: string;
|
|
360
|
+
/** 身份一句话。 */
|
|
361
|
+
identity: string;
|
|
362
|
+
/** 核心功能:主角/导师/感情线/反派/搭档/线人/功能性。 */
|
|
363
|
+
coreFunction: 'protagonist' | 'mentor' | 'love_interest' | 'antagonist' | 'sidekick' | 'informant' | 'functional';
|
|
364
|
+
/** 与主角的关系。 */
|
|
365
|
+
protagonistRelation: 'enemy' | 'friend' | 'mentor' | 'lover' | 'exploit' | 'neutral';
|
|
366
|
+
/** 口头禅/说话方式(配音一致性)。 */
|
|
367
|
+
speechStyle: string;
|
|
368
|
+
/** ≤3 个极致性格标签。 */
|
|
369
|
+
traits: string[];
|
|
370
|
+
/** 1-2 个辨识度外貌点。 */
|
|
371
|
+
appearance: string;
|
|
372
|
+
/** 3-5 个关键剧情节点。 */
|
|
373
|
+
keyScenes: string[];
|
|
374
|
+
/** 上场集数(分镜提名导入时记录)。 */
|
|
375
|
+
appearsInEpisodes: number[];
|
|
376
|
+
/** 待匹配 → 待确认 → 已导入 → 已定妆 → 已归档。 */
|
|
377
|
+
status: 'pending_match' | 'pending_confirm' | 'imported' | 'anchored' | 'archived';
|
|
378
|
+
/** 形象资产(沿用小说角色库同款结构)。 */
|
|
379
|
+
imagePrompt?: RoleRecord['imagePrompt'];
|
|
380
|
+
/** 情绪表情清单(锚点提炼时产出)。 */
|
|
381
|
+
expressions?: string[];
|
|
382
|
+
/** 四类精修生图提示词(立绘/四视图/表情/细节)。 */
|
|
383
|
+
promptKit?: RoleRecord['promptKit'];
|
|
384
|
+
/** 角色参考图。 */
|
|
385
|
+
imageUrl?: string;
|
|
386
|
+
/** 图集(图像锚点)。 */
|
|
387
|
+
gallery?: RoleImage[];
|
|
388
|
+
/** 生成锚点/精修时的方案风格 id(旧风格检测用)。 */
|
|
389
|
+
promptStyleId?: string;
|
|
390
|
+
createdAt: string;
|
|
391
|
+
updatedAt: string;
|
|
392
|
+
}
|
|
393
|
+
/** 分镜提名 → 小说角色库匹配的一条候选。 */
|
|
394
|
+
export interface MangaRoleCandidate {
|
|
395
|
+
/** 分镜里的原始称谓(正文确切用法)。 */
|
|
396
|
+
rawName: string;
|
|
397
|
+
/** matched=命中小说角色;ambiguous=多个候选待定;not_in_library=小说库没有;already_imported=已建漫剧卡(跳过)。 */
|
|
398
|
+
verdict: 'matched' | 'ambiguous' | 'not_in_library' | 'already_imported';
|
|
399
|
+
/** 规则阶段候选短名单(≤5,精确名优先 + 身份/简称匹配)。 */
|
|
400
|
+
matches: Array<{
|
|
401
|
+
roleName: string;
|
|
402
|
+
reason: string;
|
|
403
|
+
}>;
|
|
404
|
+
/** LLM/规则确认的命中角色名(ambiguous 时可能为空)。 */
|
|
405
|
+
matchedRoleName?: string;
|
|
406
|
+
/** not_in_library 时给出建议:backfill=正文有该称谓但小说库漏提炼(回小说库补);manga_new=漫剧新增角色(直接建卡)。 */
|
|
407
|
+
novelHint?: 'backfill' | 'manga_new';
|
|
408
|
+
/** 采纳时预填的漫剧卡建议。 */
|
|
409
|
+
suggested: {
|
|
410
|
+
name: string;
|
|
411
|
+
identity: string;
|
|
412
|
+
coreFunction: MangaRoleCard['coreFunction'];
|
|
413
|
+
protagonistRelation: MangaRoleCard['protagonistRelation'];
|
|
414
|
+
speechStyle: string;
|
|
415
|
+
traits: string[];
|
|
416
|
+
appearance: string;
|
|
417
|
+
keyScenes: string[];
|
|
418
|
+
};
|
|
419
|
+
}
|
|
420
|
+
/** POST /manga/roles 请求:漫剧角色库操作。 */
|
|
421
|
+
export interface MangaRolesRequest {
|
|
422
|
+
op: 'nominate' | 'adopt' | 'update' | 'remove' | 'visual' | 'promptKit' | 'image' | 'removeImage' | 'imageGenerate' | 'mode';
|
|
423
|
+
/** op='mode':短剧精简模式开关。 */
|
|
424
|
+
shortDramaMode?: boolean;
|
|
425
|
+
/** op='nominate':从哪章分镜提名角色。 */
|
|
426
|
+
chapterNo?: number;
|
|
427
|
+
/** op='adopt' / op='update':漫剧角色卡。 */
|
|
428
|
+
card?: MangaRoleCard;
|
|
429
|
+
/** op='remove' / 'visual' / 'promptKit' / 'image' / 'removeImage' / 'imageGenerate':漫剧卡 id。 */
|
|
430
|
+
id?: string;
|
|
431
|
+
/** op='visual' / 'promptKit':漫剧方案基底风格 id。 */
|
|
432
|
+
styleId?: string;
|
|
433
|
+
/** 可选滤镜风格 id。 */
|
|
434
|
+
filterId?: string;
|
|
435
|
+
/** op='image':定妆图 dataURL。 */
|
|
436
|
+
dataUrl?: string;
|
|
437
|
+
/** op='image':图集用途标签(立绘/四视图/表情-x/场景/细节);缺省视为角色参考图(imageUrl)。 */
|
|
438
|
+
label?: string;
|
|
439
|
+
/** op='imageGenerate':漫画风格预设 id(可选)。 */
|
|
440
|
+
style?: string;
|
|
441
|
+
/** op='imageGenerate':生图模型库条目 id(缺省用启用条目)。 */
|
|
442
|
+
modelId?: string;
|
|
443
|
+
}
|
|
444
|
+
/** POST /manga/roles 响应。 */
|
|
445
|
+
export interface MangaRolesResponse {
|
|
446
|
+
cards: MangaRoleCard[];
|
|
447
|
+
/** op='nominate' 时的 AI 提名候选。 */
|
|
448
|
+
candidates?: MangaRoleCandidate[];
|
|
449
|
+
/** op='visual' 时的形象锚点(已写入漫剧卡)。 */
|
|
450
|
+
visual?: RoleRecord['imagePrompt'];
|
|
451
|
+
/** op='promptKit' 时的四类精修提示词包(已写入漫剧卡)。 */
|
|
452
|
+
promptKit?: RoleRecord['promptKit'];
|
|
453
|
+
/** op='image' / 'imageGenerate' 时的定妆图 dataURL(已写入漫剧卡)。 */
|
|
454
|
+
imageUrl?: string;
|
|
455
|
+
/** op='mode' 时的短剧精简模式状态。 */
|
|
456
|
+
shortDramaMode?: boolean;
|
|
457
|
+
}
|
|
336
458
|
/** Chapter lifecycle states (the writing pipeline's state machine). */
|
|
337
459
|
export type ChapterStatus = 'pending' | 'generating' | 'written' | 'reviewing' | 'approved' | 'rejected' | 'error';
|
|
338
460
|
/** One chapter in the plan. */
|
|
@@ -825,11 +947,32 @@ export interface RolesRequest {
|
|
|
825
947
|
label?: string;
|
|
826
948
|
/** op='imageGenerate' 时的漫画风格预设 id(用于统一角色图与漫画页风格)。 */
|
|
827
949
|
style?: string;
|
|
950
|
+
/** op='imageGenerate' 时指定生图模型库条目 id(缺省用启用条目)。 */
|
|
951
|
+
modelId?: string;
|
|
828
952
|
/** op='visual' / op='promptKit' 时的漫剧基底风格 id(角色图按方案风格重出)。 */
|
|
829
953
|
styleId?: string;
|
|
830
954
|
/** op='visual' / op='promptKit' 时的可选滤镜风格 id。 */
|
|
831
955
|
filterId?: string;
|
|
832
956
|
}
|
|
957
|
+
/** POST /image-test 请求:测一个生图接口的连通性与延迟(不落盘)。 */
|
|
958
|
+
export interface ImageTestRequest {
|
|
959
|
+
/** OpenAI 兼容生图接口地址。 */
|
|
960
|
+
baseURL: string;
|
|
961
|
+
/** API Key。 */
|
|
962
|
+
apiKey: string;
|
|
963
|
+
/** 模型 id(顺带校验是否在接口模型列表里,可选)。 */
|
|
964
|
+
model?: string;
|
|
965
|
+
}
|
|
966
|
+
/** POST /image-test 响应。 */
|
|
967
|
+
export interface ImageTestResponse {
|
|
968
|
+
ok: boolean;
|
|
969
|
+
/** 连通延迟(毫秒)。 */
|
|
970
|
+
ms?: number;
|
|
971
|
+
/** 失败原因。 */
|
|
972
|
+
message?: string;
|
|
973
|
+
/** 模型 id 是否出现在接口的模型列表(探测成功时才有)。 */
|
|
974
|
+
modelFound?: boolean;
|
|
975
|
+
}
|
|
833
976
|
/** POST /roles 响应。 */
|
|
834
977
|
export interface RolesResponse {
|
|
835
978
|
roles: RoleRecord[];
|
|
@@ -956,6 +1099,10 @@ export interface ProjectState {
|
|
|
956
1099
|
plotlines?: Plotline[];
|
|
957
1100
|
/** 角色库(作者维护 + AI 提炼的主表)。 */
|
|
958
1101
|
roles?: RoleRecord[];
|
|
1102
|
+
/** 漫剧角色库(制作角色投影:从分镜提名导入,独立于小说角色库)。 */
|
|
1103
|
+
mangaRoles?: MangaRoleCard[];
|
|
1104
|
+
/** 短剧精简模式:漫剧角色库按 5-8 上镜角色 / 功能标签 / 关系闭环 / 人设极致化约束。 */
|
|
1105
|
+
shortDramaMode?: boolean;
|
|
959
1106
|
/** 场景库(作者维护 + AI 提炼的主表)。 */
|
|
960
1107
|
scenes?: SceneCard[];
|
|
961
1108
|
/** 视觉世界观规则(生图/生视频必须遵守,从道藏提炼,注入所有提示词)。 */
|
|
@@ -973,6 +1120,21 @@ export interface ProjectState {
|
|
|
973
1120
|
createdAt: string;
|
|
974
1121
|
updatedAt: string;
|
|
975
1122
|
}
|
|
1123
|
+
/** 生图模型配置(模型库条目,可多套并存,启用一条生效)。 */
|
|
1124
|
+
export interface ImageModelConfig {
|
|
1125
|
+
/** 条目 id(本地唯一)。 */
|
|
1126
|
+
id: string;
|
|
1127
|
+
/** 展示名(如「豆包 Seedream」「即梦」)。 */
|
|
1128
|
+
name: string;
|
|
1129
|
+
/** OpenAI 兼容生图接口地址(如 https://ark.cn-beijing.volces.com/api/v3)。 */
|
|
1130
|
+
baseURL: string;
|
|
1131
|
+
/** API Key。 */
|
|
1132
|
+
apiKey: string;
|
|
1133
|
+
/** 生图模型 id(如 doubao-seedream-5-0-pro-260628)。 */
|
|
1134
|
+
model: string;
|
|
1135
|
+
/** 是否启用(同时只启用一条)。 */
|
|
1136
|
+
enabled: boolean;
|
|
1137
|
+
}
|
|
976
1138
|
/** Runtime config surface exposed to the panel (subset of plugin Config). */
|
|
977
1139
|
export interface NovelConfig {
|
|
978
1140
|
/** Absolute path of the default docx outline to load. */
|
|
@@ -999,11 +1161,15 @@ export interface NovelConfig {
|
|
|
999
1161
|
autoAuthorReview: boolean;
|
|
1000
1162
|
/** 修订/润色产出草稿后是否自动附带一次 AI 审查(工作区显示新稿评分与剩余问题)。 */
|
|
1001
1163
|
autoReviewAfterRevise: boolean;
|
|
1002
|
-
/**
|
|
1164
|
+
/** 生图模型库(多套并存,启用一条生效;旧 imageApiKey/imageApiModel 自动迁移为一条)。 */
|
|
1165
|
+
imageModels?: ImageModelConfig[];
|
|
1166
|
+
/** 运行时生效的生图接口地址(= 启用条目,兼容旧代码读取)。 */
|
|
1167
|
+
imageBaseUrl?: string;
|
|
1168
|
+
/** 运行时生效的生图 API Key(= 启用条目,兼容旧代码读取)。 */
|
|
1003
1169
|
imageApiKey?: string;
|
|
1004
|
-
/**
|
|
1170
|
+
/** 运行时生效的生图模型 id(= 启用条目,兼容旧代码读取)。 */
|
|
1005
1171
|
imageApiModel?: string;
|
|
1006
|
-
/**
|
|
1172
|
+
/** 是否启用生图(= 存在启用条目)。 */
|
|
1007
1173
|
imageApiEnabled?: boolean;
|
|
1008
1174
|
}
|
|
1009
1175
|
/** GET /status response. */
|
|
@@ -1242,6 +1408,8 @@ export interface ConfigPatch {
|
|
|
1242
1408
|
imageApiKey?: string;
|
|
1243
1409
|
imageApiModel?: string;
|
|
1244
1410
|
imageApiEnabled?: boolean;
|
|
1411
|
+
/** 生图模型库(完整替换保存)。 */
|
|
1412
|
+
imageModels?: ImageModelConfig[];
|
|
1245
1413
|
}
|
|
1246
1414
|
/** One assistant conversation message (persisted per project). */
|
|
1247
1415
|
export interface AssistantMessage {
|