Skip to content

Commit 81bb9d4

Browse files
authored
Merge pull request #4 from Recouse/feature/responses
Responses improvements
2 parents 66f3cfd + 8355bdd commit 81bb9d4

5 files changed

Lines changed: 241 additions & 9 deletions

File tree

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
//
2+
// Content.swift
3+
// OpenAI
4+
//
5+
// Created by Firdavs Khaydarov on 08/08/2025.
6+
//
7+
8+
public enum Content: Encodable, Sendable {
9+
case inputText(TextInput)
10+
case inputImage(ImageInput)
11+
case inputFile(FileInput)
12+
13+
enum TypeCodingKeys: String, CodingKey {
14+
case type
15+
}
16+
17+
public func encode(to encoder: any Encoder) throws {
18+
var container = encoder.singleValueContainer()
19+
20+
switch self {
21+
case .inputText(let textInput):
22+
try container.encode(textInput)
23+
case .inputImage(let imageInput):
24+
try container.encode(imageInput)
25+
case .inputFile(let fileInput):
26+
try container.encode(fileInput)
27+
}
28+
29+
}
30+
}
31+
32+
/// A text input to the model.
33+
public struct TextInput: Codable, Sendable {
34+
/// The text input to the model.
35+
public let text: String
36+
37+
/// The type of the input item. Always `input_text`.
38+
public let type: ContentType
39+
40+
enum CodingKeys: CodingKey {
41+
case text
42+
case type
43+
}
44+
45+
public init(text: String) {
46+
self.text = text
47+
self.type = .inputText
48+
}
49+
}
50+
51+
/// An image input to the model.
52+
public struct ImageInput: Codable, Sendable {
53+
/// The detail level of the image to be sent to the model.
54+
///
55+
/// One of `high`, `low`, or `auto`. Defaults to `auto`.
56+
public let detail: ImageDetail
57+
58+
/// The type of the input item. Always `input_image`.
59+
public let type: ContentType
60+
61+
/// The ID of the file to be sent to the model.
62+
public let fileId: String?
63+
64+
/// The URL of the image to be sent to the model.
65+
///
66+
/// A fully qualified URL or base64 encoded image in a data URL.
67+
public let imageUrl: String?
68+
69+
public init(detail: ImageDetail = .auto, fileId: String? = nil, imageUrl: String? = nil) {
70+
self.detail = detail
71+
self.type = .inputImage
72+
self.fileId = fileId
73+
self.imageUrl = imageUrl
74+
}
75+
}
76+
77+
/// A file input to the model.
78+
public struct FileInput: Codable, Sendable {
79+
/// The type of the input item. Always `input_file`.
80+
public let type: ContentType
81+
82+
/// The content of the file to be sent to the model.
83+
public let fileData: String?
84+
85+
/// The ID of the file to be sent to the model.
86+
public let fileId: String?
87+
88+
/// The URL of the file to be sent to the model.
89+
public let fileUrl: String?
90+
91+
/// The name of the file to be sent to the model.
92+
public let filename: String?
93+
94+
public init(
95+
fileData: String? = nil,
96+
fileId: String? = nil,
97+
fileUrl: String? = nil,
98+
filename: String? = nil
99+
) {
100+
self.type = .inputFile
101+
self.fileData = fileData
102+
self.fileId = fileId
103+
self.fileUrl = fileUrl
104+
self.filename = filename
105+
}
106+
}
107+
108+
public enum ContentType: String, Codable, Sendable {
109+
case inputText = "input_text"
110+
case outputText = "output_text"
111+
case inputFile = "input_file"
112+
case inputImage = "input_image"
113+
}
114+
115+
116+
public enum ImageDetail: String, Codable, Sendable {
117+
case auto, low, high
118+
}

Sources/OpenAI/Common/Prompt.swift

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
//
2+
// Prompt.swift
3+
// OpenAI
4+
//
5+
// Created by Firdavs Khaydarov on 08/08/2025.
6+
//
7+
8+
// TODO: Implement file input https://platform.openai.com/docs/guides/text#reusable-prompts
9+
10+
public struct Prompt: Encodable, Sendable {
11+
/// The unique identifier of the prompt template to use.
12+
public let id: String
13+
14+
/// Optional map of values to substitute in for variables in your prompt.
15+
///
16+
/// The substitution values can either be strings, or other Response input types like images or files.
17+
public let variables: [String: String]?
18+
19+
/// Optional version of the prompt template.
20+
public let version: String?
21+
22+
public init(id: String, variables: [String: String]? = nil, version: String? = nil) {
23+
self.id = id
24+
self.variables = variables
25+
self.version = version
26+
}
27+
}

Sources/OpenAI/Model.swift

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,86 @@
55
// Created by Firdavs Khaydarov on 01/08/2025.
66
//
77

8+
/// Model type to define OpenAI models.
9+
///
10+
/// For more information about models and their capabilities visit https://platform.openai.com/docs/models
811
public typealias Model = String
912

13+
// MARK: - o-series
14+
15+
extension Model {
16+
/// o1 models think before they answer, producing a long internal chain of thought before responding to the user.
17+
///
18+
/// * Context window: 200,000
19+
/// * Max output tokens: 100,000
20+
public static let o1: Model = "o1"
21+
22+
/// The o1-pro model uses more compute to think harder and provide consistently better answers.
23+
///
24+
/// o1-pro is available in the Responses API only to enable support for multi-turn model
25+
/// interactions before responding to API requests, and other advanced API features in the future.
26+
///
27+
/// * Context window: 200,000
28+
/// * Max output tokens: 100,000
29+
public static let o1_pro: Model = "o1-pro"
30+
31+
/// o3 is a well-rounded and powerful model across domains.
32+
///
33+
/// Use it to think through multi-step problems that involve analysis across text, code, and images.
34+
///
35+
/// * Context window: 200,000
36+
/// * Max output tokens: 100,000
37+
public static let o3: Model = "o3"
38+
39+
/// The o3-pro model uses more compute to think harder and provide consistently better answers.
40+
///
41+
/// o3-pro is available in the Responses API only to enable support for multi-turn model
42+
/// interactions before responding to API requests, and other advanced API features in the future.
43+
/// Since o3-pro is designed to tackle tough problems, some requests may take several minutes to
44+
/// finish. To avoid timeouts, try using background mode.
45+
///
46+
/// * Context window: 200,000
47+
/// * Max output tokens: 100,000
48+
public static let o3_pro: Model = "o3-pro"
49+
50+
/// o3-mini is our newest small reasoning model, providing high intelligence at the same cost
51+
/// and latency targets of o1-mini.
52+
///
53+
/// o3-mini supports key developer features, like Structured Outputs, function calling, and Batch API.
54+
///
55+
/// * Context window: 200,000
56+
/// * Max output tokens: 100,000
57+
public static let o3_mini: Model = "o3-mini"
58+
59+
/// o3-deep-research is the most advanced model for deep research, designed to tackle complex,
60+
/// multi-step research tasks.
61+
///
62+
/// It can search and synthesize information from across the internet as well as from your own data—brought in through MCP connectors.
63+
///
64+
/// * Context window: 200,000
65+
/// * Max output tokens: 100,000
66+
public static let o3_deep_research: Model = "o3-deep-research"
67+
68+
/// o4-mini is the latest small o-series model.
69+
///
70+
/// It's optimized for fast, effective reasoning with exceptionally efficient performance in
71+
/// coding and visual tasks.
72+
///
73+
/// * Context window: 200,000
74+
/// * Max output tokens: 100,000
75+
public static let o4_mini: Model = "o4-mini"
76+
77+
/// o4-mini-deep-research is a faster, more affordable deep research model—ideal for tackling
78+
/// complex, multi-step research tasks.
79+
///
80+
/// It can search and synthesize information from across the internet as well as from your own
81+
/// data, brought in through MCP connectors.
82+
///
83+
/// * Context window: 200,000
84+
/// * Max output tokens: 100,000
85+
public static let o4_mini_deep_research: Model = "o4-mini-deep-research"
86+
}
87+
1088
// MARK: - GPT-5
1189

1290
extension Model {

Sources/OpenAI/Responses/ResponsesBody.swift

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,13 @@
88
import Foundation
99

1010
public extension Responses {
11-
struct Body: Codable {
11+
struct Body: Encodable {
1212
/// Whether to run the model response in the background.
1313
public var background: Bool?
1414
/// Specify additional output data to include in the model response.
1515
public var include: [AdditionalOutput]?
16-
///
17-
public var input: String?
16+
/// Text, image, or file inputs to the model, used to generate a response.
17+
public var input: [Input]?
1818
/// A system (or developer) message inserted into the model's context.
1919
///
2020
/// When using along with `previous_response_id`, the instructions from a previous response
@@ -45,8 +45,8 @@ public extension Responses {
4545
public var parallelToolCalls: Bool?
4646
/// The unique ID of the previous response to the model. Use this to create multi-turn conversations.
4747
public var previousResponseId: String?
48-
///
49-
public var prompt: String?
48+
/// Reference to a prompt template and its variables.
49+
public var prompt: Prompt?
5050
/// Used by OpenAI to cache responses for similar requests to optimize your cache hit rates.
5151
public var promptCacheKey: String?
5252
///
@@ -122,5 +122,14 @@ public extension Responses {
122122
/// an organization is enrolled in the zero data retention program).
123123
case reasoningEncryptedContent = "reasoning.encrypted_content"
124124
}
125+
126+
public struct Input: Encodable, Sendable {
127+
/// The role of the message input. One of `user`, `assistant`, `system`, or `developer`.
128+
public let role: Role
129+
130+
/// Text, image, or audio input to the model, used to generate a response. Can also contain
131+
/// previous assistant responses.
132+
public let content: [Content]
133+
}
125134
}
126135
}

Sources/OpenAI/Responses/ResponsesWrapper.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,15 @@ public struct ResponsesWrapper {
1212
public func create(
1313
background: Bool? = nil,
1414
include: [Responses.Body.AdditionalOutput]? = nil,
15-
input: String? = nil,
15+
input: [Responses.Body.Input]? = nil,
1616
instructions: String? = nil,
1717
maxOutputTokens: Int? = nil,
1818
maxToolCalls: Int? = nil,
1919
metadata: [String : String]? = nil,
2020
model: Model? = nil,
2121
parallelToolCalls: Bool? = nil,
2222
previousResponseId: String? = nil,
23-
prompt: String? = nil,
23+
prompt: Prompt? = nil,
2424
promptCacheKey: String? = nil,
2525
reasoning: String? = nil,
2626
safetyIdentifier: String? = nil,
@@ -65,15 +65,15 @@ public struct ResponsesWrapper {
6565
public func createStream(
6666
background: Bool? = nil,
6767
include: [Responses.Body.AdditionalOutput]? = nil,
68-
input: String? = nil,
68+
input: [Responses.Body.Input]? = nil,
6969
instructions: String? = nil,
7070
maxOutputTokens: Int? = nil,
7171
maxToolCalls: Int? = nil,
7272
metadata: [String : String]? = nil,
7373
model: Model? = nil,
7474
parallelToolCalls: Bool? = nil,
7575
previousResponseId: String? = nil,
76-
prompt: String? = nil,
76+
prompt: Prompt? = nil,
7777
promptCacheKey: String? = nil,
7878
reasoning: String? = nil,
7979
safetyIdentifier: String? = nil,

0 commit comments

Comments
 (0)