|
| 1 | +# Copyright (c) 2025-2026 Huawei Technologies Co., Ltd. All rights reserved. |
| 2 | + |
1 | 3 | import logging |
2 | 4 | from http import HTTPStatus |
3 | 5 | from typing import Annotated, Any, Dict, Optional |
|
7 | 9 |
|
8 | 10 | from consts.model import ( |
9 | 11 | BatchDeleteConversationRequest, |
| 12 | + ConversationModelPreferencePatch, |
10 | 13 | ConversationKnowledgeScopeUpdateRequest, |
11 | 14 | WorkbenchConfigUpdateRequest, |
12 | 15 | ConversationRequest, |
|
18 | 21 | ) |
19 | 22 | from consts.exceptions import ( |
20 | 23 | AppException, |
| 24 | + ModelOutletConflictError, |
| 25 | + ModelOutletValidationError, |
21 | 26 | ConversationNotFoundError, |
22 | 27 | ValidationError, |
23 | 28 | TokenExpiredError, |
@@ -296,6 +301,54 @@ async def update_conversation_workbench_config_endpoint( |
296 | 301 | raise HTTPException(status_code=HTTPStatus.UNPROCESSABLE_ENTITY, detail={"code": "WORKBENCH_CONFIG_INVALID"}) from exc |
297 | 302 |
|
298 | 303 |
|
| 304 | +@router.get("/{conversation_id}/model_preferences", response_model=ConversationResponse) |
| 305 | +async def get_conversation_model_preferences(conversation_id: int, authorization: Optional[str] = Header(None)): |
| 306 | + from nexent.core.concurrency import run_blocking |
| 307 | + from services.conversation_model_preferences_service import read_model_preferences |
| 308 | + |
| 309 | + user_id, _ = get_current_user_id(authorization) |
| 310 | + try: |
| 311 | + result = await run_blocking("conversation-model-preferences-read", read_model_preferences, conversation_id, user_id) |
| 312 | + return ConversationResponse(code=0, message="success", data=result) |
| 313 | + except ConversationNotFoundError: |
| 314 | + raise HTTPException(status_code=404, detail="CONVERSATION_NOT_FOUND") from None |
| 315 | + |
| 316 | + |
| 317 | +@router.get("/{conversation_id}/model_preferences/{model_id}", response_model=ConversationResponse) |
| 318 | +async def get_conversation_model_preference_view(conversation_id: int, model_id: int, authorization: Optional[str] = Header(None)): |
| 319 | + from nexent.core.concurrency import run_blocking |
| 320 | + from services.conversation_model_preferences_service import read_model_preference_view |
| 321 | + |
| 322 | + user_id, tenant_id = get_current_user_id(authorization) |
| 323 | + try: |
| 324 | + result = await run_blocking("conversation-model-preference-view", read_model_preference_view, |
| 325 | + conversation_id, model_id, user_id, tenant_id) |
| 326 | + return ConversationResponse(code=0, message="success", data=result) |
| 327 | + except ConversationNotFoundError: |
| 328 | + raise HTTPException(status_code=404, detail="CONVERSATION_NOT_FOUND") from None |
| 329 | + except ModelOutletValidationError as error: |
| 330 | + raise HTTPException(status_code=422, detail={"code": error.category, "field": error.path}) from None |
| 331 | + |
| 332 | + |
| 333 | +@router.patch("/{conversation_id}/model_preferences/{model_id}", response_model=ConversationResponse) |
| 334 | +async def patch_conversation_model_preferences(conversation_id: int, model_id: int, |
| 335 | + request: ConversationModelPreferencePatch, authorization: Optional[str] = Header(None)): |
| 336 | + from nexent.core.concurrency import run_blocking |
| 337 | + from services.conversation_model_preferences_service import patch_model_preferences |
| 338 | + |
| 339 | + user_id, tenant_id = get_current_user_id(authorization) |
| 340 | + try: |
| 341 | + result = await run_blocking("conversation-model-preferences-update", patch_model_preferences, |
| 342 | + conversation_id, model_id, request, user_id, tenant_id) |
| 343 | + return ConversationResponse(code=0, message="success", data=result) |
| 344 | + except ConversationNotFoundError: |
| 345 | + raise HTTPException(status_code=404, detail="CONVERSATION_NOT_FOUND") from None |
| 346 | + except ModelOutletConflictError: |
| 347 | + raise HTTPException(status_code=409, detail={"code": "MODEL_PREFERENCE_VERSION_CONFLICT"}) from None |
| 348 | + except ModelOutletValidationError as error: |
| 349 | + raise HTTPException(status_code=422, detail={"code": error.category, "field": error.path}) from None |
| 350 | + |
| 351 | + |
299 | 352 | @router.post("/sources", response_model=Dict[str, Any]) |
300 | 353 | async def get_sources_endpoint(request: Dict[str, Any], authorization: Optional[str] = Header(None)): |
301 | 354 | """ |
|
0 commit comments