2026-05-22 13:44:50 +08:00
|
|
|
|
from pydantic import BaseModel, ConfigDict, Field
|
|
|
|
|
|
|
|
|
|
|
|
from app.agents.state_schema import MemoirStateSchema as MemoirStateResponse
|
|
|
|
|
|
|
|
|
|
|
|
__all__ = [
|
|
|
|
|
|
"BookResponse",
|
|
|
|
|
|
"ChapterDetailResponse",
|
|
|
|
|
|
"ChapterListItemResponse",
|
|
|
|
|
|
"CoverGenerationResponse",
|
|
|
|
|
|
"ExportPdfRequest",
|
|
|
|
|
|
"ExportPdfResponse",
|
|
|
|
|
|
"ImageAssetResponse",
|
|
|
|
|
|
"MemoirStateResponse",
|
|
|
|
|
|
"NextQuestionContextResponse",
|
|
|
|
|
|
"ReadingSegmentResponse",
|
|
|
|
|
|
"SetChapterStoryOrderRequest",
|
|
|
|
|
|
"StatusMessageResponse",
|
|
|
|
|
|
"StoryOrderResponse",
|
|
|
|
|
|
"UpdateBookRequest",
|
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class ImageAssetResponse(BaseModel):
|
|
|
|
|
|
placeholder: str = ""
|
|
|
|
|
|
description: str = ""
|
|
|
|
|
|
index: int = 0
|
|
|
|
|
|
status: str = "pending"
|
|
|
|
|
|
prompt: str | None = None
|
|
|
|
|
|
url: str | None = None
|
|
|
|
|
|
provider: str | None = None
|
|
|
|
|
|
style: str | None = None
|
|
|
|
|
|
size: str | None = None
|
|
|
|
|
|
error: str | None = None
|
|
|
|
|
|
retryable: bool | None = None
|
|
|
|
|
|
created_at: str | None = None
|
|
|
|
|
|
updated_at: str | None = None
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class ReadingSegmentResponse(BaseModel):
|
|
|
|
|
|
story_id: str
|
|
|
|
|
|
body_markdown: str = ""
|
|
|
|
|
|
cover_asset: ImageAssetResponse | None = None
|
2026-03-18 17:18:23 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class UpdateBookRequest(BaseModel):
|
|
|
|
|
|
title: str
|
|
|
|
|
|
subtitle: str | None = None
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class ExportPdfRequest(BaseModel):
|
|
|
|
|
|
book_id: str
|
2026-03-20 15:15:35 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class SetChapterStoryOrderRequest(BaseModel):
|
|
|
|
|
|
"""按顺序绑定本章节要收录的 stories(覆盖原有 chapter_story_links)。"""
|
|
|
|
|
|
|
|
|
|
|
|
story_ids: list[str]
|
2026-05-22 13:44:50 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class BookResponse(BaseModel):
|
|
|
|
|
|
id: str | None = None
|
|
|
|
|
|
title: str | None = None
|
|
|
|
|
|
total_pages: int | None = None
|
|
|
|
|
|
total_words: int | None = None
|
|
|
|
|
|
cover_image_url: str | None = None
|
|
|
|
|
|
has_update: bool | None = None
|
|
|
|
|
|
last_update_chapter_id: str | None = None
|
|
|
|
|
|
message: str | None = None
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class StatusMessageResponse(BaseModel):
|
|
|
|
|
|
status: str
|
|
|
|
|
|
message: str | None = None
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class ExportPdfResponse(BaseModel):
|
|
|
|
|
|
pdf_base64: str
|
|
|
|
|
|
filename: str
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class ChapterListItemResponse(BaseModel):
|
|
|
|
|
|
model_config = ConfigDict(extra="ignore")
|
|
|
|
|
|
|
|
|
|
|
|
id: str
|
|
|
|
|
|
title: str | None = None
|
|
|
|
|
|
category: str | None = None
|
|
|
|
|
|
order_index: int | None = None
|
|
|
|
|
|
status: str = "draft"
|
|
|
|
|
|
summary: str = ""
|
|
|
|
|
|
canonical_markdown: str = ""
|
|
|
|
|
|
cover_asset: ImageAssetResponse | None = None
|
|
|
|
|
|
images: list[ImageAssetResponse] = Field(default_factory=list)
|
|
|
|
|
|
word_count: int = 0
|
|
|
|
|
|
updated_at: str | None = None
|
|
|
|
|
|
is_new: bool = False
|
|
|
|
|
|
source_segments: list[str] = Field(default_factory=list)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class ChapterDetailResponse(BaseModel):
|
|
|
|
|
|
model_config = ConfigDict(extra="ignore")
|
|
|
|
|
|
|
|
|
|
|
|
id: str
|
|
|
|
|
|
title: str | None = None
|
|
|
|
|
|
canonical_markdown: str = ""
|
|
|
|
|
|
order_index: int | None = None
|
|
|
|
|
|
status: str | None = None
|
|
|
|
|
|
category: str | None = None
|
|
|
|
|
|
images: list[ImageAssetResponse] = Field(default_factory=list)
|
|
|
|
|
|
cover_asset: ImageAssetResponse | None = None
|
|
|
|
|
|
reading_segments: list[ReadingSegmentResponse] = Field(default_factory=list)
|
|
|
|
|
|
updated_at: str | None = None
|
|
|
|
|
|
is_new: bool = False
|
|
|
|
|
|
source_segments: list[str] = Field(default_factory=list)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class CoverGenerationResponse(BaseModel):
|
|
|
|
|
|
triggered: list[str] = Field(default_factory=list)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class StoryOrderResponse(BaseModel):
|
|
|
|
|
|
status: str
|
|
|
|
|
|
chapter_id: str
|
|
|
|
|
|
story_count: int
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class NextQuestionContextResponse(BaseModel):
|
|
|
|
|
|
current_stage: str | None = None
|
|
|
|
|
|
empty_slots: list[str] = Field(default_factory=list)
|
|
|
|
|
|
covered_stages: list[str] = Field(default_factory=list)
|