@@ -55,11 +55,22 @@ final class ModelResponseEventsStreamInterpreter: @unchecked Sendable, StreamInt
55
55
}
56
56
57
57
private func processEvent( _ event: ServerSentEventsStreamParser . Event ) throws {
58
- guard let modelResponseEventType = ModelResponseStreamEventType ( rawValue: event. eventType) else {
59
- throw InterpreterError . unknownEventType ( event. eventType)
58
+ var finalEvent = event
59
+ if event. eventType == " response.output_text.annotation.added " {
60
+ // Remove when they have fixed (unified)!
61
+ //
62
+ // By looking at [API Reference](https://platform.openai.com/docs/api-reference/responses-streaming/response/output_text_annotation/added)
63
+ // and generated type `Schemas.ResponseOutputTextAnnotationAddedEvent`
64
+ // We can see that "output_text.annotation" is incorrect, whereas output_text_annotation is the correct one
65
+ let fixedDataString = event. decodedData. replacingOccurrences ( of: " response.output_text.annotation.added " , with: " response.output_text_annotation.added " )
66
+ finalEvent = . init( id: event. id, data: fixedDataString. data ( using: . utf8) ?? event. data, decodedData: fixedDataString, eventType: " response.output_text_annotation.added " , retry: event. retry)
60
67
}
61
68
62
- let responseStreamEvent = try responseStreamEvent ( modelResponseEventType: modelResponseEventType, data: event. data)
69
+ guard let modelResponseEventType = ModelResponseStreamEventType ( rawValue: finalEvent. eventType) else {
70
+ throw InterpreterError . unknownEventType ( finalEvent. eventType)
71
+ }
72
+
73
+ let responseStreamEvent = try responseStreamEvent ( modelResponseEventType: modelResponseEventType, data: finalEvent. data)
63
74
onEventDispatched ? ( responseStreamEvent)
64
75
}
65
76
@@ -75,37 +86,35 @@ final class ModelResponseEventsStreamInterpreter: @unchecked Sendable, StreamInt
75
86
) throws -> ResponseStreamEvent {
76
87
switch modelResponseEventType {
77
88
case . responseCreated:
78
- . created( try decoder . decode ( ResponseEvent . self , from : data) )
89
+ . created( try decode ( data : data) )
79
90
case . responseInProgress:
80
- . inProgress( try decoder . decode ( ResponseEvent . self , from : data) )
91
+ . inProgress( try decode ( data : data) )
81
92
case . responseCompleted:
82
- . completed( try decoder . decode ( ResponseEvent . self , from : data) )
93
+ . completed( try decode ( data : data) )
83
94
case . responseFailed:
84
- . failed( try decoder . decode ( ResponseEvent . self , from : data) )
95
+ . failed( try decode ( data : data) )
85
96
case . responseIncomplete:
86
- . incomplete( try decoder . decode ( ResponseEvent . self , from : data) )
97
+ . incomplete( try decode ( data : data) )
87
98
case . responseOutputItemAdded:
88
- . outputItem( . added( try decoder . decode ( ResponseOutputItemAddedEvent . self , from : data) ) )
99
+ . outputItem( . added( try decode ( data : data) ) )
89
100
case . responseOutputItemDone:
90
- . outputItem( . done( try decoder . decode ( ResponseOutputItemDoneEvent . self , from : data) ) )
101
+ . outputItem( . done( try decode ( data : data) ) )
91
102
case . responseContentPartAdded:
92
- . contentPart( . added( try decoder . decode ( Schemas . ResponseContentPartAddedEvent . self , from : data) ) )
103
+ . contentPart( . added( try decode ( data : data) ) )
93
104
case . responseContentPartDone:
94
- . contentPart( . done( try decoder . decode ( Schemas . ResponseContentPartDoneEvent . self , from : data) ) )
105
+ . contentPart( . done( try decode ( data : data) ) )
95
106
case . responseOutputTextDelta:
96
- . outputText( . delta( try decoder. decode ( Schemas . ResponseTextDeltaEvent. self, from: data) ) )
97
- case . responseOutputTextAnnotationAdded:
98
- . outputText( . annotationAdded( try decoder. decode ( Schemas . ResponseTextAnnotationDeltaEvent. self, from: data) ) )
107
+ . outputText( . delta( try decode ( data: data) ) )
99
108
case . responseOutputTextDone:
100
- . outputText( . done( try decoder . decode ( Schemas . ResponseTextDoneEvent . self , from : data) ) )
109
+ . outputText( . done( try decode ( data : data) ) )
101
110
case . responseRefusalDelta:
102
- . refusal( . delta( try decoder . decode ( Schemas . ResponseRefusalDeltaEvent . self , from : data) ) )
111
+ . refusal( . delta( try decode ( data : data) ) )
103
112
case . responseRefusalDone:
104
- . refusal( . done( try decoder . decode ( Schemas . ResponseRefusalDoneEvent . self , from : data) ) )
113
+ . refusal( . done( try decode ( data : data) ) )
105
114
case . responseFunctionCallArgumentsDelta:
106
- . functionCallArguments( . delta( try decoder . decode ( Schemas . ResponseFunctionCallArgumentsDeltaEvent . self , from : data) ) )
115
+ . functionCallArguments( . delta( try decode ( data : data) ) )
107
116
case . responseFunctionCallArgumentsDone:
108
- . functionCallArguments( . done( try decoder . decode ( Schemas . ResponseFunctionCallArgumentsDoneEvent . self , from : data) ) )
117
+ . functionCallArguments( . done( try decode ( data : data) ) )
109
118
case . responseFileSearchCallInProgress:
110
119
. fileSearchCall( . inProgress( try decode ( data: data) ) )
111
120
case . responseFileSearchCallSearching:
@@ -118,7 +127,53 @@ final class ModelResponseEventsStreamInterpreter: @unchecked Sendable, StreamInt
118
127
. webSearchCall( . searching( try decode ( data: data) ) )
119
128
case . responseWebSearchCallCompleted:
120
129
. webSearchCall( . completed( try decode ( data: data) ) )
130
+ case . responseReasoningSummaryPartAdded:
131
+ . reasoningSummaryPart( . added( try decode ( data: data) ) )
132
+ case . responseReasoningSummaryPartDone:
133
+ . reasoningSummaryPart( . done( try decode ( data: data) ) )
134
+ case . responseReasoningSummaryTextDelta:
135
+ . reasoningSummaryText( . delta( try decode ( data: data) ) )
136
+ case . responseReasoningSummaryTextDone:
137
+ . reasoningSummaryText( . done( try decode ( data: data) ) )
138
+ case . responseImageGenerationCallCompleted:
139
+ . imageGenerationCall( . completed( try decode ( data: data) ) )
140
+ case . responseImageGenerationCallGenerating:
141
+ . imageGenerationCall( . generating( try decode ( data: data) ) )
142
+ case . responseImageGenerationCallInProgress:
143
+ . imageGenerationCall( . inProgress( try decode ( data: data) ) )
144
+ case . responseImageGenerationCallPartialImage:
145
+ . imageGenerationCall( . partialImage( try decode ( data: data) ) )
146
+ case . responseMcpCallArgumentsDelta:
147
+ . mcpCall( . arguments( . delta( try decode ( data: data) ) ) )
148
+ case . responseMcpCallArgumentsDone:
149
+ . mcpCall( . arguments( . done( try decode ( data: data) ) ) )
150
+ case . responseMcpCallCompleted:
151
+ . mcpCall( . completed( try decode ( data: data) ) )
152
+ case . responseMcpCallFailed:
153
+ . mcpCall( . failed( try decode ( data: data) ) )
154
+ case . responseMcpCallInProgress:
155
+ . mcpCall( . inProgress( try decode ( data: data) ) )
156
+ case . responseMcpListToolsCompleted:
157
+ . mcpListTools( . completed( try decode ( data: data) ) )
158
+ case . responseMcpListToolsFailed:
159
+ . mcpListTools( . failed( try decode ( data: data) ) )
160
+ case . responseMcpListToolsInProgress:
161
+ . mcpListTools( . inProgress( try decode ( data: data) ) )
162
+ case . responseQueued:
163
+ . queued( try decode ( data: data) )
164
+ case . responseReasoningDelta:
165
+ . reasoning( . delta( try decode ( data: data) ) )
166
+ case . responseReasoningDone:
167
+ . reasoning( . done( try decode ( data: data) ) )
168
+ case . responseReasoningSummaryDelta:
169
+ . reasoningSummary( . delta( try decode ( data: data) ) )
170
+ case . responseReasoningSummaryDone:
171
+ . reasoningSummary( . done( try decode ( data: data) ) )
172
+ case . responseOutputTextAnnotationAdded:
173
+ . outputTextAnnotation( . added( try decode ( data: data) ) )
121
174
case . responseAudioDelta:
175
+ // Audio, AudioTranscript and CodeInterpreter events are not part of API Reference at the moment
176
+ // But they are present in code generated from OpenAPI spec, so we also include it
122
177
. audio( . delta( try decode ( data: data) ) )
123
178
case . responseAudioDone:
124
179
. audio( . done( try decode ( data: data) ) )
0 commit comments