All checks were successful
Deploy Noval to K3s / deploy (push) Successful in 47s
- **文件管理**: - 支持文件上传、解析和删除。 - 限制支持格式(txt, md, docx, pdf),最大 10MB。 - 提供前端上传区、文件列表及后端解析服务。 - **技能管理**: - 新增技能的创建、更新及删除功能。 - 支持分配自定义提示词和工具权限。 - 提供技能列表及分组工具选择交互界面。 同时调整相关 API 和前端组件,优化协作体验。
112 lines
4.3 KiB
Python
112 lines
4.3 KiB
Python
from datetime import datetime, timezone
|
||
from typing import Optional
|
||
|
||
from sqlmodel import SQLModel, Field
|
||
|
||
|
||
def _now_utc() -> datetime:
|
||
return datetime.now(timezone.utc)
|
||
|
||
|
||
class Novel(SQLModel, table=True):
|
||
"""小说主表"""
|
||
|
||
id: Optional[int] = Field(default=None, primary_key=True)
|
||
title: str = Field(max_length=200, index=True)
|
||
description: str = Field(default="", max_length=2000)
|
||
created_at: datetime = Field(default_factory=_now_utc)
|
||
updated_at: datetime = Field(default_factory=_now_utc)
|
||
|
||
|
||
class AIConfig(SQLModel, table=True):
|
||
"""AI服务配置(单行表)"""
|
||
|
||
id: Optional[int] = Field(default=None, primary_key=True)
|
||
provider: str = Field(default="openai") # "openai" | "anthropic"
|
||
base_url: str = Field(default="https://api.openai.com/v1")
|
||
api_key: str = Field(default="")
|
||
model: str = Field(default="gpt-4o")
|
||
updated_at: datetime = Field(default_factory=_now_utc)
|
||
|
||
|
||
class ChatMessage(SQLModel, table=True):
|
||
"""聊天消息"""
|
||
|
||
id: Optional[int] = Field(default=None, primary_key=True)
|
||
novel_id: Optional[int] = Field(default=None, foreign_key="novel.id", index=True)
|
||
role: str = Field(max_length=20) # "user" | "assistant"
|
||
content: str = Field(default="")
|
||
created_at: datetime = Field(default_factory=_now_utc)
|
||
|
||
class Outline(SQLModel, table=True):
|
||
"""大纲表,属于小说的子资源,支持两级结构(父+子)"""
|
||
|
||
id: Optional[int] = Field(default=None, primary_key=True)
|
||
novel_id: int = Field(foreign_key="novel.id", index=True)
|
||
parent_id: int | None = Field(default=None, foreign_key="outline.id", index=True)
|
||
sort_order: int = Field(default=0)
|
||
summary: str = Field(max_length=200)
|
||
detail: str = Field(default="", max_length=1000)
|
||
created_at: datetime = Field(default_factory=_now_utc)
|
||
updated_at: datetime = Field(default_factory=_now_utc)
|
||
|
||
|
||
class Character(SQLModel, table=True):
|
||
"""角色表,属于小说的子资源"""
|
||
|
||
id: Optional[int] = Field(default=None, primary_key=True)
|
||
novel_id: int = Field(foreign_key="novel.id", index=True)
|
||
name: str = Field(max_length=100)
|
||
description: str = Field(default="", max_length=1000)
|
||
created_at: datetime = Field(default_factory=_now_utc)
|
||
updated_at: datetime = Field(default_factory=_now_utc)
|
||
|
||
|
||
class Chapter(SQLModel, table=True):
|
||
"""章节表,属于小说的子资源"""
|
||
|
||
id: Optional[int] = Field(default=None, primary_key=True)
|
||
novel_id: int = Field(foreign_key="novel.id", index=True)
|
||
sort_order: int = Field(default=0)
|
||
title: str = Field(max_length=200)
|
||
content: str = Field(default="", max_length=5000)
|
||
created_at: datetime = Field(default_factory=_now_utc)
|
||
updated_at: datetime = Field(default_factory=_now_utc)
|
||
|
||
|
||
class NovelFile(SQLModel, table=True):
|
||
"""小说关联文件"""
|
||
|
||
id: Optional[int] = Field(default=None, primary_key=True)
|
||
novel_id: int = Field(foreign_key="novel.id", index=True)
|
||
filename: str = Field(max_length=255) # 原始文件名
|
||
stored_name: str = Field(max_length=255) # 磁盘存储名(uuid + 扩展名)
|
||
file_size: int = Field(default=0) # 字节数
|
||
mime_type: str = Field(default="", max_length=100)
|
||
text_length: int = Field(default=0) # 解析后纯文本字符数
|
||
created_at: datetime = Field(default_factory=_now_utc)
|
||
|
||
|
||
class Skill(SQLModel, table=True):
|
||
"""Skill 插件:自定义系统提示词 + 工具白名单"""
|
||
|
||
id: Optional[int] = Field(default=None, primary_key=True)
|
||
name: str = Field(max_length=100, index=True)
|
||
description: str = Field(default="", max_length=500)
|
||
system_prompt: str = Field(default="")
|
||
allowed_tools: str = Field(default="[]") # JSON 数组字符串,"[]" 表示全部工具
|
||
is_builtin: bool = Field(default=False)
|
||
novel_id: int | None = Field(default=None, foreign_key="novel.id", index=True)
|
||
created_at: datetime = Field(default_factory=_now_utc)
|
||
updated_at: datetime = Field(default_factory=_now_utc)
|
||
|
||
|
||
class WorldSetting(SQLModel, table=True):
|
||
"""世界观设定,每部小说一条记录"""
|
||
|
||
id: Optional[int] = Field(default=None, primary_key=True)
|
||
novel_id: int = Field(foreign_key="novel.id", index=True, unique=True)
|
||
content: str = Field(default="", max_length=5000)
|
||
created_at: datetime = Field(default_factory=_now_utc)
|
||
updated_at: datetime = Field(default_factory=_now_utc)
|