Skip to content

swift 6 + actor + sendable #22

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: develop
Choose a base branch
from
Open
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
79 changes: 79 additions & 0 deletions .swiftpm/xcode/xcshareddata/xcschemes/AISwiftAssist.xcscheme
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1620"
version = "1.7">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES"
buildArchitectures = "Automatic">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "AISwiftAssist"
BuildableName = "AISwiftAssist"
BlueprintName = "AISwiftAssist"
ReferencedContainer = "container:">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"
shouldAutocreateTestPlan = "YES">
<Testables>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "AISwiftAssistTests"
BuildableName = "AISwiftAssistTests"
BlueprintName = "AISwiftAssistTests"
ReferencedContainer = "container:">
</BuildableReference>
</TestableReference>
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "AISwiftAssist"
BuildableName = "AISwiftAssist"
BlueprintName = "AISwiftAssist"
ReferencedContainer = "container:">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
6 changes: 4 additions & 2 deletions Package.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// swift-tools-version: 5.9
// swift-tools-version: 6.0
// The swift-tools-version declares the minimum version of Swift required to build this package.

import PackageDescription
Expand All @@ -7,6 +7,7 @@ let package = Package(
name: "AISwiftAssist",
platforms: [
.iOS(.v13),
.macOS(.v12),
.watchOS(.v8)
],
products: [
Expand All @@ -24,5 +25,6 @@ let package = Package(
name: "AISwiftAssistTests",
dependencies: ["AISwiftAssist"]
),
]
],
swiftLanguageModes: [.v6]
)
67 changes: 9 additions & 58 deletions Sources/AISwiftAssist/APIs/AssistantsAPI.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import Foundation

/// Build assistants that can call models and use tools to perform tasks. [Link for Assistants](https://platform.openai.com/docs/api-reference/assistants)
public protocol IAssistantsAPI: AnyObject {
public protocol IAssistantsAPI: AnyObject, Sendable {

/// Returns a list of assistants.
/// - Parameter parameters: Parameters for the list of assistants.
Expand Down Expand Up @@ -36,49 +36,20 @@ public protocol IAssistantsAPI: AnyObject {
/// - Parameter assistantId: The ID of the assistant to delete.
/// - Returns: Deletion status
func delete(by assistantId: String) async throws -> ASADeleteModelResponse

/// Create an assistant file by attaching a File to an assistant.
/// - Parameters:
/// - assistantId: The ID of the assistant for which to create a File.
/// - request: The request object containing the File ID.
/// - Returns: An assistant file object.
func createFile(for assistantId: String, with request: ASACreateAssistantFileRequest) async throws -> ASAAssistantFile

/// Retrieves an assistant file.
/// - Parameters:
/// - assistantId: The ID of the assistant who the file belongs to.
/// - fileId: The ID of the file to retrieve.
/// - Returns: The assistant file object matching the specified ID.
func retrieveFile(for assistantId: String, fileId: String) async throws -> ASAAssistantFile

/// Delete an assistant file.
/// - Parameters:
/// - assistantId: The ID of the assistant that the file belongs to.
/// - fileId: The ID of the file to delete.
/// - Returns: Deletion status.
func deleteFile(for assistantId: String, fileId: String) async throws -> ASADeleteModelResponse

/// Returns a list of assistant files.
/// - Parameters:
/// - assistantId: The ID of the assistant the file belongs to.
/// - parameters: Parameters for the list of assistant files.
/// - Returns: A list of assistant file objects.
func listFiles(for assistantId: String, with parameters: ASAListAssistantsParameters?) async throws -> ASAAssistantFilesListResponse
}

public final class AssistantsAPI: HTTPClient, IAssistantsAPI {
public actor AssistantsAPI: HTTPClient, IAssistantsAPI {

let urlSession: URLSession

public init(apiKey: String,
baseScheme: String = Constants.baseScheme,
baseHost: String = Constants.baseHost,
path: String = Constants.path,
urlSession: URLSession = .shared) {
Constants.apiKey = apiKey
Constants.baseScheme = baseScheme
Constants.baseHost = baseHost
Constants.path = path
public init(
config: AISwiftAssistConfig,
constants: AISwiftAssistConstants = .default,
urlSession: URLSession = .shared
) {
Constants.config = config
Constants.constants = constants
self.urlSession = urlSession
}

Expand Down Expand Up @@ -110,25 +81,5 @@ public final class AssistantsAPI: HTTPClient, IAssistantsAPI {
let endpoint = AssistantEndpoint.deleteAssistant(assistantId)
return try await sendRequest(session: urlSession, endpoint: endpoint, responseModel: ASADeleteModelResponse.self)
}

public func createFile(for assistantId: String, with request: ASACreateAssistantFileRequest) async throws -> ASAAssistantFile {
let endpoint = AssistantEndpoint.createFile(assistantId, request)
return try await sendRequest(session: urlSession, endpoint: endpoint, responseModel: ASAAssistantFile.self)
}

public func retrieveFile(for assistantId: String, fileId: String) async throws -> ASAAssistantFile {
let endpoint = AssistantEndpoint.retrieveFile(assistantId, fileId)
return try await sendRequest(session: urlSession, endpoint: endpoint, responseModel: ASAAssistantFile.self)
}

public func deleteFile(for assistantId: String, fileId: String) async throws -> ASADeleteModelResponse {
let endpoint = AssistantEndpoint.deleteFile(assistantId, fileId)
return try await sendRequest(session: urlSession, endpoint: endpoint, responseModel: ASADeleteModelResponse.self)
}

public func listFiles(for assistantId: String, with parameters: ASAListAssistantsParameters? = nil) async throws -> ASAAssistantFilesListResponse {
let endpoint = AssistantEndpoint.listFiles(assistantId, parameters)
return try await sendRequest(session: urlSession, endpoint: endpoint, responseModel: ASAAssistantFilesListResponse.self)
}
}

68 changes: 21 additions & 47 deletions Sources/AISwiftAssist/APIs/MessagesAPI.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,14 @@
import Foundation

/// Create messages within threads [Link for Messages](https://platform.openai.com/docs/api-reference/messages)
public protocol IMessagesAPI: AnyObject {
public protocol IMessagesAPI: AnyObject, Sendable {

/// Returns a list of messages for a given thread.
/// - Parameters:
/// - threadId: The ID of the thread the messages belong to.
/// - parameters: Parameters for the list of messages.
/// - Returns: A list of message objects.
func getMessages(by threadId: String, parameters: ASAListMessagesParameters?) async throws -> ASAMessagesListResponse

/// Create a message.
/// - Parameters:
Expand All @@ -31,51 +38,32 @@ public protocol IMessagesAPI: AnyObject {
/// - modifyMessage: Object with parameters for modifying a message.
/// - Returns: The modified message object.
func modify(by threadId: String, messageId: String, modifyMessage: ASAModifyMessageRequest) async throws -> ASAMessage

/// Returns a list of messages for a given thread.
/// - Parameters:
/// - threadId: The ID of the thread the messages belong to.
/// - parameters: Parameters for the list of messages.
/// - Returns: A list of message objects.
func getMessages(by threadId: String, parameters: ASAListMessagesParameters?) async throws -> ASAMessagesListResponse

/// Retrieves a file associated with a message.
/// - Parameters:
/// - threadId: The ID of the thread to which the message and file belong.
/// - messageId: The ID of the message the file belongs to.
/// - fileId: The ID of the file being retrieved.
/// - Returns: The message file object.
func retrieveFile(by threadId: String, messageId: String, fileId: String) async throws -> ASAMessageFile

/// Returns a list of files associated with a message.
/// - Parameters:
/// - threadId: The ID of the thread that the message and files belong to.
/// - messageId: The ID of the message that the files belong to.
/// - parameters: Optional parameters for pagination and sorting.
/// - Returns: A list of message file objects.
func listFiles(by threadId: String, messageId: String, parameters: ASAListMessagesParameters?) async throws -> ASAMessageFilesListResponse
}

public final class MessagesAPI: HTTPClient, IMessagesAPI {
public actor MessagesAPI: HTTPClient, IMessagesAPI {

let urlSession: URLSession

public init(apiKey: String,
baseScheme: String = Constants.baseScheme,
baseHost: String = Constants.baseHost,
path: String = Constants.path,
urlSession: URLSession = .shared) {
Constants.apiKey = apiKey
Constants.baseScheme = baseScheme
Constants.baseHost = baseHost
Constants.path = path
public init(
config: AISwiftAssistConfig,
constants: AISwiftAssistConstants = .default,
urlSession: URLSession = .shared
) {
Constants.config = config
Constants.constants = constants
self.urlSession = urlSession
}

public init(urlSession: URLSession = .shared) {
self.urlSession = urlSession
}

public func getMessages(by threadId: String, parameters: ASAListMessagesParameters?) async throws -> ASAMessagesListResponse {
let endpoint = MessagesEndpoint.listMessages(threadId, parameters)
return try await sendRequest(session: urlSession, endpoint: endpoint, responseModel: ASAMessagesListResponse.self)
}

public func create(by threadId: String, createMessage: ASACreateMessageRequest) async throws -> ASAMessage {
let endpoint = MessagesEndpoint.createMessage(threadId, createMessage)
return try await sendRequest(session: urlSession, endpoint: endpoint, responseModel: ASAMessage.self)
Expand All @@ -91,18 +79,4 @@ public final class MessagesAPI: HTTPClient, IMessagesAPI {
return try await sendRequest(session: urlSession, endpoint: endpoint, responseModel: ASAMessage.self)
}

public func getMessages(by threadId: String, parameters: ASAListMessagesParameters?) async throws -> ASAMessagesListResponse {
let endpoint = MessagesEndpoint.listMessages(threadId, parameters)
return try await sendRequest(session: urlSession, endpoint: endpoint, responseModel: ASAMessagesListResponse.self)
}

public func retrieveFile(by threadId: String, messageId: String, fileId: String) async throws -> ASAMessageFile {
let endpoint = MessagesEndpoint.retrieveFile(threadId, messageId, fileId)
return try await sendRequest(session: urlSession, endpoint: endpoint, responseModel: ASAMessageFile.self)
}

public func listFiles(by threadId: String, messageId: String, parameters: ASAListMessagesParameters?) async throws -> ASAMessageFilesListResponse {
let endpoint = MessagesEndpoint.listFiles(threadId, messageId, parameters)
return try await sendRequest(session: urlSession, endpoint: endpoint, responseModel: ASAMessageFilesListResponse.self)
}
}
Loading