44from typing import Any
55
66from fastapi import APIRouter , Depends , HTTPException , Request , status
7- from llama_stack_client import APIConnectionError , NotFoundError
7+ from llama_stack_client import APIConnectionError , NOT_GIVEN , NotFoundError
88
99from app .database import get_session
1010from authentication import get_auth_dependency
1515from models .database .conversations import UserConversation
1616from models .requests import ConversationUpdateRequest
1717from models .responses import (
18- AccessDeniedResponse ,
1918 BadRequestResponse ,
2019 ConversationDeleteResponse ,
2120 ConversationDetails ,
2221 ConversationResponse ,
2322 ConversationsListResponse ,
2423 ConversationUpdateResponse ,
24+ ForbiddenResponse ,
2525 NotFoundResponse ,
2626 ServiceUnavailableResponse ,
2727 UnauthorizedResponse ,
5555 "description" : "Unauthorized: Invalid or missing Bearer token" ,
5656 },
5757 403 : {
58- "model" : AccessDeniedResponse ,
58+ "model" : ForbiddenResponse ,
5959 "description" : "Client does not have permission to access conversation" ,
6060 },
6161 404 : {
8282 "description" : "Unauthorized: Invalid or missing Bearer token" ,
8383 },
8484 403 : {
85- "model" : AccessDeniedResponse ,
85+ "model" : ForbiddenResponse ,
8686 "description" : "Client does not have permission to access conversation" ,
8787 },
8888 404 : {
124124 "description" : "Unauthorized: Invalid or missing Bearer token" ,
125125 },
126126 403 : {
127- "model" : AccessDeniedResponse ,
127+ "model" : ForbiddenResponse ,
128128 "description" : "Client does not have permission to access conversation" ,
129129 },
130130 404 : {
@@ -283,7 +283,7 @@ async def get_conversation_endpoint_handler(
283283 status_code = status .HTTP_400_BAD_REQUEST ,
284284 detail = BadRequestResponse (
285285 resource = "conversation" , resource_id = conversation_id
286- ).dump_detail (),
286+ ).model_dump (),
287287 )
288288
289289 # Normalize the conversation ID for database operations (strip conv_ prefix if present)
@@ -309,12 +309,11 @@ async def get_conversation_endpoint_handler(
309309 )
310310 raise HTTPException (
311311 status_code = status .HTTP_403_FORBIDDEN ,
312- detail = AccessDeniedResponse (
313- user_id = user_id ,
314- resource = "conversation" ,
315- resource_id = normalized_conv_id ,
312+ detail = ForbiddenResponse .conversation (
316313 action = "read" ,
317- ).dump_detail (),
314+ resource_id = normalized_conv_id ,
315+ user_id = user_id ,
316+ ).model_dump (),
318317 )
319318
320319 # If reached this, user is authorized to retrieve this conversation
@@ -342,8 +341,6 @@ async def get_conversation_endpoint_handler(
342341 )
343342
344343 # Use Conversations API to retrieve conversation items
345- from llama_stack_client import NOT_GIVEN
346-
347344 conversation_items_response = await client .conversations .items .list (
348345 conversation_id = llama_stack_conv_id ,
349346 after = NOT_GIVEN , # No pagination cursor
@@ -384,7 +381,7 @@ async def get_conversation_endpoint_handler(
384381 status_code = status .HTTP_503_SERVICE_UNAVAILABLE ,
385382 detail = ServiceUnavailableResponse (
386383 backend_name = "Llama Stack" , cause = str (e )
387- ).dump_detail (),
384+ ).model_dump (),
388385 ) from e
389386
390387 except NotFoundError as e :
@@ -393,7 +390,7 @@ async def get_conversation_endpoint_handler(
393390 status_code = status .HTTP_404_NOT_FOUND ,
394391 detail = NotFoundResponse (
395392 resource = "conversation" , resource_id = normalized_conv_id
396- ).dump_detail (),
393+ ).model_dump (),
397394 ) from e
398395
399396 except HTTPException :
@@ -402,11 +399,15 @@ async def get_conversation_endpoint_handler(
402399 except Exception as e :
403400 # Handle case where conversation doesn't exist or other errors
404401 logger .exception ("Error retrieving conversation %s: %s" , normalized_conv_id , e )
402+ error_msg = (
403+ f"Unknown error while getting conversation { normalized_conv_id } : "
404+ f"{ str (e )} "
405+ )
405406 raise HTTPException (
406407 status_code = status .HTTP_500_INTERNAL_SERVER_ERROR ,
407408 detail = {
408409 "response" : "Unknown error" ,
409- "cause" : f"Unknown error while getting conversation { normalized_conv_id } : { str ( e ) } " ,
410+ "cause" : error_msg ,
410411 },
411412 ) from e
412413
@@ -444,7 +445,7 @@ async def delete_conversation_endpoint_handler(
444445 status_code = status .HTTP_400_BAD_REQUEST ,
445446 detail = BadRequestResponse (
446447 resource = "conversation" , resource_id = conversation_id
447- ).dump_detail (),
448+ ).model_dump (),
448449 )
449450
450451 # Normalize the conversation ID for database operations (strip conv_ prefix if present)
@@ -465,12 +466,11 @@ async def delete_conversation_endpoint_handler(
465466 )
466467 raise HTTPException (
467468 status_code = status .HTTP_403_FORBIDDEN ,
468- detail = AccessDeniedResponse (
469- user_id = user_id ,
470- resource = "conversation" ,
471- resource_id = normalized_conv_id ,
469+ detail = ForbiddenResponse .conversation (
472470 action = "delete" ,
473- ).dump_detail (),
471+ resource_id = normalized_conv_id ,
472+ user_id = user_id ,
473+ ).model_dump (),
474474 )
475475
476476 # If reached this, user is authorized to delete this conversation
@@ -480,7 +480,7 @@ async def delete_conversation_endpoint_handler(
480480 status_code = status .HTTP_404_NOT_FOUND ,
481481 detail = NotFoundResponse (
482482 resource = "conversation" , resource_id = normalized_conv_id
483- ).dump_detail (),
483+ ).model_dump (),
484484 )
485485
486486 logger .info ("Deleting conversation %s using Conversations API" , normalized_conv_id )
@@ -502,16 +502,15 @@ async def delete_conversation_endpoint_handler(
502502
503503 return ConversationDeleteResponse (
504504 conversation_id = normalized_conv_id ,
505- success = True ,
506- response = "Conversation deleted successfully" ,
505+ deleted = True ,
507506 )
508507
509508 except APIConnectionError as e :
510509 raise HTTPException (
511510 status_code = status .HTTP_503_SERVICE_UNAVAILABLE ,
512511 detail = ServiceUnavailableResponse (
513512 backend_name = "Llama Stack" , cause = str (e )
514- ).dump_detail (),
513+ ).model_dump (),
515514 ) from e
516515
517516 except NotFoundError :
@@ -524,8 +523,7 @@ async def delete_conversation_endpoint_handler(
524523
525524 return ConversationDeleteResponse (
526525 conversation_id = normalized_conv_id ,
527- success = True ,
528- response = "Conversation deleted successfully" ,
526+ deleted = True ,
529527 )
530528
531529 except HTTPException :
@@ -534,11 +532,15 @@ async def delete_conversation_endpoint_handler(
534532 except Exception as e :
535533 # Handle case where conversation doesn't exist or other errors
536534 logger .exception ("Error deleting conversation %s: %s" , normalized_conv_id , e )
535+ error_msg = (
536+ f"Unknown error while deleting conversation { normalized_conv_id } : "
537+ f"{ str (e )} "
538+ )
537539 raise HTTPException (
538540 status_code = status .HTTP_500_INTERNAL_SERVER_ERROR ,
539541 detail = {
540542 "response" : "Unknown error" ,
541- "cause" : f"Unknown error while deleting conversation { normalized_conv_id } : { str ( e ) } " ,
543+ "cause" : error_msg ,
542544 },
543545 ) from e
544546
@@ -574,7 +576,7 @@ async def update_conversation_endpoint_handler(
574576 status_code = status .HTTP_400_BAD_REQUEST ,
575577 detail = BadRequestResponse (
576578 resource = "conversation" , resource_id = conversation_id
577- ).dump_detail (),
579+ ).model_dump (),
578580 )
579581
580582 # Normalize the conversation ID for database operations (strip conv_ prefix if present)
@@ -595,12 +597,11 @@ async def update_conversation_endpoint_handler(
595597 )
596598 raise HTTPException (
597599 status_code = status .HTTP_403_FORBIDDEN ,
598- detail = AccessDeniedResponse (
599- user_id = user_id ,
600- resource = "conversation" ,
601- resource_id = normalized_conv_id ,
600+ detail = ForbiddenResponse .conversation (
602601 action = "update" ,
603- ).dump_detail (),
602+ resource_id = normalized_conv_id ,
603+ user_id = user_id ,
604+ ).model_dump (),
604605 )
605606
606607 # If reached this, user is authorized to update this conversation
@@ -610,7 +611,7 @@ async def update_conversation_endpoint_handler(
610611 status_code = status .HTTP_404_NOT_FOUND ,
611612 detail = NotFoundResponse (
612613 resource = "conversation" , resource_id = normalized_conv_id
613- ).dump_detail (),
614+ ).model_dump (),
614615 )
615616
616617 logger .info (
@@ -629,7 +630,7 @@ async def update_conversation_endpoint_handler(
629630 metadata = {"topic_summary" : update_request .topic_summary }
630631
631632 # Use Conversations API to update the conversation metadata
632- await client .conversations .update_conversation (
633+ await client .conversations .update (
633634 conversation_id = llama_stack_conv_id ,
634635 metadata = metadata ,
635636 )
@@ -663,15 +664,15 @@ async def update_conversation_endpoint_handler(
663664 status_code = status .HTTP_503_SERVICE_UNAVAILABLE ,
664665 detail = ServiceUnavailableResponse (
665666 backend_name = "Llama Stack" , cause = str (e )
666- ).dump_detail (),
667+ ).model_dump (),
667668 ) from e
668669
669670 except NotFoundError as e :
670671 raise HTTPException (
671672 status_code = status .HTTP_404_NOT_FOUND ,
672673 detail = NotFoundResponse (
673674 resource = "conversation" , resource_id = normalized_conv_id
674- ).dump_detail (),
675+ ).model_dump (),
675676 ) from e
676677
677678 except HTTPException :
@@ -680,10 +681,14 @@ async def update_conversation_endpoint_handler(
680681 except Exception as e :
681682 # Handle case where conversation doesn't exist or other errors
682683 logger .exception ("Error updating conversation %s: %s" , normalized_conv_id , e )
684+ error_msg = (
685+ f"Unknown error while updating conversation { normalized_conv_id } : "
686+ f"{ str (e )} "
687+ )
683688 raise HTTPException (
684689 status_code = status .HTTP_500_INTERNAL_SERVER_ERROR ,
685690 detail = {
686691 "response" : "Unknown error" ,
687- "cause" : f"Unknown error while updating conversation { normalized_conv_id } : { str ( e ) } " ,
692+ "cause" : error_msg ,
688693 },
689694 ) from e
0 commit comments