Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions Examples/SwiftUICallView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,34 @@ class CallManager: ObservableObject {
print(event)
case .voiceInput:
print(event)
case .workflowNodeStarted:
print(event)
case .assistantStarted:
print(event)
case .toolCalls:
print(event)
case .toolCallsResult:
print(event)
case .transferUpdate:
print(event)
case .languageChangeDetected:
print(event)
case .chatCreated:
print(event)
case .chatDeleted:
print(event)
case .sessionCreated:
print(event)
case .sessionUpdated:
print(event)
case .sessionDeleted:
print(event)
case .callDeleted:
print(event)
case .callDeleteFailed:
print(event)
case .unknown:
print(event)
case .error(let error):
print("Error: \(error)")
}
Expand Down
78 changes: 74 additions & 4 deletions Sources/Models/AppMessage.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@

import Foundation

struct AppMessage: Codable {
enum MessageType: String, Codable {
struct AppMessage: Decodable {
enum MessageType: String {
case hang
case functionCall = "function-call"
case transcript
Expand All @@ -19,7 +19,77 @@ struct AppMessage: Codable {
case statusUpdate = "status-update"
case voiceInput = "voice-input"
case userInterrupted = "user-interrupted"
case assistantStarted = "assistant.started"
case workflowNodeStarted = "workflow.node.started"
case toolCalls = "tool-calls"
case toolCallsResult = "tool-calls-result"
case transferUpdate = "transfer-update"
case languageChangeDetected = "language-change-detected"
case chatCreated = "chat.created"
case chatDeleted = "chat.deleted"
case sessionCreated = "session.created"
case sessionUpdated = "session.updated"
case sessionDeleted = "session.deleted"
case callDeleted = "call.deleted"
case callDeleteFailed = "call.delete.failed"
case unknown
}

let type: String

var messageType: MessageType {
// Messages can be configured as transcript[transcriptType="final"].
let normalizedType = String(type.split(separator: "[", maxSplits: 1).first ?? "")

switch normalizedType {
case MessageType.functionCall.rawValue:
return .functionCall
case MessageType.hang.rawValue:
return .hang
case MessageType.transcript.rawValue:
return .transcript
case MessageType.speechUpdate.rawValue:
return .speechUpdate
case MessageType.metadata.rawValue:
return .metadata
case MessageType.conversationUpdate.rawValue:
return .conversationUpdate
case MessageType.modelOutput.rawValue:
return .modelOutput
case MessageType.statusUpdate.rawValue:
return .statusUpdate
case MessageType.voiceInput.rawValue:
return .voiceInput
case MessageType.userInterrupted.rawValue:
return .userInterrupted
case MessageType.assistantStarted.rawValue:
return .assistantStarted
case MessageType.workflowNodeStarted.rawValue:
return .workflowNodeStarted
case MessageType.toolCalls.rawValue:
return .toolCalls
case MessageType.toolCallsResult.rawValue, "function-call-result", "tool.completed", "assistant.tool.completed":
return .toolCallsResult
case MessageType.transferUpdate.rawValue:
return .transferUpdate
case MessageType.languageChangeDetected.rawValue, "language-changed":
return .languageChangeDetected
case MessageType.chatCreated.rawValue:
return .chatCreated
case MessageType.chatDeleted.rawValue:
return .chatDeleted
case MessageType.sessionCreated.rawValue:
return .sessionCreated
case MessageType.sessionUpdated.rawValue:
return .sessionUpdated
case MessageType.sessionDeleted.rawValue:
return .sessionDeleted
case MessageType.callDeleted.rawValue:
return .callDeleted
case MessageType.callDeleteFailed.rawValue:
return .callDeleteFailed
default:
return .unknown
}
}

let type: MessageType
}
53 changes: 52 additions & 1 deletion Sources/Models/ConversationUpdate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,63 @@ public struct Message: Codable {
case user = "user"
case assistant = "assistant"
case system = "system"
case tool = "tool"
case unknown

public init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
let rawValue = try container.decode(String.self)
self = Role(rawValue: rawValue) ?? .unknown
}
}

public let role: Role
public let content: String
public let content: String?

private enum CodingKeys: String, CodingKey {
case role
case content
}

public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
role = (try? container.decode(Role.self, forKey: .role)) ?? .unknown
content = try? container.decodeIfPresent(String.self, forKey: .content)
}
}

public struct ConversationUpdate: Codable {
public let conversation: [Message]

private enum CodingKeys: String, CodingKey {
case conversation
case messages
case messagesOpenAIFormatted
}

public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)

if let conversation = try? container.decode([Message].self, forKey: .conversation) {
self.conversation = conversation
return
}

if let messages = try? container.decode([Message].self, forKey: .messages) {
self.conversation = messages
return
}

if let openAIFormattedMessages = try? container.decode([Message].self, forKey: .messagesOpenAIFormatted) {
self.conversation = openAIFormattedMessages
return
}

self.conversation = []
}

public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(conversation, forKey: .conversation)
}
}
Loading