feat(persona): add folder_id and sort_order params to persona creation
Extend persona creation flow to support folder placement and ordering: - Add folder_id and sort_order parameters to insert_persona in db layer - Update PersonaManager.create_persona to accept and pass folder params - Add get_folder_detail API endpoint for retrieving folder information - Include folder_id and sort_order in persona creation response - Add session flush/refresh to return complete persona object
This commit is contained in:
@@ -252,8 +252,19 @@ class BaseDatabase(abc.ABC):
|
||||
system_prompt: str,
|
||||
begin_dialogs: list[str] | None = None,
|
||||
tools: list[str] | None = None,
|
||||
folder_id: str | None = None,
|
||||
sort_order: int = 0,
|
||||
) -> Persona:
|
||||
"""Insert a new persona record."""
|
||||
"""Insert a new persona record.
|
||||
|
||||
Args:
|
||||
persona_id: Unique identifier for the persona
|
||||
system_prompt: System prompt for the persona
|
||||
begin_dialogs: Optional list of initial dialog strings
|
||||
tools: Optional list of tool names (None means all tools, [] means no tools)
|
||||
folder_id: Optional folder ID to place the persona in (None means root)
|
||||
sort_order: Sort order within the folder (default 0)
|
||||
"""
|
||||
...
|
||||
|
||||
@abc.abstractmethod
|
||||
|
||||
@@ -560,6 +560,8 @@ class SQLiteDatabase(BaseDatabase):
|
||||
system_prompt,
|
||||
begin_dialogs=None,
|
||||
tools=None,
|
||||
folder_id=None,
|
||||
sort_order=0,
|
||||
):
|
||||
"""Insert a new persona record."""
|
||||
async with self.get_db() as session:
|
||||
@@ -570,8 +572,12 @@ class SQLiteDatabase(BaseDatabase):
|
||||
system_prompt=system_prompt,
|
||||
begin_dialogs=begin_dialogs or [],
|
||||
tools=tools,
|
||||
folder_id=folder_id,
|
||||
sort_order=sort_order,
|
||||
)
|
||||
session.add(new_persona)
|
||||
await session.flush()
|
||||
await session.refresh(new_persona)
|
||||
return new_persona
|
||||
|
||||
async def get_persona_by_id(self, persona_id):
|
||||
|
||||
@@ -239,8 +239,19 @@ class PersonaManager:
|
||||
system_prompt: str,
|
||||
begin_dialogs: list[str] | None = None,
|
||||
tools: list[str] | None = None,
|
||||
folder_id: str | None = None,
|
||||
sort_order: int = 0,
|
||||
) -> Persona:
|
||||
"""创建新的 persona。tools 参数为 None 时表示使用所有工具,空列表表示不使用任何工具"""
|
||||
"""创建新的 persona。
|
||||
|
||||
Args:
|
||||
persona_id: Persona 唯一标识
|
||||
system_prompt: 系统提示词
|
||||
begin_dialogs: 预设对话列表
|
||||
tools: 工具列表,None 表示使用所有工具,空列表表示不使用任何工具
|
||||
folder_id: 所属文件夹 ID,None 表示根目录
|
||||
sort_order: 排序顺序
|
||||
"""
|
||||
if await self.db.get_persona_by_id(persona_id):
|
||||
raise ValueError(f"Persona with ID {persona_id} already exists.")
|
||||
new_persona = await self.db.insert_persona(
|
||||
@@ -248,6 +259,8 @@ class PersonaManager:
|
||||
system_prompt,
|
||||
begin_dialogs,
|
||||
tools=tools,
|
||||
folder_id=folder_id,
|
||||
sort_order=sort_order,
|
||||
)
|
||||
self.personas.append(new_persona)
|
||||
self.get_v3_persona_data()
|
||||
|
||||
@@ -28,6 +28,7 @@ class PersonaRoute(Route):
|
||||
# Folder routes
|
||||
"/persona/folder/list": ("GET", self.list_folders),
|
||||
"/persona/folder/tree": ("GET", self.get_folder_tree),
|
||||
"/persona/folder/detail": ("POST", self.get_folder_detail),
|
||||
"/persona/folder/create": ("POST", self.create_folder),
|
||||
"/persona/folder/update": ("POST", self.update_folder),
|
||||
"/persona/folder/delete": ("POST", self.delete_folder),
|
||||
@@ -119,6 +120,8 @@ class PersonaRoute(Route):
|
||||
system_prompt = data.get("system_prompt", "").strip()
|
||||
begin_dialogs = data.get("begin_dialogs", [])
|
||||
tools = data.get("tools")
|
||||
folder_id = data.get("folder_id") # None 表示根目录
|
||||
sort_order = data.get("sort_order", 0)
|
||||
|
||||
if not persona_id:
|
||||
return Response().error("人格ID不能为空").__dict__
|
||||
@@ -139,6 +142,8 @@ class PersonaRoute(Route):
|
||||
system_prompt=system_prompt,
|
||||
begin_dialogs=begin_dialogs if begin_dialogs else None,
|
||||
tools=tools if tools else None,
|
||||
folder_id=folder_id,
|
||||
sort_order=sort_order,
|
||||
)
|
||||
|
||||
return (
|
||||
@@ -151,6 +156,8 @@ class PersonaRoute(Route):
|
||||
"system_prompt": persona.system_prompt,
|
||||
"begin_dialogs": persona.begin_dialogs or [],
|
||||
"tools": persona.tools or [],
|
||||
"folder_id": persona.folder_id,
|
||||
"sort_order": persona.sort_order,
|
||||
"created_at": persona.created_at.isoformat()
|
||||
if persona.created_at
|
||||
else None,
|
||||
@@ -283,6 +290,42 @@ class PersonaRoute(Route):
|
||||
logger.error(f"获取文件夹树失败: {e!s}\n{traceback.format_exc()}")
|
||||
return Response().error(f"获取文件夹树失败: {e!s}").__dict__
|
||||
|
||||
async def get_folder_detail(self):
|
||||
"""获取指定文件夹的详细信息"""
|
||||
try:
|
||||
data = await request.get_json()
|
||||
folder_id = data.get("folder_id")
|
||||
|
||||
if not folder_id:
|
||||
return Response().error("缺少必要参数: folder_id").__dict__
|
||||
|
||||
folder = await self.persona_mgr.get_folder(folder_id)
|
||||
if not folder:
|
||||
return Response().error("文件夹不存在").__dict__
|
||||
|
||||
return (
|
||||
Response()
|
||||
.ok(
|
||||
{
|
||||
"folder_id": folder.folder_id,
|
||||
"name": folder.name,
|
||||
"parent_id": folder.parent_id,
|
||||
"description": folder.description,
|
||||
"sort_order": folder.sort_order,
|
||||
"created_at": folder.created_at.isoformat()
|
||||
if folder.created_at
|
||||
else None,
|
||||
"updated_at": folder.updated_at.isoformat()
|
||||
if folder.updated_at
|
||||
else None,
|
||||
},
|
||||
)
|
||||
.__dict__
|
||||
)
|
||||
except Exception as e:
|
||||
logger.error(f"获取文件夹详情失败: {e!s}\n{traceback.format_exc()}")
|
||||
return Response().error(f"获取文件夹详情失败: {e!s}").__dict__
|
||||
|
||||
async def create_folder(self):
|
||||
"""创建文件夹"""
|
||||
try:
|
||||
|
||||
Reference in New Issue
Block a user