Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
65 commits
Select commit Hold shift + click to select a range
724eb17
Added ImageEdit and ImageVariations calls
MarkHoath Jul 16, 2023
0e02e20
Added Comments
MarkHoath Jul 16, 2023
71a6371
removed imageError
MarkHoath Jul 16, 2023
f5a33dc
Change Data to String for edits
MarkHoath Jul 16, 2023
7d764f5
Fixed Image and Mask to Strings not Data
MarkHoath Jul 16, 2023
92dc7e1
Add the correct formats for Edits and Variations
MarkHoath Jul 16, 2023
a14c801
Back to Data for the Data type!
MarkHoath Jul 16, 2023
3d0f485
Back to String (Data is base64 encoded)
MarkHoath Jul 16, 2023
019ccc4
prints added for debugging
MarkHoath Jul 16, 2023
3b9a97f
multipart forms
MarkHoath Jul 16, 2023
64a580c
DALLE...
MarkHoath Jul 16, 2023
99bab81
debugging
MarkHoath Jul 16, 2023
108fb24
Prompt Fix
MarkHoath Jul 16, 2023
51d8dca
getting closer
MarkHoath Jul 16, 2023
953abde
one more...
MarkHoath Jul 16, 2023
78fc069
syntax
MarkHoath Jul 16, 2023
5ef24fe
fixed empty prompt
MarkHoath Jul 16, 2023
45e1327
final code
MarkHoath Jul 16, 2023
10f7eee
removed old structs
MarkHoath Jul 16, 2023
f021d4e
Removal of Identifiable
MarkHoath Jul 18, 2023
6cc1202
Update README.md
tysonwil Jul 21, 2023
db672df
Add explicit codable implementation to ChatMessage
marcoboerner Jul 31, 2023
0e7ae8e
fix problem on linux
underthestars-zhy Aug 18, 2023
d850bf0
pr by @marcoboerner
underthestars-zhy Aug 18, 2023
8ac1303
Reduced requirement to iOS 13
laszlotuss Aug 19, 2023
71994c0
Fixed error 2, ChatMessage Codable breaks auth
laszlotuss Aug 19, 2023
2f33fcd
Restored old init, but flagged deprecated
laszlotuss Aug 19, 2023
2c57dad
Refactoring and documenting id property in ChatMessage
marcoboerner Aug 19, 2023
d772242
Adding custom init from rawValue to OpenAIModelType
marcoboerner Aug 19, 2023
dc23218
Add compatible OpenAI model types
marcoboerner Sep 1, 2023
068359d
Update README.md
a-elnajjar Sep 12, 2023
4886eb6
Update README.md
a-elnajjar Sep 13, 2023
8b8c03b
Update README.md
a-elnajjar Sep 14, 2023
75192ad
add more sense to readme, fix 400 error because of id
astrokin Oct 15, 2023
db66252
improve error handling
astrokin Oct 16, 2023
34b9686
Merge pull request #5 from MarkHoath/main
MarkHoath Nov 9, 2023
d278ce8
Merge pull request #6 from tysonwil/patch-1
MarkHoath Nov 9, 2023
d81f042
Merge pull request #7 from marcoboerner/main
MarkHoath Nov 9, 2023
89b0522
Merge pull request #11 from astrokin/fix_400
MarkHoath Nov 9, 2023
5da2edf
Merge pull request #10 from a-elnajjar/a-elnajjar-patch-1
MarkHoath Nov 9, 2023
e881e72
Merge pull request #9 from laszlotuss/main
MarkHoath Nov 9, 2023
8245a52
Merge pull request #8 from underthestars-zhy/main
MarkHoath Nov 9, 2023
7751058
Merge pull request #12 from Swift-Almanac/marcoboerner
MarkHoath Nov 9, 2023
0241654
Merge branch 'main' into astrokin
MarkHoath Nov 9, 2023
f021a49
Merge pull request #13 from Swift-Almanac/astrokin
MarkHoath Nov 9, 2023
2e8409e
Merge branch 'main' into underthestars-zhy
MarkHoath Nov 9, 2023
dd94ede
Merge pull request #14 from Swift-Almanac/underthestars-zhy
MarkHoath Nov 9, 2023
c6b4241
Merge branch 'main' into laszlotuss
MarkHoath Nov 9, 2023
4f46e4c
Merge pull request #15 from Swift-Almanac/laszlotuss
MarkHoath Nov 9, 2023
965b03b
Merge branch 'main' into a-einajar
MarkHoath Nov 9, 2023
b4af8d1
Merge pull request #16 from Swift-Almanac/a-einajar
MarkHoath Nov 9, 2023
20c005a
Merge branch 'main' into markhoath
MarkHoath Nov 9, 2023
b8a99dd
Merge pull request #17 from Swift-Almanac/markhoath
MarkHoath Nov 9, 2023
d5337d9
Merge branch 'main' into tysonwil
MarkHoath Nov 9, 2023
7f0a25a
Merge pull request #18 from Swift-Almanac/tysonwil
MarkHoath Nov 9, 2023
3f720f4
Fixed Identifiable and Compile Issue
MarkHoath Nov 9, 2023
8516e41
Updates
MarkHoath Nov 10, 2023
cea73c3
Files Completed.
MarkHoath Nov 14, 2023
afce3df
Fine_tuning Completed.
MarkHoath Nov 14, 2023
c8cd977
Models Completed.
MarkHoath Nov 15, 2023
c32e033
changes to allow for Query Items and make Body Optional
MarkHoath Nov 15, 2023
0df40bf
Dev Conference beta
MarkHoath Nov 16, 2023
b7b0166
Extend URL Session Time Interval
MarkHoath Jan 5, 2024
aa5dba2
Latest Updates - 8 Feb 2024
MarkHoath Feb 7, 2024
0df0622
Merge pull request #2 from Swift-Almanac/ChatMessage
MarkHoath Feb 7, 2024
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
2 changes: 1 addition & 1 deletion Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import PackageDescription

let package = Package(
name: "OpenAISwift",
platforms: [.iOS(.v15), .macOS(.v10_15)],
platforms: [.iOS(.v13), .macOS(.v10_15)],
products: [
// Products define the executables and libraries a package produces, and make them visible to other packages.
.library(
Expand Down
34 changes: 33 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,39 @@ Import the framework in your project:

[Create an OpenAI API key](https://platform.openai.com/account/api-keys) and add it to your configuration:

`let openAI = OpenAISwift(authToken: "TOKEN")`
let TOKEN = "sk-...... "

let openAI: OpenAISwift = OpenAISwift(config: OpenAISwift.Config.makeDefaultOpenAI(apiKey: "TOKEN"))


To follow [OpenAI requirements](https://platform.openai.com/docs/api-reference/authentication)

> Remember that your API key is a secret! Do not share it with others or expose it in any client-side code (browsers, apps). Production requests must be routed through your own backend server where your API key can be securely loaded from an environment variable or key management service.

and basic industrial safety you should not call OpenAI API directly.

```swift
private lazy var proxyOpenAIBackend: OpenAISwift = .init(
config: OpenAISwift.Config(
baseURL: "http://localhost",
endpointPrivider: OpenAIEndpointProvider(source: .proxy(path: { _ -> String in
"/chat/completions"
}, method: { _ -> String in
"POST"
})),
session: session,
authorizeRequest: { [weak self] request in
self?.authorizeRequest(&request)
}
))

private func authorizeRequest(_ request: inout URLRequest) {
if let apiKey = try? Encryptor.getApiToken() {
request.setValue(apiKey, forHTTPHeaderField: "X-API-KEY")
}
}
```


This framework supports Swift concurrency; each example below has both an async/await and completion handler variant.

Expand Down
15 changes: 15 additions & 0 deletions Sources/OpenAISwift/Extensions/Extensions.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
//
// File.swift
//
//
// Created by Mark Hoath on 15/11/2023.
//

import Foundation

extension Encodable {
func toDictionary() -> [String: Any]? {
guard let data = try? JSONEncoder().encode(self) else { return nil }
return (try? JSONSerialization.jsonObject(with: data, options: .allowFragments)).flatMap { $0 as? [String: Any] }
}
}
69 changes: 69 additions & 0 deletions Sources/OpenAISwift/Models/AssistantObject.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
//
// File.swift
//
//
// Created by Mark Hoath on 15/11/2023.
//

import Foundation

public struct CodeInterpretorTool: Codable {
public let type: String
}

public struct RetrievalTool: Codable {
public let type: String
}

public struct ParamJSONObject: Codable {
public let properties: String
}

public struct FunctionObject: Codable {
public let description: String
public let name: String
public let parameters: ParamJSONObject
}

public struct FunctionTool: Codable {
public let type: String
public let function: FunctionObject
}

public struct Tools: Codable {
public let codeInterpretorTool: CodeInterpretorTool?
public let retrievalTool: RetrievalTool?
public let functionTool: FunctionTool?
}



public struct AssistantObject: Codable {
public let id: String
public let object: String
public let created_at: Int
public let name: String?
public let description: String?
public let model: String
public let instructions: String?
public let tools: [Tools]
public let file_ids: [String]
public let metadata: [String:String]
}

public struct AssistantBody: Codable {
public let model: String
public let name: String?
public let description: String?
public let instructions: String?
public let tools: [Tools]?
public let file_ids: [String]?
public let metadata: [String:String]?
}

public struct ListAssistantParams: Codable {
public let limit: Int?
public let order: String?
public let after: String?
public let before: String?
}
47 changes: 47 additions & 0 deletions Sources/OpenAISwift/Models/AudioObject.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
//
// File.swift
//
//
// Created by Mark Hoath on 14/11/2023.
//

import Foundation

public enum Voice: String, Codable {
case alloy, echo, fable, onyx, nova, shimmer
}

public enum AudioResponseFormat: String, Codable {
case mp3, opus, aac, flac
}

public enum TranscriptionResponseFormat: String, Codable {
case json, text, srt, verbose_json, vtt
}

public struct Audio: Encodable {
public let model: String
public let input: String
public let voice: Voice
public let response_format: AudioResponseFormat?
public let speed: Double?
}

public struct Transcription: Encodable {
public let file: String
public let model: String
public let language: String?
public let prompt: String?
public let response_format: TranscriptionResponseFormat?
public let temperature: Double?

}

public struct Translation: Encodable {
public let file: String
public let model: String
public let prompt: String?
public let response_format: TranscriptionResponseFormat?
public let temperature: Double?
}

42 changes: 39 additions & 3 deletions Sources/OpenAISwift/Models/ChatMessage.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,12 @@ public enum ChatRole: String, Codable {
}

/// A structure that represents a single message in a chat conversation.

public struct ChatMessage: Codable, Identifiable {
// uuid to conform to Identifiable protocol
/// UUID to conform to the Identifiable protocol
/// - Note: This property is not de- and encoded. A DTO or other logic might be required if the `ChatMessage` instance is stored locally.
public var id = UUID()

/// The role of the sender of the message.
public let role: ChatRole?
/// The content of the message.
Expand All @@ -34,6 +37,39 @@ public struct ChatMessage: Codable, Identifiable {
self.role = role
self.content = content
}

enum CodingKeys: CodingKey {
case id
case role
case content
}

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


self.id = UUID()
self.role = try container.decodeIfPresent(ChatRole.self, forKey: ChatMessage.CodingKeys.role)
self.content = try container.decodeIfPresent(String.self, forKey: ChatMessage.CodingKeys.content)

}

public func encode(to encoder: Encoder) throws {
var container: KeyedEncodingContainer<ChatMessage.CodingKeys> = encoder.container(keyedBy: ChatMessage.CodingKeys.self)

try container.encodeIfPresent(self.role, forKey: ChatMessage.CodingKeys.role)
try container.encodeIfPresent(self.content, forKey: ChatMessage.CodingKeys.content)

}
}

extension ChatMessage: Equatable {
public func hash(into hasher: inout Hasher) {
hasher.combine(id)
}
public static func == (lhs: ChatMessage, rhs: ChatMessage) -> Bool {
return lhs.id == rhs.id
}
}

/// A structure that represents a chat conversation.
Expand Down Expand Up @@ -70,7 +106,7 @@ public struct ChatConversation: Encodable {

/// Modify the likelihood of specified tokens appearing in the completion. Maps tokens (specified by their token ID in the OpenAI Tokenizer—not English words) to an associated bias value from -100 to 100. Values between -1 and 1 should decrease or increase likelihood of selection; values like -100 or 100 should result in a ban or exclusive selection of the relevant token.
let logitBias: [Int: Double]?

/// If you're generating long completions, waiting for the response can take many seconds. To get responses sooner, you can 'stream' the completion as it's being generated. This allows you to start printing or processing the beginning of the completion before the full completion is finished.
/// https://github.com/openai/openai-cookbook/blob/main/examples/How_to_stream_completions.ipynb
let stream: Bool?
Expand All @@ -96,6 +132,6 @@ public struct ChatError: Codable {
public let message, type: String
public let param, code: String?
}

public let error: Payload
}
31 changes: 31 additions & 0 deletions Sources/OpenAISwift/Models/FilesObject.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
//
// File.swift
//
//
// Created by Mark Hoath on 14/11/2023.
//

import Foundation


public enum FilePurpose: String, Codable {
case fine_tune = "fine-tune", fine_tune_results = "fine-tune-results", assistants, assistants_output = "assistants-output"
}

public struct FilesResquest: Codable {
public let purpose: String?
}

public struct FileUploadResquest: Codable {
public let file: Data
public let purpose: String
}

public struct FilesModel: Codable {
public var id: String
public var bytes: Int
public var created_at: Int
public var filename: String
public var object: String = "file"
public var purpose: FilePurpose?
}
61 changes: 61 additions & 0 deletions Sources/OpenAISwift/Models/FineTuningObject.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
//
// File.swift
//
//
// Created by Mark Hoath on 15/11/2023.
//

import Foundation


public struct FineTuningError: Codable {
public let code: String
public let message: String
public let param: String?
}

public struct FineTuningHyperParams: Codable {
public let batch_size: String?
public let learning_rate_multiplier: String?
public let n_epochs: String?
}

public struct FineTuning: Codable {

public let id: String
public let created_at: Int
public let error: FineTuningError?
public let fine_tuned_model: String?
public let finished_at: Int
public let hyperparameters: FineTuningHyperParams?
public let model: String
public let object: String
public let organization_id: String
public let results_files: [String]
public let status: String
public let trained_tokens: Int?
public let training_file: String
public let validation_file: String?
}

public struct FineTuningRequest: Codable {
public let model: String
public let training_file: String
public let hyperparameters: FineTuningHyperParams?
public let suffix: String?
public let validation_file: String?
}

public struct FineTuningListRequest: Codable {
public let after: String?
public let limit: Int?
}

public struct FineTuningEvent: Codable {
public let id: String
public let created_at: Int
public let level: String
public let message: String
public let object: String
}

16 changes: 16 additions & 0 deletions Sources/OpenAISwift/Models/ImageGeneration.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,22 @@ struct ImageGeneration: Encodable {
let user: String?
}

struct ImageEdit: Encodable {
let image: Data
let mask: Data?
let prompt: String
let n: Int
let size: ImageSize
let user: String?
}

struct ImageVariations: Encodable {
let image: Data
let n: Int
let size: ImageSize
let user: String?
}

public enum ImageSize: String, Codable {
case size1024 = "1024x1024"
case size512 = "512x512"
Expand Down
15 changes: 15 additions & 0 deletions Sources/OpenAISwift/Models/MessageFileObject.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
//
// File.swift
//
//
// Created by Mark Hoath on 16/11/2023.
//

import Foundation

public struct MessageFileObject: Codable {
public let id: String
public let object: String
public let created_at: Int
public let message_id: String
}
Loading