Skip to content

Commit 69e4551

Browse files
committed
Improved Responses output
1 parent 5202209 commit 69e4551

1 file changed

Lines changed: 138 additions & 6 deletions

File tree

Sources/OpenAI/Responses/ResponsesResponse.swift

Lines changed: 138 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -90,8 +90,8 @@ public extension Responses {
9090
/// items in the `output` array, if any are present.
9191
public var outputText: String? {
9292
output.reduce(into: "") { partialResult, output in
93-
if output.type == "message" {
94-
partialResult += output.content.reduce(into: "") { contentPartialResult, content in
93+
if case let .message(message) = output {
94+
partialResult += message.content.reduce(into: "") { contentPartialResult, content in
9595
if content.type == "output_text" {
9696
contentPartialResult += content.text ?? ""
9797
}
@@ -104,19 +104,151 @@ public extension Responses {
104104
public let reason: String
105105
}
106106

107-
public struct Output: Decodable, Sendable {
108-
public let id: String
109-
public let type: String
110-
public let status: String
107+
public enum OutputType: String, Decodable, Sendable {
108+
case message
109+
case fileSearchCall = "file_search_call"
110+
case functionCall = "function_call"
111+
case webSearchCall = "web_search_call"
112+
case computerCall = "computer_call"
113+
case reasoning
114+
case imageGenerationCall = "image_generation_call"
115+
case codeInterpreterCall = "code_interpreter_call"
116+
case localShellCall = "local_shell_call"
117+
case mcpCall = "mcp_call"
118+
}
119+
120+
public enum Output: Decodable, Sendable {
121+
case message(MessageOutput)
122+
case fileSearchCall(FileSearchCallOutput)
123+
case reasoning(ReasoningOutput)
124+
125+
enum CodingKeys: String, CodingKey {
126+
case type
127+
}
128+
129+
public init(from decoder: any Decoder) throws {
130+
let container = try decoder.container(keyedBy: CodingKeys.self)
131+
let type = try container.decode(OutputType.self, forKey: .type)
132+
switch type {
133+
case .message:
134+
let innerContainer = try decoder.singleValueContainer()
135+
let message = try innerContainer.decode(MessageOutput.self)
136+
self = .message(message)
137+
case .fileSearchCall:
138+
let innerContainer = try decoder.singleValueContainer()
139+
let fileSearchCall = try innerContainer.decode(FileSearchCallOutput.self)
140+
self = .fileSearchCall(fileSearchCall)
141+
case .reasoning:
142+
let innerContainer = try decoder.singleValueContainer()
143+
let reasoning = try innerContainer.decode(ReasoningOutput.self)
144+
self = .reasoning(reasoning)
145+
default:
146+
throw OpenAIError.incompatibleModel
147+
}
148+
}
149+
}
150+
151+
/// An output message from the model.
152+
public struct MessageOutput: Decodable, Sendable {
153+
/// The content of the output message.
111154
public let content: [Content]
155+
156+
/// The unique ID of the output message.
157+
public let id: String
158+
159+
/// The role of the output message. Always `assistant`.
112160
public let role: Role
113161

162+
/// The status of the message input. One of `in_progress`, `completed`, or `incomplete`.
163+
///
164+
/// Populated when input items are returned via API.
165+
public let status: String
166+
114167
public struct Content: Decodable, Sendable {
115168
public let type: String
116169
public let text: String?
117170
}
118171
}
119172

173+
/// The results of a file search tool call.
174+
public struct FileSearchCallOutput: Decodable, Sendable {
175+
/// The unique ID of the file search tool call.
176+
public let id: String
177+
178+
/// The queries used to search for files.
179+
public let queries: [String]
180+
181+
/// The results of the file search tool call.
182+
public let results: [Result]?
183+
184+
/// The status of the file search tool call. One of `in_progress`, `searching`,
185+
/// `incomplete` or `failed`,
186+
public let status: String
187+
188+
public struct Result: Decodable, Sendable {
189+
/// Set of 16 key-value pairs that can be attached to an object.
190+
///
191+
/// This can be useful for storing additional information about the object in a
192+
/// structured format, and querying for objects via API or the dashboard. Keys are
193+
/// strings with a maximum length of 64 characters. Values are strings with a
194+
/// maximum length of 512 characters, booleans, or numbers.
195+
public let attributes: [String: String]
196+
197+
/// The unique ID of the file.
198+
public let fileId: String
199+
200+
/// The name of the file.
201+
public let filename: String
202+
203+
/// The relevance score of the file - a value between 0 and 1.
204+
public let score: Double
205+
206+
/// The text that was retrieved from the file.
207+
public let text: String
208+
}
209+
}
210+
211+
/// A description of the chain of thought used by a reasoning model while generating a
212+
/// response.
213+
///
214+
/// Be sure to include these items in your input to the Responses API for subsequent
215+
/// turns of a conversation if you are manually managing context.
216+
public struct ReasoningOutput: Decodable, Sendable {
217+
/// Reasoning text content.
218+
public let content: [Content]
219+
220+
/// The encrypted content of the reasoning item - populated when a response is
221+
/// generated with `reasoning.encrypted_content` in the `include` parameter.
222+
public let encryptedContent: String?
223+
224+
/// The unique identifier of the reasoning content.
225+
public let id: String
226+
227+
/// The status of the item. One of `in_progress`, `completed`, or `incomplete`.
228+
///
229+
/// Populated when items are returned via API.
230+
public let status: String
231+
232+
/// Reasoning summary content.
233+
public let summary: [Summary]
234+
235+
public struct Content: Decodable, Sendable {
236+
/// Reasoning text output from the model.
237+
public let text: String
238+
239+
/// The type of the object. Always `reasoning_text`.
240+
public let type: String
241+
}
242+
243+
public struct Summary: Decodable, Sendable {
244+
/// A summary of the reasoning output from the model so far.
245+
public let text: String
246+
247+
/// The type of the object. Always `summary_text`.
248+
public let type: String
249+
}
250+
}
251+
120252
public struct Usage: Decodable, Sendable {
121253
public let inputTokens: Int
122254
public let inputTokensDetails: InputTokensDetails

0 commit comments

Comments
 (0)