diff --git a/Package.resolved b/Package.resolved index 13b9b27..625fac8 100644 --- a/Package.resolved +++ b/Package.resolved @@ -1,5 +1,5 @@ { - "originHash" : "0c364e7fa8e05421f0e3b7bb643662940fdd975364f4e626d32917014214c887", + "originHash" : "d75be039b346c5be8e74ab76ba6410bc6894aa76cb62f747559983bc6aed165f", "pins" : [ { "identity" : "networkimage", @@ -33,8 +33,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/Compiler-Inc/Transcriber", "state" : { - "branch" : "0.1.8", - "revision" : "37e25987bb85f5edb6a77b8378fc2dac18124e99" + "revision" : "37e25987bb85f5edb6a77b8378fc2dac18124e99", + "version" : "0.1.8" } } ], diff --git a/Sources/CompilerSwiftAI/CompilerClient.swift b/Sources/CompilerSwiftAI/CompilerClient.swift index fd55ac0..b99ffba 100644 --- a/Sources/CompilerSwiftAI/CompilerClient.swift +++ b/Sources/CompilerSwiftAI/CompilerClient.swift @@ -62,4 +62,61 @@ public final actor CompilerClient { public func makeStreamingSession() -> StreamConfiguration { configuration.streamingChat } + + /// Generate text from a prompt using the specified model + /// - Parameters: + /// - prompt: The input prompt + /// - model: The model configuration to use + /// - systemPrompt: Optional system prompt to set context + /// - Returns: The complete model response including tokens used, finish reason, etc. + public func generateText( + prompt: String, + using model: StreamConfiguration, + systemPrompt: String? = nil + ) async throws -> CompletionResponse { + try await makeModelCallWithResponse( + using: model.metadata, + systemPrompt: systemPrompt, + userPrompt: prompt + ) + } + + /// Stream text generation from a prompt + /// - Parameters: + /// - prompt: The input prompt + /// - model: The model configuration to use + /// - systemPrompt: Optional system prompt to set context + /// - Returns: An async stream of response chunks with metadata + public func streamText( + prompt: String, + using model: StreamConfiguration, + systemPrompt: String? = nil + ) async -> AsyncThrowingStream { + let message = Message(role: .user, content: prompt) + let messages = systemPrompt.map { [Message(role: .system, content: $0), message] } ?? [message] + return makeStreamingModelCall(using: model.metadata, messages: messages) + } + + /// Process a natural language command into structured function calls + /// - Parameters: + /// - command: The natural language command to process + /// - Returns: Array of functions with their parameters + /// - Note: You must specify the Parameters type when calling this function, either through type annotation or explicit generic parameter: + /// ```swift + /// // Option 1: Type annotation + /// let functions: [Function] = try await client.processFunctionCall("Add todo") + /// + /// // Option 2: Explicit generic + /// let functions = try await client.processFunctionCall("Add todo") + /// ``` + public func processFunctionCall( + _ command: String + ) async throws -> [Function] { + // We use an empty state since this is the simplified version + try await processFunction(command, for: EmptyState(), using: "") + } +} + +private struct EmptyState: Encodable, Sendable { + // Empty state for simplified function calls } diff --git a/Sources/CompilerSwiftAI/Model Calling/ModelCall.swift b/Sources/CompilerSwiftAI/Model Calling/ModelCall.swift index 92031f4..44c8b72 100644 --- a/Sources/CompilerSwiftAI/Model Calling/ModelCall.swift +++ b/Sources/CompilerSwiftAI/Model Calling/ModelCall.swift @@ -71,12 +71,37 @@ struct StreamRequest: ModelCallRequestBase { } } -/// Response format for completion calls -struct CompletionResponse: Codable, Sendable { - let content: String +public struct CompletionResponse: Codable, Sendable { + private struct Choice: Codable { + struct Message: Codable { + let content: String + } + + let message: Message + } + + private let choices: [Choice] + + /// The generated text content + public var content: String { + choices.first?.message.content ?? "" + } } -/// Response format for streaming calls - each chunk -struct StreamChunk: Codable, Sendable { - let content: String +/// Response format for streaming chunks +public struct StreamChunk: Codable, Sendable { + private struct Choice: Codable { + struct Message: Codable { + let content: String + } + + let message: Message + } + + private let choices: [Choice] + + /// The generated text content + public var content: String { + choices.first?.message.content ?? "" + } } diff --git a/Sources/CompilerSwiftAI/UI/Chat/ChatView/ChatViewModel.swift b/Sources/CompilerSwiftAI/UI/Chat/ChatView/ChatViewModel.swift index 256ec7c..51e17db 100644 --- a/Sources/CompilerSwiftAI/UI/Chat/ChatView/ChatViewModel.swift +++ b/Sources/CompilerSwiftAI/UI/Chat/ChatView/ChatViewModel.swift @@ -14,6 +14,7 @@ You are a helpful AI Assistant. Be direct, concise, and friendly. Always format class ChatViewModel: Transcribable { public var isRecording = false public var transcribedText = "" + public var rmsLevel: Float = 0.0 public var authStatus: SFSpeechRecognizerAuthorizationStatus = .notDetermined public var error: Error? @@ -105,11 +106,11 @@ class ChatViewModel: Transcribable { let stream = try await transcriber.startStream() isRecording = true - for try await partialResult in stream { - switch partialResult { - case let .rms(float): - print("rms: \(float)") - case let .transcription(string): + for try await signal in stream { + switch signal { + case .rms(let float): + self.rmsLevel = float + case .transcription(let string): self._userInput = string } } diff --git a/Sources/CompilerSwiftAI/UI/Function Chat/FunctionChatViewModel.swift b/Sources/CompilerSwiftAI/UI/Function Chat/FunctionChatViewModel.swift index a2e3308..19e9d17 100644 --- a/Sources/CompilerSwiftAI/UI/Function Chat/FunctionChatViewModel.swift +++ b/Sources/CompilerSwiftAI/UI/Function Chat/FunctionChatViewModel.swift @@ -9,6 +9,7 @@ import Transcriber class FunctionChatViewModel: Transcribable { public var isRecording = false public var transcribedText = "" + public var rmsLevel: Float = 0 public var authStatus: SFSpeechRecognizerAuthorizationStatus = .notDetermined public var error: Error? @@ -41,12 +42,12 @@ class FunctionChatViewModel