Skip to content

Commit bc6b847

Browse files
Merge pull request #193 from Panha-Sim/main
Handle Realtime MCP event response.mcp_call.completed
2 parents b138a46 + 9899e97 commit bc6b847

7 files changed

Lines changed: 26 additions & 8 deletions

File tree

Examples/SwiftOpenAIExample/SwiftOpenAIExample/Files/AttachmentView.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import SwiftUI
1010
struct AttachmentView: View {
1111
let fileName: String
1212
@Binding var actionTrigger: Bool
13+
1314
let isLoading: Bool
1415

1516
var body: some View {

Examples/SwiftOpenAIExample/SwiftOpenAIExample/ResponseAPIDemo/ResponseStreamDemoView.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,7 @@ struct ResponseStreamDemoView: View {
145145

146146
struct MessageBubbleView: View {
147147
let message: ResponseStreamProvider.ResponseMessage
148+
148149
@Environment(\.colorScheme) var colorScheme
149150

150151
var body: some View {

Examples/SwiftOpenAIExample/SwiftOpenAIExample/SharedUI/LoadingView.swift

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,6 @@
88
import SwiftUI
99

1010
struct LoadingView: View {
11-
@State private var dotsCount = 0
12-
1311
let timer = Timer.publish(every: 0.5, on: .main, in: .common).autoconnect()
1412

1513
var body: some View {
@@ -28,4 +26,7 @@ struct LoadingView: View {
2826
func getDots() -> String {
2927
String(repeating: ".", count: dotsCount)
3028
}
29+
30+
@State private var dotsCount = 0
31+
3132
}

Sources/OpenAI/Private/Audio/MicrophonePCMSampleVendorAT.swift

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -278,11 +278,11 @@ class MicrophonePCMSampleVendorAT: MicrophonePCMSampleVendor {
278278
/// This @RealtimeActor annotation is a lie.
279279
@RealtimeActor private let audioRenderCallback: AURenderCallback = {
280280
inRefCon,
281-
ioActionFlags,
282-
inTimeStamp,
283-
inBusNumber,
284-
inNumberFrames,
285-
_ in
281+
ioActionFlags,
282+
inTimeStamp,
283+
inBusNumber,
284+
inNumberFrames,
285+
_ in
286286
let microphonePCMSampleVendor = Unmanaged<MicrophonePCMSampleVendorAT>
287287
.fromOpaque(inRefCon)
288288
.takeUnretainedValue()

Sources/OpenAI/Private/Realtime/OpenAIRealtimeSession.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,15 @@ open class OpenAIRealtimeSession {
249249

250250
continuation?.yield(.mcpListToolsFailed(fullError))
251251

252+
case "response.mcp_call.completed":
253+
let eventId = json["event_id"] as? String
254+
let itemId = json["item_id"] as? String
255+
let outputIndex = json["output_index"] as? Int
256+
continuation?.yield(.responseMcpCallCompleted(eventId: eventId, itemId: itemId, outputIndex: outputIndex))
257+
258+
case "response.mcp_call.in_progress":
259+
continuation?.yield(.responseMcpCallInProgress)
260+
252261
case "response.done":
253262
// Handle response completion (may contain errors like insufficient_quota)
254263
if

Sources/OpenAI/Public/ResponseModels/Realtime/OpenAIRealtimeMessage.swift

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ public enum OpenAIRealtimeMessage: Sendable {
2626
case mcpListToolsInProgress // "mcp_list_tools.in_progress"
2727
case mcpListToolsCompleted([String: Any]) // "mcp_list_tools.completed" with tools data
2828
case mcpListToolsFailed(String?) // "mcp_list_tools.failed" with error details
29-
3029
/// Response completion with potential errors
3130
case responseDone(status: String, statusDetails: [String: Any]?) // "response.done"
3231

@@ -42,6 +41,10 @@ public enum OpenAIRealtimeMessage: Sendable {
4241
case responseContentPartAdded(type: String) // "response.content_part.added"
4342
case responseContentPartDone(type: String, text: String?) // "response.content_part.done"
4443

44+
// MCP response
45+
case responseMcpCallCompleted(eventId: String?, itemId: String?, outputIndex: Int?)
46+
case responseMcpCallInProgress
47+
4548
/// Conversation item
4649
case conversationItemCreated(itemId: String, type: String, role: String?) // "conversation.item.created"
4750
}

Sources/OpenAI/Public/Service/OpenAIService.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1419,9 +1419,11 @@ extension OpenAIService {
14191419
case .threadMessageDelta:
14201420
let decoded = try self.decoder.decode(MessageDeltaObject.self, from: data)
14211421
continuation.yield(.threadMessageDelta(decoded))
1422+
14221423
case .threadRunStepDelta:
14231424
let decoded = try self.decoder.decode(RunStepDeltaObject.self, from: data)
14241425
continuation.yield(.threadRunStepDelta(decoded))
1426+
14251427
case .threadRun:
14261428
// We expect a object of type "thread.run.SOME_STATE" in the data object
14271429
// However what we get is a `thread.run` object but we can check the status
@@ -1454,6 +1456,7 @@ extension OpenAIService {
14541456
}
14551457
#endif
14561458
}
1459+
14571460
default:
14581461
#if DEBUG
14591462
if debugEnabled {

0 commit comments

Comments
 (0)