feat(api): Support specifying app version for chat

This commit is contained in:
wxy
2026-04-10 12:10:24 +08:00
parent 412183c359
commit c253968aa8
3 changed files with 50 additions and 36 deletions

View File

@@ -14,6 +14,7 @@ from app.core.response_utils import success
from app.db import get_db
from app.models.app_model import App
from app.models.app_model import AppType
from app.models.app_release_model import AppRelease
from app.repositories import knowledge_repository
from app.repositories.end_user_repository import EndUserRepository
from app.schemas import AppChatRequest, conversation_schema
@@ -61,18 +62,11 @@ async def list_apps():
# return success(data={"received": True}, msg="消息已接收")
def _checkAppConfig(app: App):
if app.type == AppType.AGENT:
if not app.current_release.config:
raise BusinessException("Agent 应用未配置模型", BizCode.AGENT_CONFIG_MISSING)
elif app.type == AppType.MULTI_AGENT:
if not app.current_release.config:
raise BusinessException("Multi-Agent 应用未配置模型", BizCode.AGENT_CONFIG_MISSING)
elif app.type == AppType.WORKFLOW:
if not app.current_release.config:
raise BusinessException("工作流应用未配置模型", BizCode.AGENT_CONFIG_MISSING)
else:
raise BusinessException("不支持的应用类型", BizCode.AGENT_CONFIG_MISSING)
def _checkAppConfig(release: AppRelease):
if not release.config:
raise BusinessException("应用未配置,无法使用", BizCode.AGENT_CONFIG_MISSING)
if release.type not in (AppType.AGENT, AppType.MULTI_AGENT, AppType.WORKFLOW):
raise BusinessException("不支持的应用类型", BizCode.APP_TYPE_NOT_SUPPORTED)
@router.post("/chat")
@@ -97,25 +91,11 @@ async def chat(
app = app_service.get_app(api_key_auth.resource_id, api_key_auth.workspace_id)
# 版本切换:指定 version 时查找对应历史快照
# 版本切换:指定 version 时查找对应历史快照,否则使用当前激活版本
if payload.version is not None:
from sqlalchemy import select as _select
from app.models.app_release_model import AppRelease as _AppRelease
release = db.scalars(
_select(_AppRelease).where(
_AppRelease.app_id == app.id,
_AppRelease.version == payload.version,
_AppRelease.is_active.is_(True),
)
).first()
if not release:
raise BusinessException(
f"版本 {payload.version} 不存在或已下线",
BizCode.RELEASE_NOT_FOUND,
)
# 临时替换 current_release后续逻辑无需改动
app.current_release = release
app.current_release_id = release.id
active_release = app_service.get_release_by_version(app.id, payload.version)
else:
active_release = app.current_release
other_id = payload.user_id
workspace_id = api_key_auth.workspace_id
end_user_repo = EndUserRepository(db)
@@ -153,7 +133,7 @@ async def chat(
storage_type = 'neo4j'
app_type = app.type
# check app config
_checkAppConfig(app)
_checkAppConfig(active_release)
# 获取或创建会话(提前验证)
conversation = conversation_service.create_or_get_conversation(
@@ -168,7 +148,7 @@ async def chat(
# print("="*50)
# print(app.current_release.default_model_config_id)
agent_config = agent_config_4_app_release(app.current_release)
agent_config = agent_config_4_app_release(active_release)
# print(agent_config.default_model_config_id)
# thinking 开关:仅当 agent 配置了 deep_thinking 且请求 thinking=True 时才启用
@@ -220,7 +200,7 @@ async def chat(
return success(data=conversation_schema.ChatResponse(**result).model_dump(mode="json"))
elif app_type == AppType.MULTI_AGENT:
# 多 Agent 流式返回
config = multi_agent_config_4_app_release(app.current_release)
config = multi_agent_config_4_app_release(active_release)
if payload.stream:
async def event_generator():
async for event in app_chat_service.multi_agent_chat_stream(
@@ -263,7 +243,7 @@ async def chat(
return success(data=conversation_schema.ChatResponse(**result).model_dump(mode="json"))
elif app_type == AppType.WORKFLOW:
# 多 Agent 流式返回
config = workflow_config_4_app_release(app.current_release)
config = workflow_config_4_app_release(active_release)
if payload.stream:
async def event_generator():
async for event in app_chat_service.workflow_chat_stream(
@@ -279,7 +259,7 @@ async def chat(
user_rag_memory_id=user_rag_memory_id,
app_id=app.id,
workspace_id=workspace_id,
release_id=app.current_release.id,
release_id=active_release.id,
public=True
):
event_type = event.get("event", "message")
@@ -314,7 +294,7 @@ async def chat(
files=payload.files,
app_id=app.id,
workspace_id=workspace_id,
release_id=app.current_release.id
release_id=active_release.id
)
logger.debug(
"工作流试运行返回结果",

View File

@@ -61,3 +61,15 @@ def get_apps_by_id(db: Session, app_id: uuid.UUID) -> App:
"""根据工作空间ID查询应用"""
repo = AppRepository(db)
return repo.get_apps_by_id(app_id)
def get_release_by_version(db: Session, app_id: uuid.UUID, version: int):
"""根据版本号查询发布快照(仅返回激活状态)"""
from app.models.app_release_model import AppRelease
return db.scalars(
select(AppRelease).where(
AppRelease.app_id == app_id,
AppRelease.version == version,
AppRelease.is_active.is_(True),
)
).first()

View File

@@ -619,6 +619,28 @@ class AppService:
self._validate_app_accessible(app, workspace_id)
return app
def get_release_by_version(self, app_id: uuid.UUID, version: int) -> AppRelease:
"""按版本号获取发布快照
Args:
app_id: 应用ID
version: 版本号(整数,按应用内递增)
Returns:
AppRelease: 发布快照
Raises:
BusinessException: 版本不存在或已下线
"""
from app.repositories.app_repository import get_release_by_version
release = get_release_by_version(self.db, app_id, version)
if not release:
raise BusinessException(
f"版本 {version} 不存在或已下线",
BizCode.RELEASE_NOT_FOUND,
)
return release
def create_app(
self,
*,