1
1
# OpenAI Responses API
2
+ > Hand-crafted Swift SDK for the [ OpenAI Responses API] ( https://platform.openai.com/docs/api-reference/responses ) .
2
3
3
4
[ ![ Swift Version] ( https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2Fm1guelpf%2Fswift-openai-responses%2Fbadge%3Ftype%3Dswift-versions&color=brightgreen )] ( https://swiftpackageindex.com/m1guelpf/swift-openai-responses )
4
5
[ ![ GitHub license] ( https://img.shields.io/badge/license-MIT-blue.svg )] ( https://raw.githubusercontent.com/m1guelpf/swift-openai-responses/main/LICENSE )
5
6
6
- An unofficial Swift SDK for the [ OpenAI Responses API] ( https://platform.openai.com/docs/api-reference/responses ) .
7
+ This package contains:
8
+ - A fully typed client for the Responses API that _ feels_ Swifty
9
+ - ` Schemable ` and ` Tool ` macros, providing elegant ways to define tools and structured responses.
10
+ - A ` Conversation ` class, handling everything you need for multi-turn streaming conversations in your views.
11
+
7
12
8
13
## Installation
9
14
@@ -29,15 +34,15 @@ dependencies: [
29
34
- File > Swift Packages > Add Package Dependency
30
35
- Add https://github.com/m1guelpf/swift-openai-responses.git
31
36
- Select "Branch" with "main"
32
-
37
+
33
38
</details >
34
39
35
40
<details >
36
41
37
42
<summary >CocoaPods</summary >
38
43
39
44
Ask ChatGPT to help you migrate away from CocoaPods.
40
-
45
+
41
46
</details >
42
47
43
48
## Getting started 🚀
@@ -50,17 +55,17 @@ import SwiftUI
50
55
51
56
struct ContentView : View {
52
57
@State private var newMessage: String = " "
53
- @State private var conversation = Conversation (authToken : OPENAI_KEY, using : .gpt4o )
58
+ @State private var conversation = Conversation (authToken : OPENAI_KEY, using : .gpt5 )
54
59
55
60
var body: some View {
56
61
VStack (spacing : 0 ) {
57
62
ScrollView {
58
- VStack (spacing : 12 ) {
59
- ForEach (messages, id : \.self ) { message in
60
- MessageBubble (message : message)
61
- }
62
- }
63
- .padding ()
63
+ VStack (spacing : 12 ) {
64
+ ForEach (conversation. messages , id : \.self ) { message in
65
+ MessageBubble (message : message)
66
+ }
67
+ }
68
+ .padding ()
64
69
}
65
70
66
71
HStack (spacing : 12 ) {
@@ -92,10 +97,8 @@ struct ContentView: View {
92
97
func sendMessage () {
93
98
guard newMessage != " " else { return }
94
99
95
- Task {
96
- try await conversation.send (text : newMessage)
97
- newMessage = " "
98
- }
100
+ conversation.send (text : newMessage)
101
+ newMessage = " "
99
102
}
100
103
}
101
104
```
@@ -111,13 +114,13 @@ The Conversation class provides a high-level interface for managing a conversati
111
114
To create a ` Conversation ` instance, all you need is an OpenAI API key, and the model you will be talking to:
112
115
113
116
``` swift
114
- @State private var conversation = Conversation (authToken : OPENAI_API_KEY, using : .gpt4o )
117
+ @State private var conversation = Conversation (authToken : OPENAI_API_KEY, using : .gpt5 )
115
118
```
116
119
117
120
You can optionally provide a closure to configure the conversation, adding a system prompt or tools for the model to use:
118
121
119
122
``` swift
120
- @State private var conversation = Conversation (authToken : OPENAI_API_KEY, using : .gpt4o ) { config in
123
+ @State private var conversation = Conversation (authToken : OPENAI_API_KEY, using : .gpt5 ) { config in
121
124
// configure the model's behaviour
122
125
config.instructions = " You are a coding assistant that talks like a pirate"
123
126
@@ -143,25 +146,25 @@ conversation.truncation = .auto
143
146
Your ` Conversation ` instance contains various helpers to make communicating with the model easier. For example, you can send a simple text message like this:
144
147
145
148
``` swift
146
- try await conversation.send (text : " Hey!" )
149
+ conversation.send (text : " Hey!" )
147
150
```
148
151
149
152
There are also helpers for providing the output of a tool call or computer use call:
150
153
151
154
``` swift
152
- try await conversation.send (functionCallOutput : .init (callId : callId, output : " { ... }" ))
153
- try await conversation.send (computerCallOutput : .init (callId : callId, output : .screenshot (fileId : " ..." )))
155
+ conversation.send (functionCallOutput : .init (callId : callId, output : " { ... }" ))
156
+ conversation.send (computerCallOutput : .init (callId : callId, output : .screenshot (fileId : " ..." )))
154
157
```
155
158
156
159
For more complex use cases, you can construct the ` Input ` yourself:
157
160
158
161
``` swift
159
- try await conversation.send ( Input ([
160
- .message (content : Input. Content ( [
162
+ conversation.send ([
163
+ .message (content : [
161
164
.image (fileId : " ..." ),
162
165
.text (" Take a look at this image and tell me what you see" ),
163
- ])) ,
164
- ]))
166
+ ]),
167
+ ])
165
168
```
166
169
167
170
#### Reading messages
@@ -184,7 +187,6 @@ ScrollView {
184
187
}
185
188
```
186
189
187
-
188
190
### ` ResponsesAPI `
189
191
190
192
#### Creating a new instance
@@ -207,7 +209,7 @@ let client = ResponsesAPI(
207
209
208
210
For more advanced use cases like connecting to a custom server, you can customize the ` URLRequest ` used to connect to the API:
209
211
210
- ``` swift
212
+ ``` swift
211
213
let urlRequest = URLRequest (url : MY_CUSTOM_ENDPOINT)
212
214
urlRequest.addValue (" Bearer \( YOUR_API_KEY ) " , forHTTPHeaderField : " Authorization" )
213
215
@@ -220,7 +222,7 @@ To create a new response, call the `create` method with a `Request` instance:
220
222
221
223
``` swift
222
224
let response = try await client.create (Request (
223
- model : .gpt4o ,
225
+ model : .gpt5 ,
224
226
input : .text (" Are semicolons optional in JavaScript?" ),
225
227
instructions : " You are a coding assistant that talks like a pirate"
226
228
))
@@ -234,7 +236,7 @@ To stream back the response as it is generated, use the `stream` method:
234
236
235
237
``` swift
236
238
let stream = try await client.stream (Request (
237
- model : .gpt4o ,
239
+ model : .gpt5 ,
238
240
input : .text (" Are semicolons optional in JavaScript?" ),
239
241
instructions : " You are a coding assistant that talks like a pirate"
240
242
))
@@ -255,7 +257,7 @@ let file = try await client.upload(file: .file(name: "image.png", contents: imag
255
257
256
258
// then, use it on a message
257
259
try await client.create (Request (
258
- model : .gpt4o ,
260
+ model : .gpt5 ,
259
261
input : .message (content : [
260
262
.image (fileId : file.id ),
261
263
.text (" Take a look at this image and tell me what you see" ),
0 commit comments