export type ProviderType = 'openai-compatible' | 'anthropic' | 'google' export type AgentRole = 'editor' | 'writer' | 'summarizer' /** * 章节状态流转: * planned(大纲已规划)→ briefed(主编已写简报)→ writing(作家写作中) * → written(等待用户确认)→ approved(已确认,摘要已入库) */ export type ChapterStatus = 'planned' | 'briefed' | 'writing' | 'written' | 'approved' export type VersionStatus = 'writing' | 'done' | 'error' | 'cancelled' export type JobType = 'outline' | 'brief' | 'write' | 'summarize' | 'review' | 'pipeline' export type JobStatus = 'running' | 'done' | 'error' | 'cancelled' export type LoreEntrySource = 'user' | 'card' export interface ProjectRequirements { /** 文风,如:细腻、冷峻、轻松幽默 */ style: string /** 输出语言 */ language: string /** 叙事视角:第一人称 / 第三人称有限 / 全知 */ pov: string /** 叙述方式补充:时态、节奏、对白比例等 */ narration: string /** 每章目标字数 */ wordsPerChapter: number /** 其他要求(禁用词、尺度等) */ extra: string } export interface ProjectSettings { /** 自动模式:章节写完后自动确认并继续下一章 */ autoMode: boolean /** 主编写完简报后暂停,等用户确认简报 */ pauseAfterBrief: boolean /** 允许主编自行创建作家 */ allowEditorCreateWriters: boolean /** 注入给作家的上一章结尾字数 */ prevTailChars: number /** 注入的最近章节摘要数量 */ recentSummaryCount: number /** 输出被截断时自动续写的最大次数 */ maxContinuations: number /** 自动模式下最多连续写作的章节数(防止失控) */ autoChapterLimit: number } export interface CharacterState { name: string state: string } export interface Foreshadowing { text: string status: 'open' | 'resolved' chapter: number resolvedChapter?: number } export interface ProjectMemory { characterStates: CharacterState[] foreshadowing: Foreshadowing[] timeline: { chapter: number, event: string }[] } export const DEFAULT_REQUIREMENTS: ProjectRequirements = { style: '', language: '简体中文', pov: '第三人称有限视角', narration: '', wordsPerChapter: 3000, extra: '' } export const DEFAULT_SETTINGS: ProjectSettings = { autoMode: false, pauseAfterBrief: false, allowEditorCreateWriters: true, prevTailChars: 1500, recentSummaryCount: 5, maxContinuations: 2, autoChapterLimit: 10 } export const EMPTY_MEMORY: ProjectMemory = { characterStates: [], foreshadowing: [], timeline: [] } export const CHAPTER_STATUS_LABEL: Record = { planned: '已规划', briefed: '已出简报', writing: '写作中', written: '待确认', approved: '已确认' } export const CHAPTER_STATUS_COLOR: Record = { planned: 'neutral', briefed: 'info', writing: 'warning', written: 'primary', approved: 'success' } export const ROLE_LABEL: Record = { editor: '主编', writer: '作家', summarizer: '摘要员' } export const JOB_TYPE_LABEL: Record = { outline: '规划大纲', brief: '章节简报', write: '写作', summarize: '摘要', review: '审稿', pipeline: '流水线' } /** 解析后的酒馆角色卡(统一为内部结构) */ export interface ParsedCard { spec: 'v1' | 'v2' | 'v3' name: string description: string personality: string scenario: string firstMes: string mesExample: string systemPrompt: string postHistoryInstructions: string creatorNotes: string alternateGreetings: string[] tags: string[] world: string lore: { title: string, keys: string[], content: string, constant: boolean, enabled: boolean, order: number }[] raw: Record } /** 服务端推送给前端的事件 */ export type ProjectEvent = | { type: 'job', job: JobInfo } | { type: 'delta', chapterId: string, versionId: string, text: string } | { type: 'chapter', chapterId: string } | { type: 'chapters' } | { type: 'agents' } | { type: 'pipeline', running: boolean, message?: string } | { type: 'log', level: 'info' | 'warn' | 'error', message: string } export interface JobInfo { id: string type: JobType status: JobStatus chapterId: string | null agentName: string modelLabel: string inputTokens: number outputTokens: number error: string log: string createdAt: string | number | Date finishedAt: string | number | Date | null }