新增文件管理与技能管理功能:
All checks were successful
Deploy Noval to K3s / deploy (push) Successful in 47s

- **文件管理**:
  - 支持文件上传、解析和删除。
  - 限制支持格式(txt, md, docx, pdf),最大 10MB。
  - 提供前端上传区、文件列表及后端解析服务。

- **技能管理**:
  - 新增技能的创建、更新及删除功能。
  - 支持分配自定义提示词和工具权限。
  - 提供技能列表及分组工具选择交互界面。

同时调整相关 API 和前端组件,优化协作体验。
This commit is contained in:
2026-03-22 23:50:14 +08:00
parent 7d5f4640b3
commit b39377e487
21 changed files with 1913 additions and 45 deletions

View File

@@ -1,8 +1,9 @@
import json
import os
from pathlib import Path
from sqlalchemy import text
from sqlmodel import SQLModel, Session, create_engine
from sqlmodel import SQLModel, Session, create_engine, select
# 数据目录优先使用环境变量Docker 中设为 /app/data否则用 backend/data/
DATA_DIR = Path(os.environ.get("NOVAL_DATA_DIR", Path(__file__).resolve().parent.parent / "data"))
@@ -16,6 +17,7 @@ engine = create_engine(DATABASE_URL, echo=False)
def init_db() -> None:
SQLModel.metadata.create_all(engine)
_migrate_outline_parent_id()
_seed_builtin_skills()
def _migrate_outline_parent_id() -> None:
@@ -30,6 +32,57 @@ def _migrate_outline_parent_id() -> None:
session.commit()
def _seed_builtin_skills() -> None:
"""初始化预置 Skill仅首次运行时插入"""
from .models import Skill # 延迟导入避免循环
with Session(engine) as session:
existing = session.exec(select(Skill).where(Skill.is_builtin == True)).first() # noqa: E712
if existing:
return # 已初始化过
builtin_skills = [
Skill(
name="通用写作助手",
description="全能写作助手,可使用所有工具",
system_prompt="你是一个专业的小说写作助手,擅长构思情节、塑造角色、打磨文笔。请根据用户需求提供创作建议,必要时主动使用工具查看和操作小说数据。",
allowed_tools="[]",
is_builtin=True,
),
Skill(
name="大纲规划师",
description="构建清晰的故事骨架,规划情节节点",
system_prompt="你是大纲规划专家。请帮助用户构建清晰的故事骨架,包括起承转合、情节节点和分章结构。分析现有大纲时请关注因果逻辑、节奏控制和悬念布置。在操作大纲时,注意保持节点间的逻辑连贯性。",
allowed_tools=json.dumps(["get_novel_info", "list_outlines", "create_outline", "update_outline", "delete_outline", "reorder_outlines"]),
is_builtin=True,
),
Skill(
name="角色塑造师",
description="设计立体、有深度的角色",
system_prompt="你是角色塑造专家。请帮助用户设计立体、有深度的角色,包括外貌、性格、动机、成长弧线和人物关系。注意角色间的化学反应和戏剧张力,确保每个角色都有独特的声音和行为逻辑。",
allowed_tools=json.dumps(["get_novel_info", "list_characters", "create_character", "update_character", "delete_character"]),
is_builtin=True,
),
Skill(
name="世界观架构师",
description="构建完整自洽的虚构世界",
system_prompt="你是世界观构建专家。请帮助用户设计完整自洽的虚构世界,包括地理、历史、政治、经济、魔法或科技体系等。确保设定内部逻辑一致,并与故事主线相辅相成。",
allowed_tools=json.dumps(["get_novel_info", "get_world_setting", "save_world_setting", "list_outlines", "list_characters"]),
is_builtin=True,
),
Skill(
name="文稿分析师",
description="分析上传的小说或剧本文件",
system_prompt="你是文稿分析专家。请仔细阅读用户上传的文件,提取关键信息,分析文风、角色、情节结构,并提供改进建议。分析时可以分段读取大文件,注意把握整体脉络。",
allowed_tools=json.dumps(["get_novel_info", "list_files", "read_file", "list_outlines", "list_characters", "list_chapters"]),
is_builtin=True,
),
]
for skill in builtin_skills:
session.add(skill)
session.commit()
def get_session():
with Session(engine) as session:
yield session