fix(multimodal): temporarily limit API to image-only modality
This commit is contained in:
@@ -580,6 +580,7 @@ async def chat(
|
|||||||
conversation_id=conversation.id, # 使用已创建的会话 ID
|
conversation_id=conversation.id, # 使用已创建的会话 ID
|
||||||
user_id=end_user_id, # 转换为字符串
|
user_id=end_user_id, # 转换为字符串
|
||||||
variables=payload.variables,
|
variables=payload.variables,
|
||||||
|
files=payload.files,
|
||||||
config=config,
|
config=config,
|
||||||
web_search=payload.web_search,
|
web_search=payload.web_search,
|
||||||
memory=payload.memory,
|
memory=payload.memory,
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ from app.core.exceptions import BusinessException
|
|||||||
from app.core.logging_config import get_business_logger
|
from app.core.logging_config import get_business_logger
|
||||||
from app.core.response_utils import success
|
from app.core.response_utils import success
|
||||||
from app.db import get_db
|
from app.db import get_db
|
||||||
from app.dependencies import get_app_or_workspace
|
|
||||||
from app.models.app_model import App
|
from app.models.app_model import App
|
||||||
from app.models.app_model import AppType
|
from app.models.app_model import AppType
|
||||||
from app.repositories import knowledge_repository
|
from app.repositories import knowledge_repository
|
||||||
@@ -21,9 +20,10 @@ from app.schemas import AppChatRequest, conversation_schema
|
|||||||
from app.schemas.api_key_schema import ApiKeyAuth
|
from app.schemas.api_key_schema import ApiKeyAuth
|
||||||
from app.services import workspace_service
|
from app.services import workspace_service
|
||||||
from app.services.app_chat_service import AppChatService, get_app_chat_service
|
from app.services.app_chat_service import AppChatService, get_app_chat_service
|
||||||
from app.services.conversation_service import ConversationService, get_conversation_service
|
|
||||||
from app.utils.app_config_utils import dict_to_multi_agent_config, workflow_config_4_app_release, agent_config_4_app_release, multi_agent_config_4_app_release
|
|
||||||
from app.services.app_service import get_app_service, AppService
|
from app.services.app_service import get_app_service, AppService
|
||||||
|
from app.services.conversation_service import ConversationService, get_conversation_service
|
||||||
|
from app.utils.app_config_utils import workflow_config_4_app_release, \
|
||||||
|
agent_config_4_app_release, multi_agent_config_4_app_release
|
||||||
|
|
||||||
router = APIRouter(prefix="/app", tags=["V1 - App API"])
|
router = APIRouter(prefix="/app", tags=["V1 - App API"])
|
||||||
logger = get_business_logger()
|
logger = get_business_logger()
|
||||||
@@ -34,6 +34,7 @@ async def list_apps():
|
|||||||
"""列出可访问的应用(占位)"""
|
"""列出可访问的应用(占位)"""
|
||||||
return success(data=[], msg="App API - Coming Soon")
|
return success(data=[], msg="App API - Coming Soon")
|
||||||
|
|
||||||
|
|
||||||
# /v1/app/chat
|
# /v1/app/chat
|
||||||
|
|
||||||
# @router.post("/chat")
|
# @router.post("/chat")
|
||||||
@@ -73,16 +74,17 @@ def _checkAppConfig(app: App):
|
|||||||
else:
|
else:
|
||||||
raise BusinessException("不支持的应用类型", BizCode.AGENT_CONFIG_MISSING)
|
raise BusinessException("不支持的应用类型", BizCode.AGENT_CONFIG_MISSING)
|
||||||
|
|
||||||
|
|
||||||
@router.post("/chat")
|
@router.post("/chat")
|
||||||
@require_api_key(scopes=["app"])
|
@require_api_key(scopes=["app"])
|
||||||
async def chat(
|
async def chat(
|
||||||
request:Request,
|
request: Request,
|
||||||
api_key_auth: ApiKeyAuth = None,
|
api_key_auth: ApiKeyAuth = None,
|
||||||
db: Session = Depends(get_db),
|
db: Session = Depends(get_db),
|
||||||
conversation_service: Annotated[ConversationService, Depends(get_conversation_service)] = None,
|
conversation_service: Annotated[ConversationService, Depends(get_conversation_service)] = None,
|
||||||
app_chat_service: Annotated[AppChatService, Depends(get_app_chat_service)] = None,
|
app_chat_service: Annotated[AppChatService, Depends(get_app_chat_service)] = None,
|
||||||
app_service: Annotated[AppService, Depends(get_app_service)] = None,
|
app_service: Annotated[AppService, Depends(get_app_service)] = None,
|
||||||
message: str = Body(..., description="聊天消息内容"),
|
message: str = Body(..., description="聊天消息内容"),
|
||||||
):
|
):
|
||||||
body = await request.json()
|
body = await request.json()
|
||||||
payload = AppChatRequest(**body)
|
payload = AppChatRequest(**body)
|
||||||
@@ -98,8 +100,8 @@ async def chat(
|
|||||||
original_user_id=other_id # Save original user_id to other_id
|
original_user_id=other_id # Save original user_id to other_id
|
||||||
)
|
)
|
||||||
end_user_id = str(new_end_user.id)
|
end_user_id = str(new_end_user.id)
|
||||||
web_search=True
|
web_search = True
|
||||||
memory=True
|
memory = True
|
||||||
# 提前验证和准备(在流式响应开始前完成)
|
# 提前验证和准备(在流式响应开始前完成)
|
||||||
storage_type = workspace_service.get_workspace_storage_type_without_auth(
|
storage_type = workspace_service.get_workspace_storage_type_without_auth(
|
||||||
db=db,
|
db=db,
|
||||||
@@ -146,17 +148,17 @@ async def chat(
|
|||||||
if payload.stream:
|
if payload.stream:
|
||||||
async def event_generator():
|
async def event_generator():
|
||||||
async for event in app_chat_service.agnet_chat_stream(
|
async for event in app_chat_service.agnet_chat_stream(
|
||||||
message=payload.message,
|
message=payload.message,
|
||||||
conversation_id=conversation.id, # 使用已创建的会话 ID
|
conversation_id=conversation.id, # 使用已创建的会话 ID
|
||||||
user_id= end_user_id, # 转换为字符串
|
user_id=end_user_id, # 转换为字符串
|
||||||
variables=payload.variables,
|
variables=payload.variables,
|
||||||
web_search=web_search,
|
web_search=web_search,
|
||||||
config=agent_config,
|
config=agent_config,
|
||||||
memory=memory,
|
memory=memory,
|
||||||
storage_type=storage_type,
|
storage_type=storage_type,
|
||||||
user_rag_memory_id=user_rag_memory_id,
|
user_rag_memory_id=user_rag_memory_id,
|
||||||
workspace_id=workspace_id,
|
workspace_id=workspace_id,
|
||||||
files=payload.files # 传递多模态文件
|
files=payload.files # 传递多模态文件
|
||||||
):
|
):
|
||||||
yield event
|
yield event
|
||||||
|
|
||||||
@@ -176,7 +178,7 @@ async def chat(
|
|||||||
conversation_id=conversation.id, # 使用已创建的会话 ID
|
conversation_id=conversation.id, # 使用已创建的会话 ID
|
||||||
user_id=end_user_id, # 转换为字符串
|
user_id=end_user_id, # 转换为字符串
|
||||||
variables=payload.variables,
|
variables=payload.variables,
|
||||||
config= agent_config,
|
config=agent_config,
|
||||||
web_search=web_search,
|
web_search=web_search,
|
||||||
memory=memory,
|
memory=memory,
|
||||||
storage_type=storage_type,
|
storage_type=storage_type,
|
||||||
@@ -192,15 +194,15 @@ async def chat(
|
|||||||
async def event_generator():
|
async def event_generator():
|
||||||
async for event in app_chat_service.multi_agent_chat_stream(
|
async for event in app_chat_service.multi_agent_chat_stream(
|
||||||
|
|
||||||
message=payload.message,
|
message=payload.message,
|
||||||
conversation_id=conversation.id, # 使用已创建的会话 ID
|
conversation_id=conversation.id, # 使用已创建的会话 ID
|
||||||
user_id=end_user_id, # 转换为字符串
|
user_id=end_user_id, # 转换为字符串
|
||||||
variables=payload.variables,
|
variables=payload.variables,
|
||||||
config=config,
|
config=config,
|
||||||
web_search=web_search,
|
web_search=web_search,
|
||||||
memory=memory,
|
memory=memory,
|
||||||
storage_type=storage_type,
|
storage_type=storage_type,
|
||||||
user_rag_memory_id=user_rag_memory_id
|
user_rag_memory_id=user_rag_memory_id
|
||||||
):
|
):
|
||||||
yield event
|
yield event
|
||||||
|
|
||||||
@@ -234,19 +236,19 @@ async def chat(
|
|||||||
if payload.stream:
|
if payload.stream:
|
||||||
async def event_generator():
|
async def event_generator():
|
||||||
async for event in app_chat_service.workflow_chat_stream(
|
async for event in app_chat_service.workflow_chat_stream(
|
||||||
|
message=payload.message,
|
||||||
message=payload.message,
|
conversation_id=conversation.id, # 使用已创建的会话 ID
|
||||||
conversation_id=conversation.id, # 使用已创建的会话 ID
|
user_id=end_user_id, # 转换为字符串
|
||||||
user_id=end_user_id, # 转换为字符串
|
variables=payload.variables,
|
||||||
variables=payload.variables,
|
files=payload.files,
|
||||||
config=config,
|
config=config,
|
||||||
web_search=web_search,
|
web_search=web_search,
|
||||||
memory=memory,
|
memory=memory,
|
||||||
storage_type=storage_type,
|
storage_type=storage_type,
|
||||||
user_rag_memory_id=user_rag_memory_id,
|
user_rag_memory_id=user_rag_memory_id,
|
||||||
app_id=app.id,
|
app_id=app.id,
|
||||||
workspace_id=workspace_id,
|
workspace_id=workspace_id,
|
||||||
release_id=app.current_release.id,
|
release_id=app.current_release.id,
|
||||||
):
|
):
|
||||||
event_type = event.get("event", "message")
|
event_type = event.get("event", "message")
|
||||||
event_data = event.get("data", {})
|
event_data = event.get("data", {})
|
||||||
@@ -296,4 +298,3 @@ async def chat(
|
|||||||
from app.core.exceptions import BusinessException
|
from app.core.exceptions import BusinessException
|
||||||
from app.core.error_codes import BizCode
|
from app.core.error_codes import BizCode
|
||||||
raise BusinessException(f"不支持的应用类型: {app_type}", BizCode.APP_TYPE_NOT_SUPPORTED)
|
raise BusinessException(f"不支持的应用类型: {app_type}", BizCode.APP_TYPE_NOT_SUPPORTED)
|
||||||
|
|
||||||
|
|||||||
@@ -15,6 +15,13 @@ class FileType(StrEnum):
|
|||||||
AUDIO = "audio"
|
AUDIO = "audio"
|
||||||
VIDEO = "video"
|
VIDEO = "video"
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def trans(cls, value: str) -> 'FileType':
|
||||||
|
if value.startswith("image"):
|
||||||
|
return cls.IMAGE
|
||||||
|
# TODO: other file type support
|
||||||
|
raise RuntimeError("Unsupport file type")
|
||||||
|
|
||||||
|
|
||||||
class TransferMethod(str, Enum):
|
class TransferMethod(str, Enum):
|
||||||
"""文件传输方式枚举"""
|
"""文件传输方式枚举"""
|
||||||
@@ -29,6 +36,15 @@ class FileInput(BaseModel):
|
|||||||
upload_file_id: Optional[uuid.UUID] = Field(None, description="已上传文件ID(local_file时必填)")
|
upload_file_id: Optional[uuid.UUID] = Field(None, description="已上传文件ID(local_file时必填)")
|
||||||
url: Optional[str] = Field(None, description="远程URL(remote_url时必填)")
|
url: Optional[str] = Field(None, description="远程URL(remote_url时必填)")
|
||||||
|
|
||||||
|
@field_validator("type", mode="before")
|
||||||
|
@classmethod
|
||||||
|
def validate_type(cls, v):
|
||||||
|
"""验证文件类型"""
|
||||||
|
try:
|
||||||
|
return FileType.trans(v)
|
||||||
|
except ValueError:
|
||||||
|
raise ValueError(f"无效的文件类型: {v}")
|
||||||
|
|
||||||
@field_validator("upload_file_id")
|
@field_validator("upload_file_id")
|
||||||
@classmethod
|
@classmethod
|
||||||
def validate_local_file(cls, v, info):
|
def validate_local_file(cls, v, info):
|
||||||
@@ -82,6 +98,7 @@ class ToolConfig(BaseModel):
|
|||||||
tool_id: Optional[str] = Field(default=None, description="工具ID")
|
tool_id: Optional[str] = Field(default=None, description="工具ID")
|
||||||
operation: Optional[str] = Field(default=None, description="工具特定配置")
|
operation: Optional[str] = Field(default=None, description="工具特定配置")
|
||||||
|
|
||||||
|
|
||||||
class SkillConfig(BaseModel):
|
class SkillConfig(BaseModel):
|
||||||
"""技能配置"""
|
"""技能配置"""
|
||||||
enabled: bool = Field(default=True, description="是否启用该技能")
|
enabled: bool = Field(default=True, description="是否启用该技能")
|
||||||
|
|||||||
@@ -655,6 +655,7 @@ class AppChatService:
|
|||||||
workspace_id: uuid.UUID,
|
workspace_id: uuid.UUID,
|
||||||
user_id: str = None,
|
user_id: str = None,
|
||||||
variables: Optional[Dict[str, Any]] = None,
|
variables: Optional[Dict[str, Any]] = None,
|
||||||
|
files: Optional[List[FileInput]] = None,
|
||||||
web_search: bool = False,
|
web_search: bool = False,
|
||||||
memory: bool = True,
|
memory: bool = True,
|
||||||
storage_type: Optional[str] = None,
|
storage_type: Optional[str] = None,
|
||||||
@@ -669,7 +670,8 @@ class AppChatService:
|
|||||||
variables=variables,
|
variables=variables,
|
||||||
conversation_id=str(conversation_id),
|
conversation_id=str(conversation_id),
|
||||||
stream=True,
|
stream=True,
|
||||||
user_id=user_id
|
user_id=user_id,
|
||||||
|
files=files
|
||||||
)
|
)
|
||||||
async for event in workflow_service.run_stream(
|
async for event in workflow_service.run_stream(
|
||||||
app_id=app_id,
|
app_id=app_id,
|
||||||
|
|||||||
Reference in New Issue
Block a user