33
44from fastapi import APIRouter , BackgroundTasks , HTTPException , status
55from fastapi .responses import StreamingResponse
6+ from loguru import logger
67
7- from app .api .dependencies import Agent , AsyncDB , FeedbackSender , UserID
8+ from app .api .dependencies import Agent , AsyncDB , FeedbackSender , RunningRuns , UserID
89from app .api .schemas import ConfigDict , UserMessage
9- from app .api .streaming import stream_response
10+ from app .api .streaming import run_agent , stream_events
11+ from app .api .streaming .schemas import StreamEvent
1012from app .db .models import (
1113 FeedbackCreate ,
1214 FeedbackPayload ,
@@ -96,14 +98,19 @@ async def list_messages(
9698 return await database .get_messages (thread .id , order_by )
9799
98100
99- @router .post ("/threads/{thread_id}/messages" )
101+ @router .post (
102+ "/threads/{thread_id}/messages" ,
103+ response_class = StreamingResponse ,
104+ status_code = status .HTTP_201_CREATED ,
105+ )
100106async def send_message (
101107 thread_id : str ,
102108 user_message : UserMessage ,
103- agent : Agent ,
104109 database : AsyncDB ,
110+ agent : Agent ,
111+ running_runs : RunningRuns ,
105112 user_id : UserID ,
106- ) -> Message :
113+ ) -> StreamingResponse :
107114 run_id = str (uuid .uuid4 ())
108115
109116 config = ConfigDict (
@@ -120,15 +127,35 @@ async def send_message(
120127
121128 message = await database .create_message (message_create )
122129
123- return StreamingResponse (
124- stream_response (
125- database = database ,
130+ queue : asyncio .Queue [StreamEvent ] = asyncio .Queue ()
131+
132+ task = asyncio .create_task (
133+ run_agent (
126134 agent = agent ,
127- user_message = message ,
128135 config = config ,
129136 thread_id = thread_id ,
137+ user_message = message ,
130138 model_uri = settings .MODEL_URI ,
139+ queue = queue ,
131140 ),
141+ name = f"run_agent:{ run_id } " ,
142+ )
143+
144+ running_runs [run_id ] = task
145+
146+ def _cleanup (task : asyncio .Task ): # pragma: no cover
147+ del running_runs [run_id ]
148+ if task .cancelled ():
149+ logger .warning (f"run_agent task { run_id } was cancelled mid-run" )
150+ return
151+ e = task .exception ()
152+ if e is not None :
153+ logger .opt (exception = e ).error (f"run_agent task { run_id } crashed mid-run:" )
154+
155+ task .add_done_callback (_cleanup )
156+
157+ return StreamingResponse (
158+ stream_events (queue ),
132159 status_code = status .HTTP_201_CREATED ,
133160 )
134161
0 commit comments