@@ -4,6 +4,14 @@ import (
44 "github.com/openai/openai-go/v3"
55)
66
7+ const (
8+ keyOutputIndex = "output_index"
9+ keyContentIndex = "content_index"
10+ keyType = "type"
11+ keyItem = "item"
12+ keyRefusal = "refusal"
13+ )
14+
715// Handler processes streaming chat completion chunks and converts them into
816// structured stream events. It maintains state across chunks to reconstruct
917// complete messages, function calls, and reasoning content.
@@ -154,9 +162,9 @@ func (h *Handler) processTextContent(content string) []Event {
154162 events = append (events , & RawResponseEvent {
155163 Type : "response.output_item.added" ,
156164 Data : map [string ]any {
157- "output_index" : h .state .reasoningOutputOffset (),
158- "item" : map [string ]any {
159- "type" : "message" ,
165+ keyOutputIndex : h .state .reasoningOutputOffset (),
166+ keyItem : map [string ]any {
167+ keyType : "message" ,
160168 "role" : "assistant" ,
161169 "content" : []any {},
162170 "status" : "in_progress" ,
@@ -169,11 +177,11 @@ func (h *Handler) processTextContent(content string) []Event {
169177 events = append (events , & RawResponseEvent {
170178 Type : "response.content_part.added" ,
171179 Data : map [string ]any {
172- "content_index" : h .state .textContentIndex .index ,
173- "output_index" : h .state .reasoningOutputOffset (),
180+ keyContentIndex : h .state .textContentIndex .index ,
181+ keyOutputIndex : h .state .reasoningOutputOffset (),
174182 "part" : map [string ]any {
175- "type" : "output_text" ,
176- "text" : "" ,
183+ keyType : "output_text" ,
184+ "text" : "" ,
177185 },
178186 },
179187 SequenceNumber : h .seqNum .Next (),
@@ -184,8 +192,8 @@ func (h *Handler) processTextContent(content string) []Event {
184192 events = append (events , & RawResponseEvent {
185193 Type : "response.output_text.delta" ,
186194 Data : map [string ]any {
187- "content_index" : h .state .textContentIndex .index ,
188- "output_index" : h .state .reasoningOutputOffset (),
195+ keyContentIndex : h .state .textContentIndex .index ,
196+ keyOutputIndex : h .state .reasoningOutputOffset (),
189197 "delta" : content ,
190198 },
191199 SequenceNumber : h .seqNum .Next (),
@@ -220,9 +228,9 @@ func (h *Handler) processRefusal(refusal string) []Event {
220228 events = append (events , & RawResponseEvent {
221229 Type : "response.output_item.added" ,
222230 Data : map [string ]any {
223- "output_index" : h .state .reasoningOutputOffset (),
224- "item" : map [string ]any {
225- "type" : "message" ,
231+ keyOutputIndex : h .state .reasoningOutputOffset (),
232+ keyItem : map [string ]any {
233+ keyType : "message" ,
226234 "role" : "assistant" ,
227235 "content" : []any {},
228236 "status" : "in_progress" ,
@@ -234,11 +242,11 @@ func (h *Handler) processRefusal(refusal string) []Event {
234242 events = append (events , & RawResponseEvent {
235243 Type : "response.content_part.added" ,
236244 Data : map [string ]any {
237- "content_index" : h .state .refusalContentIndex .index ,
238- "output_index" : h .state .reasoningOutputOffset (),
245+ keyContentIndex : h .state .refusalContentIndex .index ,
246+ keyOutputIndex : h .state .reasoningOutputOffset (),
239247 "part" : map [string ]any {
240- "type" : "refusal" ,
241- "refusal" : "" ,
248+ keyType : keyRefusal ,
249+ keyRefusal : "" ,
242250 },
243251 },
244252 SequenceNumber : h .seqNum .Next (),
@@ -249,8 +257,8 @@ func (h *Handler) processRefusal(refusal string) []Event {
249257 events = append (events , & RawResponseEvent {
250258 Type : "response.refusal.delta" ,
251259 Data : map [string ]any {
252- "content_index" : h .state .refusalContentIndex .index ,
253- "output_index" : h .state .reasoningOutputOffset (),
260+ keyContentIndex : h .state .refusalContentIndex .index ,
261+ keyOutputIndex : h .state .reasoningOutputOffset (),
254262 "delta" : refusal ,
255263 },
256264 SequenceNumber : h .seqNum .Next (),
@@ -322,9 +330,9 @@ func (h *Handler) processToolCalls(toolCalls []openai.ChatCompletionChunkChoiceD
322330 events = append (events , & RawResponseEvent {
323331 Type : "response.output_item.added" ,
324332 Data : map [string ]any {
325- "output_index" : outputIndex ,
326- "item" : map [string ]any {
327- "type" : "function_call" ,
333+ keyOutputIndex : outputIndex ,
334+ keyItem : map [string ]any {
335+ keyType : "function_call" ,
328336 "call_id" : builder .callID ,
329337 "name" : builder .name ,
330338 "arguments" : "" ,
@@ -340,7 +348,7 @@ func (h *Handler) processToolCalls(toolCalls []openai.ChatCompletionChunkChoiceD
340348 events = append (events , & RawResponseEvent {
341349 Type : "response.function_call_arguments.delta" ,
342350 Data : map [string ]any {
343- "output_index" : outputIndex ,
351+ keyOutputIndex : outputIndex ,
344352 "delta" : tc .Function .Arguments ,
345353 },
346354 SequenceNumber : h .seqNum .Next (),
@@ -360,11 +368,11 @@ func (h *Handler) Finalize() []Event {
360368 events = append (events , & RawResponseEvent {
361369 Type : "response.content_part.done" ,
362370 Data : map [string ]any {
363- "content_index" : h .state .textContentIndex .index ,
364- "output_index" : h .state .reasoningOutputOffset (),
371+ keyContentIndex : h .state .textContentIndex .index ,
372+ keyOutputIndex : h .state .reasoningOutputOffset (),
365373 "part" : map [string ]any {
366- "type" : "output_text" ,
367- "text" : h .state .textContentIndex .text ,
374+ keyType : "output_text" ,
375+ "text" : h .state .textContentIndex .text ,
368376 },
369377 },
370378 SequenceNumber : h .seqNum .Next (),
@@ -376,11 +384,11 @@ func (h *Handler) Finalize() []Event {
376384 events = append (events , & RawResponseEvent {
377385 Type : "response.content_part.done" ,
378386 Data : map [string ]any {
379- "content_index" : h .state .refusalContentIndex .index ,
380- "output_index" : h .state .reasoningOutputOffset (),
387+ keyContentIndex : h .state .refusalContentIndex .index ,
388+ keyOutputIndex : h .state .reasoningOutputOffset (),
381389 "part" : map [string ]any {
382- "type" : "refusal" ,
383- "refusal" : h .state .refusalContentIndex .refusal ,
390+ keyType : keyRefusal ,
391+ keyRefusal : h .state .refusalContentIndex .refusal ,
384392 },
385393 },
386394 SequenceNumber : h .seqNum .Next (),
@@ -394,9 +402,9 @@ func (h *Handler) Finalize() []Event {
394402 events = append (events , & RawResponseEvent {
395403 Type : "response.output_item.done" ,
396404 Data : map [string ]any {
397- "output_index" : outputIndex ,
398- "item" : map [string ]any {
399- "type" : "function_call" ,
405+ keyOutputIndex : outputIndex ,
406+ keyItem : map [string ]any {
407+ keyType : "function_call" ,
400408 "call_id" : builder .callID ,
401409 "name" : builder .name ,
402410 "arguments" : builder .arguments ,
@@ -412,23 +420,23 @@ func (h *Handler) Finalize() []Event {
412420 content := make ([]map [string ]any , 0 )
413421 if h .state .textContentIndex != nil {
414422 content = append (content , map [string ]any {
415- "type" : "output_text" ,
416- "text" : h .state .textContentIndex .text ,
423+ keyType : "output_text" ,
424+ "text" : h .state .textContentIndex .text ,
417425 })
418426 }
419427 if h .state .refusalContentIndex != nil {
420428 content = append (content , map [string ]any {
421- "type" : "refusal" ,
422- "refusal" : h .state .refusalContentIndex .refusal ,
429+ keyType : keyRefusal ,
430+ keyRefusal : h .state .refusalContentIndex .refusal ,
423431 })
424432 }
425433
426434 events = append (events , & RawResponseEvent {
427435 Type : "response.output_item.done" ,
428436 Data : map [string ]any {
429- "output_index" : h .state .reasoningOutputOffset (),
430- "item" : map [string ]any {
431- "type" : "message" ,
437+ keyOutputIndex : h .state .reasoningOutputOffset (),
438+ keyItem : map [string ]any {
439+ keyType : "message" ,
432440 "role" : "assistant" ,
433441 "content" : content ,
434442 "status" : "completed" ,
0 commit comments