@@ -15,7 +15,7 @@ function create_response(schema::TestEchoOpenAIResponseSchema, api_key::Abstract
1515end
1616
1717"""
18- create_response(schema::AbstractResponseSchema , api_key::AbstractString,
18+ create_response(schema::AbstractOpenAIResponseSchema , api_key::AbstractString,
1919 model::AbstractString,
2020 input;
2121 instructions::Union{Nothing, AbstractString} = nothing,
2929Creates a response using the OpenAI Responses API with streaming support.
3030
3131# Arguments
32- - `schema::AbstractResponseSchema `: The response schema to use
32+ - `schema::AbstractOpenAIResponseSchema `: The response schema to use
3333- `api_key::AbstractString`: The API key to use for the OpenAI API
3434- `model::AbstractString`: The model to use for generating the response
3535- `input`: The input for the model, can be a string or structured input
@@ -46,7 +46,7 @@ Creates a response using the OpenAI Responses API with streaming support.
4646# Returns
4747- `response`: The response from the OpenAI API
4848"""
49- function create_response (schema:: AbstractResponseSchema , api_key:: AbstractString ,
49+ function create_response (schema:: AbstractOpenAIResponseSchema , api_key:: AbstractString ,
5050 model:: AbstractString ,
5151 input;
5252 instructions:: Union{Nothing, AbstractString} = nothing ,
@@ -73,23 +73,19 @@ function create_response(schema::AbstractResponseSchema, api_key::AbstractString
7373 body[" stream" ] = true
7474 end
7575
76- # Add all parameters from api_kwargs
76+ # Add all parameters from api_kwargs (except url which is used for testing)
7777 # Supports: reasoning, text, temperature, max_output_tokens, etc.
7878 for (key, value) in pairs (api_kwargs)
79+ key == :url && continue # url is used for testing, not sent to API
7980 body[string (key)] = value
8081 end
8182
82- # Make the API request
83- url = OpenAI. build_url (OpenAI. DEFAULT_PROVIDER, " responses" )
83+ # Make the API request (url can be overridden via api_kwargs for testing)
84+ url = get (api_kwargs, :url , OpenAI. build_url (OpenAI. DEFAULT_PROVIDER, " responses" ) )
8485 headers = OpenAI. auth_header (OpenAI. DEFAULT_PROVIDER, api_key)
8586
8687 if ! isnothing (streamcallback)
87- # Streaming is not yet supported for the Responses API
88- # The Responses API uses a different SSE format than Chat Completions,
89- # requiring a dedicated ResponseStream flavor in StreamCallbacks.jl
90- throw (ArgumentError (" Streaming is not yet supported for OpenAI Responses API (OpenAIResponseSchema). Use non-streaming requests for now." ))
91-
92- # Configure streaming callback - only pass schema, no extra kwargs
88+ # Configure streaming callback
9389 streamcallback, stream_kwargs = configure_callback! (streamcallback, schema)
9490
9591 # Convert body dict to IOBuffer for streaming (streamed_request! expects IOBuffer)
@@ -99,7 +95,10 @@ function create_response(schema::AbstractResponseSchema, api_key::AbstractString
9995
10096 # Use streaming request
10197 resp = streamed_request! (streamcallback, url, headers, input; http_kwargs... )
102- return OpenAI. OpenAIResponse (resp. status, JSON3. read (resp. body))
98+
99+ # Build response body from chunks using StreamCallbacks
100+ response_body = build_response_body (streamcallback. flavor, streamcallback)
101+ return OpenAI. OpenAIResponse (resp. status, response_body)
103102 else
104103 # Convert the body to JSON for non-streaming
105104 json_body = JSON3. write (body)
@@ -111,7 +110,7 @@ function create_response(schema::AbstractResponseSchema, api_key::AbstractString
111110end
112111
113112"""
114- render(schema::AbstractResponseSchema , messages::Vector{<:AbstractMessage};
113+ render(schema::AbstractOpenAIResponseSchema , messages::Vector{<:AbstractMessage};
115114 conversation::AbstractVector{<:AbstractMessage} = AbstractMessage[],
116115 no_system_message::Bool = false,
117116 kwargs...)
@@ -124,7 +123,7 @@ The Responses API expects:
124123- `instructions`: System-level instructions (from SystemMessage, optional)
125124
126125# Arguments
127- - `schema::AbstractResponseSchema `: The response schema
126+ - `schema::AbstractOpenAIResponseSchema `: The response schema
128127- `messages::Vector{<:AbstractMessage}`: Messages to render
129128- `conversation`: Previous conversation history (currently limited support)
130129- `no_system_message`: If true, don't add default system message
@@ -133,7 +132,7 @@ The Responses API expects:
133132# Returns
134133- `NamedTuple{(:input, :instructions), Tuple{String, Union{Nothing, String}}}`: Rendered input and instructions
135134"""
136- function render (schema:: AbstractResponseSchema ,
135+ function render (schema:: AbstractOpenAIResponseSchema ,
137136 messages:: Vector{<:AbstractMessage} ;
138137 conversation:: AbstractVector{<:AbstractMessage} = AbstractMessage[],
139138 no_system_message:: Bool = false ,
@@ -165,23 +164,23 @@ function render(schema::AbstractResponseSchema,
165164end
166165
167166# Render for string prompts - wrap in UserMessage and process
168- function render (schema:: AbstractResponseSchema , prompt:: AbstractString ;
167+ function render (schema:: AbstractOpenAIResponseSchema , prompt:: AbstractString ;
169168 no_system_message:: Bool = true , kwargs... )
170169 render (schema, [UserMessage (prompt)]; no_system_message, kwargs... )
171170end
172171
173172# Render for single message
174- function render (schema:: AbstractResponseSchema , msg:: AbstractMessage ; kwargs... )
173+ function render (schema:: AbstractOpenAIResponseSchema , msg:: AbstractMessage ; kwargs... )
175174 render (schema, [msg]; kwargs... )
176175end
177176
178177# Render for AITemplate
179- function render (schema:: AbstractResponseSchema , template:: AITemplate ; kwargs... )
178+ function render (schema:: AbstractOpenAIResponseSchema , template:: AITemplate ; kwargs... )
180179 render (schema, render (template); kwargs... )
181180end
182181
183182# Render for Symbol (template name)
184- function render (schema:: AbstractResponseSchema , template:: Symbol ; kwargs... )
183+ function render (schema:: AbstractOpenAIResponseSchema , template:: Symbol ; kwargs... )
185184 render (schema, AITemplate (template); kwargs... )
186185end
187186
@@ -225,7 +224,7 @@ function extract_response_content(response)
225224end
226225
227226"""
228- aigenerate(schema::AbstractResponseSchema , prompt::ALLOWED_PROMPT_TYPE;
227+ aigenerate(schema::AbstractOpenAIResponseSchema , prompt::ALLOWED_PROMPT_TYPE;
229228 previous_response_id::Union{Nothing, AbstractString} = nothing,
230229 enable_websearch::Bool = false,
231230 model::AbstractString = MODEL_CHAT,
@@ -238,7 +237,7 @@ Generate an AI response using the OpenAI Responses API with streaming support.
238237Returns an AIMessage with the response content and additional information in the extras field.
239238
240239# Arguments
241- - `schema::AbstractResponseSchema `: The schema to use (e.g., `OpenAIResponseSchema()`)
240+ - `schema::AbstractOpenAIResponseSchema `: The schema to use (e.g., `OpenAIResponseSchema()`)
242241- `prompt`: The prompt to send to the API, can be:
243242 - A string (sent as user input)
244243 - A vector of AbstractMessages (SystemMessage becomes instructions, UserMessage becomes input)
@@ -285,7 +284,7 @@ response = aigenerate(schema, "Solve 2+2*3";
285284println(response.extras[:reasoning_content])
286285```
287286"""
288- function aigenerate (schema:: AbstractResponseSchema , prompt:: ALLOWED_PROMPT_TYPE ;
287+ function aigenerate (schema:: AbstractOpenAIResponseSchema , prompt:: ALLOWED_PROMPT_TYPE ;
289288 previous_response_id:: Union{Nothing, AbstractString} = nothing ,
290289 enable_websearch:: Bool = false ,
291290 model:: AbstractString = MODEL_CHAT,
@@ -367,7 +366,7 @@ function aigenerate(schema::AbstractResponseSchema, prompt::ALLOWED_PROMPT_TYPE;
367366end
368367
369368"""
370- aiextract(schema::AbstractResponseSchema , prompt::ALLOWED_PROMPT_TYPE;
369+ aiextract(schema::AbstractOpenAIResponseSchema , prompt::ALLOWED_PROMPT_TYPE;
371370 return_type::Union{Type, AbstractTool},
372371 model::AbstractString = MODEL_CHAT,
373372 api_key::AbstractString = "",
@@ -383,7 +382,7 @@ Note: Unlike the Chat Completions API, the Responses API `text.format` only supp
383382JSON schema. For multi-type extraction (union of structs), use the Chat Completions API instead.
384383
385384# Arguments
386- - `schema::AbstractResponseSchema `: The schema to use
385+ - `schema::AbstractOpenAIResponseSchema `: The schema to use
387386- `prompt`: The input prompt
388387- `return_type`: A Julia struct type or AbstractTool to extract (single type only)
389388- `model`: The model to use
@@ -424,7 +423,7 @@ result = aiextract(schema, "Solve: What is 15% of 80?";
424423println(result.extras[:reasoning_content])
425424```
426425"""
427- function aiextract (schema:: AbstractResponseSchema , prompt:: ALLOWED_PROMPT_TYPE ;
426+ function aiextract (schema:: AbstractOpenAIResponseSchema , prompt:: ALLOWED_PROMPT_TYPE ;
428427 return_type:: Union{Type, AbstractTool} ,
429428 model:: AbstractString = MODEL_CHAT,
430429 api_key:: AbstractString = " " ,
0 commit comments