@@ -3,31 +3,74 @@ import type { Context } from "hono"
33import { streamSSE , type SSEMessage } from "hono/streaming"
44
55import type { ChatCompletionsPayload } from "~/services/copilot/chat-completions/types"
6+ import type { ChatCompletionChunk } from "~/services/copilot/chat-completions/types-streaming"
67
78import { logger } from "~/lib/logger"
89import { chatCompletions } from "~/services/copilot/chat-completions/service"
910import { chatCompletionsStream } from "~/services/copilot/chat-completions/service-streaming"
1011
12+ function createCondensedStreamingResponse (
13+ finalChunk : ChatCompletionChunk ,
14+ collectedContent : string ,
15+ ) {
16+ return {
17+ id : finalChunk . id ,
18+ model : finalChunk . model ,
19+ created : finalChunk . created ,
20+ object : "chat.completion" ,
21+ system_fingerprint : finalChunk . system_fingerprint ,
22+ usage : finalChunk . usage ,
23+ choices : [
24+ {
25+ index : 0 ,
26+ finish_reason : finalChunk . choices [ 0 ] . finish_reason ,
27+ message : {
28+ role : "assistant" ,
29+ content : collectedContent ,
30+ } ,
31+ content_filter_results : finalChunk . choices [ 0 ] . content_filter_results ,
32+ } ,
33+ ] ,
34+ }
35+ }
36+
1137export async function handlerStreaming ( c : Context ) {
1238 const payload = await c . req . json < ChatCompletionsPayload > ( )
1339
14- // Log the request
40+ // Log the request at the beginning for both streaming and non-streaming cases
1541 await logger . logRequest ( "/chat/completions" , "POST" , payload )
1642
1743 if ( payload . stream ) {
1844 const response = await chatCompletionsStream ( payload )
1945
20- // For streaming responses, we'll log the initial response setup
21- await logger . logResponse ( "/chat/completions" , {
22- type : "stream" ,
23- timestamp : new Date ( ) . toISOString ( ) ,
24- model : payload . model ,
25- } )
46+ // For collecting the complete streaming response
47+ let collectedContent = ""
48+ let finalChunk : ChatCompletionChunk | null = null
2649
2750 return streamSSE ( c , async ( stream ) => {
2851 for await ( const chunk of response ) {
52+ const data = JSON . parse ( chunk . data ?? "{}" ) as ChatCompletionChunk
53+
54+ // Keep track of the latest chunk for metadata
55+ finalChunk = data
56+
57+ // Accumulate content from each delta
58+ if ( data . choices [ 0 ] . delta . content ) {
59+ collectedContent += data . choices [ 0 ] . delta . content
60+ }
61+
2962 await stream . writeSSE ( chunk as SSEMessage )
3063 }
64+
65+ // After streaming completes, log the condensed response
66+ if ( finalChunk ) {
67+ const condensedResponse = createCondensedStreamingResponse (
68+ finalChunk ,
69+ collectedContent ,
70+ )
71+
72+ await logger . logResponse ( "/chat/completions" , condensedResponse )
73+ }
3174 } )
3275 }
3376
0 commit comments