Skip to content

Commit 96fcb2f

Browse files
committed
Added new Responses API
1 parent bc189bb commit 96fcb2f

8 files changed

+955
-0
lines changed

README.md

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ Stream text with GPT-4, transcribe and translate audio with Whisper, or create i
3737
- [Streaming Chat](#streaming-chat)
3838
- [Vision](#vision)
3939
- [JSON Mode](#json-mode)
40+
- [Responses API](#responses-api)
4041
- [Functions](#functions)
4142
- [Completions](#completions)
4243
- [Embeddings](#embeddings)
@@ -441,6 +442,74 @@ You can stream it as well!
441442
# }
442443
```
443444

445+
### Responses API
446+
OpenAI's most advanced interface for generating model responses. Supports text and image inputs, and text outputs. Create stateful interactions with the model, using the output of previous responses as input. Extend the model's capabilities with built-in tools for file search, web search, computer use, and more. Allow the model access to external systems and data using function calling.
447+
448+
```ruby
449+
response = client.responses(parameters: {
450+
model: "gpt-4o",
451+
input: "Hello!"
452+
})
453+
454+
puts response.dig("output", 0, "content", 0, "text")
455+
```
456+
#### Follow-up Messages (former threads functionality available in the Assistant API)
457+
```ruby
458+
followup = client.responses(parameters: {
459+
model: "gpt-4o",
460+
input: "Remind me, what is my name?",
461+
previous_response_id: response["id"]
462+
})
463+
464+
puts followup.dig("output", 0, "content", 0, "text")
465+
```
466+
467+
#### Tool Calls
468+
```ruby
469+
response = client.responses(parameters: {
470+
model: "gpt-4o",
471+
input: "What's the weather in Paris?",
472+
tools: [
473+
{
474+
"type" => "function",
475+
"name" => "get_current_weather",
476+
"description" => "Get the current weather in a given location",
477+
"parameters" => {
478+
"type" => "object",
479+
"properties" => {
480+
"location" => {
481+
"type" => "string",
482+
"description" => "The geographic location to get the weather for"
483+
}
484+
},
485+
"required" => ["location"]
486+
}
487+
}
488+
]
489+
})
490+
491+
puts response.dig("output", 0, "name") # => "get_current_weather"
492+
```
493+
494+
#### Streaming
495+
```ruby
496+
chunks = []
497+
streamer = proc { |chunk, _| chunks << chunk }
498+
499+
client.responses(parameters: {
500+
model: "gpt-4o",
501+
input: "Hello!",
502+
stream: streamer
503+
})
504+
505+
output = chunks
506+
.select { |c| c["type"] == "response.output_text.delta" }
507+
.map { |c| c["delta"] }
508+
.join
509+
510+
puts output
511+
```
512+
444513
### Functions
445514

446515
You can describe and pass in functions and the model will intelligently choose to output a JSON object containing arguments to call them - eg., to use your method `get_current_weather` to get the weather in a given location. Note that tool_choice is optional, but if you exclude it, the model will choose whether to use the function or not ([see here](https://platform.openai.com/docs/api-reference/chat/create#chat-create-tool_choice)).

lib/openai/client.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ def completions(parameters: {})
3232
json_post(path: "/completions", parameters: parameters)
3333
end
3434

35+
def responses(parameters: {})
36+
json_post(path: "/responses", parameters: parameters)
37+
end
38+
3539
def audio
3640
@audio ||= OpenAI::Audio.new(client: self)
3741
end

spec/fixtures/cassettes/gpt-4o_responsesapi_responses.yml

Lines changed: 119 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
---
2+
http_interactions:
3+
- request:
4+
method: post
5+
uri: https://api.openai.com/v1/responses
6+
body:
7+
encoding: UTF-8
8+
string: '{"model":"gpt-4o","input":"Hello!","stream":true}'
9+
headers:
10+
Content-Type:
11+
- application/json
12+
Authorization:
13+
- Bearer <OPENAI_ACCESS_TOKEN>
14+
Accept-Encoding:
15+
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
16+
Accept:
17+
- "*/*"
18+
User-Agent:
19+
- Ruby
20+
response:
21+
status:
22+
code: 200
23+
message: OK
24+
headers:
25+
Date:
26+
- Wed, 12 Mar 2025 16:59:40 GMT
27+
Content-Type:
28+
- text/event-stream; charset=utf-8
29+
Transfer-Encoding:
30+
- chunked
31+
Connection:
32+
- keep-alive
33+
Openai-Version:
34+
- '2020-10-01'
35+
Openai-Organization:
36+
- tropic-7
37+
X-Request-Id:
38+
- req_fa50380d9311693c3f763a22b24eee77
39+
Openai-Processing-Ms:
40+
- '51'
41+
Strict-Transport-Security:
42+
- max-age=31536000; includeSubDomains; preload
43+
Cf-Cache-Status:
44+
- DYNAMIC
45+
Set-Cookie:
46+
- __cf_bm=IY3ThYrVK7alqLEMbB1twLEG88Bef1OUz6pWWgkYrfE-1741798780-1.0.1.1-s5avIb8RUXCHgZmfvWToJkH_uELi5H6BS0QtoSVSISmg9.RBA7Z97ySYNXZ6Czt7RZnT.K6Pj9W5u3NDNf6u4rroFm_BAWRyUaZUHgbnkR0;
47+
path=/; expires=Wed, 12-Mar-25 17:29:40 GMT; domain=.api.openai.com; HttpOnly;
48+
Secure; SameSite=None
49+
- _cfuvid=tjwk_Z09jnlOWbISJrfgtJrv.wn3k_50UJ9uEAnlEU0-1741798780709-0.0.1.1-604800000;
50+
path=/; domain=.api.openai.com; HttpOnly; Secure; SameSite=None
51+
X-Content-Type-Options:
52+
- nosniff
53+
Server:
54+
- cloudflare
55+
Cf-Ray:
56+
- 91f4d7e9c902b1b8-WAW
57+
Alt-Svc:
58+
- h3=":443"; ma=86400
59+
body:
60+
encoding: UTF-8
61+
string: |+
62+
event: response.created
63+
data: {"type":"response.created","response":{"id":"resp_67d1bd7c931c8191870ad798c711562004d0a3fcf4e20298","object":"response","created_at":1741798780,"status":"in_progress","error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"model":"gpt-4o-2024-08-06","output":[],"parallel_tool_calls":true,"previous_response_id":null,"reasoning":{"effort":null,"generate_summary":null},"store":true,"temperature":1.0,"text":{"format":{"type":"text"}},"tool_choice":"auto","tools":[],"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}}
64+
65+
event: response.in_progress
66+
data: {"type":"response.in_progress","response":{"id":"resp_67d1bd7c931c8191870ad798c711562004d0a3fcf4e20298","object":"response","created_at":1741798780,"status":"in_progress","error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"model":"gpt-4o-2024-08-06","output":[],"parallel_tool_calls":true,"previous_response_id":null,"reasoning":{"effort":null,"generate_summary":null},"store":true,"temperature":1.0,"text":{"format":{"type":"text"}},"tool_choice":"auto","tools":[],"top_p":1.0,"truncation":"disabled","usage":null,"user":null,"metadata":{}}}
67+
68+
event: response.output_item.added
69+
data: {"type":"response.output_item.added","output_index":0,"item":{"type":"message","id":"msg_67d1bd7ce24c819188993565819babf404d0a3fcf4e20298","status":"in_progress","role":"assistant","content":[]}}
70+
71+
event: response.content_part.added
72+
data: {"type":"response.content_part.added","item_id":"msg_67d1bd7ce24c819188993565819babf404d0a3fcf4e20298","output_index":0,"content_index":0,"part":{"type":"output_text","text":"","annotations":[]}}
73+
74+
event: response.output_text.delta
75+
data: {"type":"response.output_text.delta","item_id":"msg_67d1bd7ce24c819188993565819babf404d0a3fcf4e20298","output_index":0,"content_index":0,"delta":"Hi"}
76+
77+
event: response.output_text.delta
78+
data: {"type":"response.output_text.delta","item_id":"msg_67d1bd7ce24c819188993565819babf404d0a3fcf4e20298","output_index":0,"content_index":0,"delta":" there"}
79+
80+
event: response.output_text.delta
81+
data: {"type":"response.output_text.delta","item_id":"msg_67d1bd7ce24c819188993565819babf404d0a3fcf4e20298","output_index":0,"content_index":0,"delta":"!"}
82+
83+
event: response.output_text.delta
84+
data: {"type":"response.output_text.delta","item_id":"msg_67d1bd7ce24c819188993565819babf404d0a3fcf4e20298","output_index":0,"content_index":0,"delta":" How"}
85+
86+
event: response.output_text.delta
87+
data: {"type":"response.output_text.delta","item_id":"msg_67d1bd7ce24c819188993565819babf404d0a3fcf4e20298","output_index":0,"content_index":0,"delta":" can"}
88+
89+
event: response.output_text.delta
90+
data: {"type":"response.output_text.delta","item_id":"msg_67d1bd7ce24c819188993565819babf404d0a3fcf4e20298","output_index":0,"content_index":0,"delta":" I"}
91+
92+
event: response.output_text.delta
93+
data: {"type":"response.output_text.delta","item_id":"msg_67d1bd7ce24c819188993565819babf404d0a3fcf4e20298","output_index":0,"content_index":0,"delta":" assist"}
94+
95+
event: response.output_text.delta
96+
data: {"type":"response.output_text.delta","item_id":"msg_67d1bd7ce24c819188993565819babf404d0a3fcf4e20298","output_index":0,"content_index":0,"delta":" you"}
97+
98+
event: response.output_text.delta
99+
data: {"type":"response.output_text.delta","item_id":"msg_67d1bd7ce24c819188993565819babf404d0a3fcf4e20298","output_index":0,"content_index":0,"delta":" today"}
100+
101+
event: response.output_text.delta
102+
data: {"type":"response.output_text.delta","item_id":"msg_67d1bd7ce24c819188993565819babf404d0a3fcf4e20298","output_index":0,"content_index":0,"delta":"?"}
103+
104+
event: response.output_text.done
105+
data: {"type":"response.output_text.done","item_id":"msg_67d1bd7ce24c819188993565819babf404d0a3fcf4e20298","output_index":0,"content_index":0,"text":"Hi there! How can I assist you today?"}
106+
107+
event: response.content_part.done
108+
data: {"type":"response.content_part.done","item_id":"msg_67d1bd7ce24c819188993565819babf404d0a3fcf4e20298","output_index":0,"content_index":0,"part":{"type":"output_text","text":"Hi there! How can I assist you today?","annotations":[]}}
109+
110+
event: response.output_item.done
111+
data: {"type":"response.output_item.done","output_index":0,"item":{"type":"message","id":"msg_67d1bd7ce24c819188993565819babf404d0a3fcf4e20298","status":"completed","role":"assistant","content":[{"type":"output_text","text":"Hi there! How can I assist you today?","annotations":[]}]}}
112+
113+
event: response.completed
114+
data: {"type":"response.completed","response":{"id":"resp_67d1bd7c931c8191870ad798c711562004d0a3fcf4e20298","object":"response","created_at":1741798780,"status":"completed","error":null,"incomplete_details":null,"instructions":null,"max_output_tokens":null,"model":"gpt-4o-2024-08-06","output":[{"type":"message","id":"msg_67d1bd7ce24c819188993565819babf404d0a3fcf4e20298","status":"completed","role":"assistant","content":[{"type":"output_text","text":"Hi there! How can I assist you today?","annotations":[]}]}],"parallel_tool_calls":true,"previous_response_id":null,"reasoning":{"effort":null,"generate_summary":null},"store":true,"temperature":1.0,"text":{"format":{"type":"text"}},"tool_choice":"auto","tools":[],"top_p":1.0,"truncation":"disabled","usage":{"input_tokens":27,"input_tokens_details":{"cached_tokens":0},"output_tokens":11,"output_tokens_details":{"reasoning_tokens":0},"total_tokens":38},"user":null,"metadata":{}}}
115+
116+
recorded_at: Wed, 12 Mar 2025 16:59:41 GMT
117+
recorded_with: VCR 6.1.0
118+
...

0 commit comments

Comments
 (0)