SpyBara
Go Premium

Documentation 2026-10-31 23:01 UTC to 2026-11-01 23:00 UTC

40 files changed +726 −247. View all changes and history on the product overview
2026
Fri 13 23:58 Thu 12 22:57 Wed 11 23:57 Tue 10 23:02 Mon 9 23:02 Sun 8 22:59 Sat 7 22:59 Fri 6 23:00 Thu 5 23:00 Wed 4 22:58 Tue 3 22:58 Mon 2 23:58 Sun 1 23:00
Details

745 745 

746@app.post("/messages")746@app.post("/messages")

747async def message(message: Message):747async def message(message: Message):

748 if not message.session_id.strip() or not message.content.strip():

749 raise HTTPException(

750 status_code=400, detail="session_id and content are required"

751 )

748 conversation_id = conversations_by_session.get(message.session_id)752 conversation_id = conversations_by_session.get(message.session_id)

749 if conversation_id is None:753 if conversation_id is None:

750 conversation_id = openai.conversations.create().id754 conversation_id = openai.conversations.create().id

Details

200 notification_channel={200 notification_channel={

201 "recipients": ["billing@example.com"],201 "recipients": ["billing@example.com"],

202 "type": "email",202 "type": "email",

203 "subject_prefix": "[OpenAI spend]",203 "subject_prefix": "OpenAI spend",

204 },204 },

205 threshold_amount=50000,205 threshold_amount=50000,

206)206)

Details

309# Replace the illustrative IDs and URLs below with your own resource values.309# Replace the illustrative IDs and URLs below with your own resource values.

310from openai import OpenAI310from openai import OpenAI

311 311 

312client = OpenAI()

313 312 

314session_id = "sess_123"313def find_turn(client, session_id, turn_id):

315turns = client.beta.agents.sessions.turns.list(session_id, limit=20, order="desc")314 # Native SDK pagination searches every page for the owning agent.

316print(turns.to_json())315 for turn in client.beta.agents.sessions.turns.list(session_id, limit=100):

317turn_id = "turn_123"316 if turn.id == turn_id:

318turn = client.beta.agents.sessions.turns.retrieve(turn_id, session_id=session_id)317 return client.beta.agents.sessions.turns.retrieve(

319print(turn.subagent_id)318 turn_id, session_id=session_id

319 )

320 

321 for subagent in client.beta.agents.sessions.subagents.list(session_id, limit=100):

322 turns = client.beta.agents.sessions.subagents.turns.list(

323 subagent.id, session_id=session_id, limit=100

324 )

325 for turn in turns:

326 if turn.id == turn_id:

327 return client.beta.agents.sessions.subagents.turns.retrieve(

328 turn_id, session_id=session_id, subagent_id=subagent.id

329 )

330 raise ValueError(f"Turn {turn_id} not found in session {session_id}")

331 

332 

333turn = find_turn(OpenAI(), "sess_123", "turn_123")

334print(turn.subagent_id or "main agent")

320```335```

321 336 

322```go337```go

Details

90)90)

91 91 

92 92 

93@input_guardrail93# Validate input before starting the support agent.

94@input_guardrail(run_in_parallel=False)

94async def math_guardrail(95async def math_guardrail(

95 ctx: RunContextWrapper[None],96 ctx: RunContextWrapper[None],

96 agent: Agent,97 agent: Agent,


176 177 

177agent = Agent(178agent = Agent(

178 name="Support agent",179 name="Support agent",

179 instructions="Handle support requests and ask for approval when needed.",180 instructions="Use cancel_order to handle cancellation requests.",

180 tools=[cancel_order],181 tools=[cancel_order],

181)182)

182 183 


187 if result.interruptions:188 if result.interruptions:

188 state = result.to_state()189 state = result.to_state()

189 for interruption in result.interruptions:190 for interruption in result.interruptions:

191 print("Approval required:", interruption.name)

190 state.approve(interruption)192 state.approve(interruption)

191 result = await Runner.run(agent, state)193 result = await Runner.run(agent, state)

192 194 

Details

433docker_run_config = RunConfig(433docker_run_config = RunConfig(

434 sandbox=SandboxRunConfig(434 sandbox=SandboxRunConfig(

435 client=DockerSandboxClient(docker_from_env()),435 client=DockerSandboxClient(docker_from_env()),

436 options=DockerSandboxClientOptions(image=DEFAULT_PYTHON_SANDBOX_IMAGE),436 options=DockerSandboxClientOptions(

437 image=DEFAULT_PYTHON_SANDBOX_IMAGE,

438 network_mode="none",

439 ),

437 ),440 ),

438 workflow_name="Docker sandbox review",441 workflow_name="Docker sandbox review",

439)442)


443 "Summarize the renewal blockers and recommend the next two actions.",446 "Summarize the renewal blockers and recommend the next two actions.",

444 run_config=docker_run_config,447 run_config=docker_run_config,

445)448)

449 

450print(result.final_output)

446```451```

447 452 

448 453 


548async with session:553async with session:

549 first_result = await Runner.run(554 first_result = await Runner.run(

550 agent,555 agent,

551 "Build the first version of the app.",556 "Create app.py with an add(a, b) function that returns their sum. "

557 "Run it once to check that add(2, 3) equals 5.",

552 max_turns=20,558 max_turns=20,

553 run_config=RunConfig(559 run_config=RunConfig(

554 sandbox=SandboxRunConfig(session=session),560 sandbox=SandboxRunConfig(session=session),


564conversation.append(570conversation.append(

565 {571 {

566 "role": "user",572 "role": "user",

567 "content": "Continue from the existing workspace and add tests.",573 "content": (

574 "Read the existing app.py without replacing it. Add test_app.py with "

575 "two unittest tests: one for positive inputs and one for negative "

576 "inputs. Run both tests."

577 ),

568 }578 }

569)579)

570 580 


582 )592 )

583finally:593finally:

584 await client.delete(resumed_session)594 await client.delete(resumed_session)

595 

596print(second_result.final_output)

585```597```

586 598 

587 599 

Details

260 260 

261completion = client.chat.completions.create(261completion = client.chat.completions.create(

262 model="gpt-audio-1.5",262 model="gpt-audio-1.5",

263 store=False,

263 modalities=["text", "audio"],264 modalities=["text", "audio"],

264 audio={"voice": "alloy", "format": "wav"},265 audio={"voice": "alloy", "format": "wav"},

265 messages=[266 messages=[

Details

469)469)

470 470 

471cursor = None471cursor = None

472response_id = None

472for event in stream:473for event in stream:

473 print(event)474 print(event)

475 if event.type == "response.created":

476 response_id = event.response.id

477 # Keepalives use connection counters, not stored-event resume positions.

478 if event.type != "keepalive":

474 cursor = event.sequence_number479 cursor = event.sequence_number

475 480 

476# If your connection drops, the response continues running and you can reconnect:481 # If your connection drops, the response continues running and you can reconnect:

477# SDK support for resuming the stream is coming soon.482 # with client.responses.stream(response_id=response_id, starting_after=cursor) as resumed:

478# for event in client.responses.stream(resp.id, starting_after=cursor):483 # for event in resumed:

479# print(event)484 # print(event)

485 if event.type == "response.created":

486 response_id = event.response.id

480```487```

481 488 

482```go489```go

Details

54 await self.store.add_thread_item(54 await self.store.add_thread_item(

55 thread.id,55 thread.id,

56 HiddenContextItem(56 HiddenContextItem(

57 id="item_123",57 id=self.store.generate_item_id("message", thread, context),

58 thread_id=thread.id,58 thread_id=thread.id,

59 created_at=datetime.now(),59 created_at=datetime.now(),

60 content="<USER_ACTION>The user did a thing</USER_ACTION>",60 content="<USER_ACTION>The user did a thing</USER_ACTION>",


175```python175```python

176form = Form(176form = Form(

177 direction="col",177 direction="col",

178 validation="native",

179 onSubmitAction=ActionConfig(178 onSubmitAction=ActionConfig(

180 type="update_todo",179 type="update_todo",

181 payload={"id": todo.id},180 payload={"id": todo.id},

Details

114 114 

115 conversation.extend(response.output)115 conversation.extend(response.output)

116 116 

117 try:

118 next_input = get_next_user_input()

119 except EOFError:

120 break

117 conversation.append(121 conversation.append(

118 {122 {

119 "type": "message",123 "type": "message",

120 "role": "user",124 "role": "user",

121 "content": get_next_user_input(),125 "content": next_input,

122 }126 }

123 )127 )

124```128```

Details

252 Questions: []openai.DecisionNewParamsQuestionUnion{{252 Questions: []openai.DecisionNewParamsQuestionUnion{{

253 OfPredicate: &openai.DecisionNewParamsQuestionPredicate{253 OfPredicate: &openai.DecisionNewParamsQuestionPredicate{

254 Name: openai.String("visible_damage"),254 Name: openai.String("visible_damage"),

255 Instructions: "Does the product have visible damage, such as a crack, tear, or dent? Ignore shadows and damage to the packaging.",255 Instructions: openai.DecisionNewParamsQuestionPredicateInstructionsUnion{

256 OfString: openai.String("Does the product have visible damage, such as a crack, tear, or dent? Ignore shadows and damage to the packaging."),

257 },

256 },258 },

257 }},259 }},

258 })260 })


273```java275```java

274import com.openai.models.decisions.DecisionCreateParams;276import com.openai.models.decisions.DecisionCreateParams;

275import com.openai.models.decisions.DecisionInputImage;277import com.openai.models.decisions.DecisionInputImage;

278import com.openai.models.decisions.DecisionInputItem;

276import com.openai.models.decisions.DecisionInputMessage;279import com.openai.models.decisions.DecisionInputMessage;

277import com.openai.models.decisions.DecisionInputPart;280import com.openai.models.decisions.DecisionInputPart;

278import com.openai.models.decisions.DecisionInputText;281import com.openai.models.decisions.DecisionInputText;


284String imageBase64 =287String imageBase64 =

285 Base64.getEncoder().encodeToString(Files.readAllBytes(Path.of("product.png")));288 Base64.getEncoder().encodeToString(Files.readAllBytes(Path.of("product.png")));

286var message =289var message =

287 DecisionInputMessage.builder()290 DecisionInputMessage.User.builder()

288 .contentOfParts(291 .contentOfParts(

289 List.of(292 List.of(

290 DecisionInputPart.ofInputText(293 DecisionInputPart.ofInputText(


302 .create(305 .create(

303 DecisionCreateParams.builder()306 DecisionCreateParams.builder()

304 .model("gpt-6-luna")307 .model("gpt-6-luna")

305 .inputOfDecisionInputMessages(List.of(message))308 .inputOfDecisionInputItems(

309 List.of(

310 DecisionInputItem.ofDecisionInputMessage(

311 DecisionInputMessage.ofUser(message))))

306 .addQuestion(312 .addQuestion(

307 DecisionCreateParams.Question.Predicate.builder()313 DecisionCreateParams.Question.Predicate.builder()

308 .name("visible_damage")314 .name("visible_damage")


542 Questions: []openai.DecisionNewParamsQuestionUnion{{548 Questions: []openai.DecisionNewParamsQuestionUnion{{

543 OfChoice: &openai.DecisionNewParamsQuestionChoice{549 OfChoice: &openai.DecisionNewParamsQuestionChoice{

544 Name: openai.String("department"),550 Name: openai.String("department"),

545 Instructions: "Which department should handle this complaint?",551 Instructions: openai.DecisionNewParamsQuestionChoiceInstructionsUnion{

552 OfString: openai.String("Which department should handle this complaint?"),

553 },

546 Choices: []openai.DecisionNewParamsQuestionChoiceChoice{554 Choices: []openai.DecisionNewParamsQuestionChoiceChoice{

547 {555 {

548 Value: openai.DecisionNewParamsQuestionChoiceChoiceValueUnion{OfString: openai.String("billing")},556 Value: openai.DecisionNewParamsQuestionChoiceChoiceValueUnion{OfString: openai.String("billing")},


820 Questions: []openai.DecisionNewParamsQuestionUnion{{828 Questions: []openai.DecisionNewParamsQuestionUnion{{

821 OfScore: &openai.DecisionNewParamsQuestionScore{829 OfScore: &openai.DecisionNewParamsQuestionScore{

822 Name: openai.String("severity"),830 Name: openai.String("severity"),

823 Instructions: "How severe is this issue?",831 Instructions: openai.DecisionNewParamsQuestionScoreInstructionsUnion{

832 OfString: openai.String("How severe is this issue?"),

833 },

824 Levels: []openai.DecisionNewParamsQuestionScoreLevel{834 Levels: []openai.DecisionNewParamsQuestionScoreLevel{

825 {Label: "Cosmetic", Description: openai.String("Appearance only; no lost functionality.")},835 {Label: "Cosmetic", Description: openai.String("Appearance only; no lost functionality.")},

826 {Label: "Workaround available", Description: openai.String("A task fails, but another way works.")},836 {Label: "Workaround available", Description: openai.String("A task fails, but another way works.")},

Details

1350 input=history,1350 input=history,

1351)1351)

1352 1352 

1353history.extend(item.model_dump(exclude={"status"}) for item in first.output)1353history.extend(item.to_dict() for item in first.output)

1354history.append(1354history.append(

1355 {1355 {

1356 "role": "user",1356 "role": "user",


1800The JavaScript sample uses `npm install openai@^7.10.0 ws`.1800The JavaScript sample uses `npm install openai@^7.10.0 ws`.

1801The Ruby sample uses `gem install openai async-websocket`.1801The Ruby sample uses `gem install openai async-websocket`.

1802 1802 

1803For Go, run `go get github.com/openai/openai-go/v3@v3.85.1`.1803For Go, run `go get github.com/openai/openai-go/v3@v3.91.0`.

1804For Java, add the Maven dependency `com.openai:openai-java:4.90.0`.1804For Java, add the Maven dependency `com.openai:openai-java:4.95.0`.

1805These Go and Java SDK versions provide native Responses WebSocket support.1805These Go and Java SDK versions provide native Responses WebSocket support.

1806 1806 

1807Start a Responses API WebSocket session1807Start a Responses API WebSocket session

Details

216```216```

217 217 

218```python218```python

219from pathlib import Path

220 

219from openai import OpenAI221from openai import OpenAI

220 222 

221client = OpenAI()223client = OpenAI()


229df["ada_embedding"] = df.combined.apply(231df["ada_embedding"] = df.combined.apply(

230 lambda x: get_embedding(x, model="text-embedding-3-small")232 lambda x: get_embedding(x, model="text-embedding-3-small")

231)233)

234Path("output").mkdir(exist_ok=True)

232df.to_csv("output/embedded_1k_reviews.csv", index=False)235df.to_csv("output/embedded_1k_reviews.csv", index=False)

233```236```

234 237 


395To load the data from a saved file, you can run the following:398To load the data from a saved file, you can run the following:

396 399 

397```python400```python

401from ast import literal_eval

398import pandas as pd402import pandas as pd

399 403 

400df = pd.read_csv("output/embedded_1k_reviews.csv")404df = pd.read_csv("output/embedded_1k_reviews.csv")

401df["ada_embedding"] = df.ada_embedding.apply(eval).apply(np.array)405df["ada_embedding"] = df.ada_embedding.apply(literal_eval).apply(np.array)

402```406```

403 407 

404 408 


1522The visualization seems to have produced roughly 3 clusters, one of which has mostly negative reviews.1526The visualization seems to have produced roughly 3 clusters, one of which has mostly negative reviews.

1523 1527 

1524```python1528```python

1529from ast import literal_eval

1525import numpy as np1530import numpy as np

1526import pandas as pd1531import pandas as pd

1527from sklearn.manifold import TSNE1532from sklearn.manifold import TSNE


1529import matplotlib1534import matplotlib

1530 1535 

1531df = pd.read_csv("output/embedded_1k_reviews.csv")1536df = pd.read_csv("output/embedded_1k_reviews.csv")

1532matrix = np.array(df.ada_embedding.apply(eval).to_list())1537matrix = np.array(df.ada_embedding.apply(literal_eval).to_list())

1533 1538 

1534# Create a t-SNE model and transform the data1539# Create a t-SNE model and transform the data

1535tsne = TSNE(1540tsne = TSNE(

Details

205 {205 {

206 "type": "function",206 "type": "function",

207 "name": "get_horoscope",207 "name": "get_horoscope",

208 "strict": True,

208 "description": "Get today's horoscope for an astrological sign.",209 "description": "Get today's horoscope for an astrological sign.",

209 "parameters": {210 "parameters": {

210 "type": "object",211 "type": "object",


215 },216 },

216 },217 },

217 "required": ["sign"],218 "required": ["sign"],

219 "additionalProperties": False,

218 },220 },

219 },221 },

220]222]


253 }255 }

254 )256 )

255 257 

256print("Final input:")

257print(input_list)

258 

259response = client.responses.create(258response = client.responses.create(

260 model="gpt-6-astra",259 model="gpt-6-astra",

261 instructions="Respond only with a horoscope generated by a tool.",260 instructions="Respond only with a horoscope generated by a tool.",


264)263)

265 264 

266# 5. The model should be able to give a response!265# 5. The model should be able to give a response!

267print("Final output:")266print(response.output_text)

268print(response.model_dump_json(indent=2))

269print("\n" + response.output_text)

270```267```

271 268 

272```go269```go


919 input=input_messages,916 input=input_messages,

920 tools=responses_tools,917 tools=responses_tools,

921)918)

922 

923print(response.output_text)

924```919```

925 920 

926```go921```go


1256 {1251 {

1257 "type": "function",1252 "type": "function",

1258 "name": "get_weather",1253 "name": "get_weather",

1254 "strict": True,

1259 "description": "Get current temperature for a given location.",1255 "description": "Get current temperature for a given location.",

1260 "parameters": {1256 "parameters": {

1261 "type": "object",1257 "type": "object",


1456final_tool_calls = {}1452final_tool_calls = {}

1457 1453 

1458for event in stream:1454for event in stream:

1459 if event.type == "response.output_item.added":1455 if (

1456 event.type == "response.output_item.added"

1457 and event.item.type == "function_call"

1458 ):

1460 final_tool_calls[event.output_index] = event.item1459 final_tool_calls[event.output_index] = event.item

1461 elif event.type == "response.function_call_arguments.delta":1460 elif event.type == "response.function_call_arguments.delta":

1462 index = event.output_index1461 index = event.output_index

Details

207 },207 },

208 ],208 ],

209 "pass_threshold": 0.5,209 "pass_threshold": 0.5,

210 "model": "o4-mini-2025-04-16",210 "model": "gpt-4.1-2025-04-14",

211 "range": [0, 1],211 "range": [0, 1],

212 "sampling_params": {212 "sampling_params": {

213 "max_completions_tokens": 32768,213 "max_completions_tokens": 32768,

214 "top_p": 1,214 "top_p": 1,

215 "reasoning_effort": "medium",

216 },215 },

217}216}

218 217 

Details

1348"""1348"""

1349 1349 

1350result = client.images.generate(1350result = client.images.generate(

1351 model="gpt-image-2",1351 model="gpt-image-2.5-sunburst",

1352 prompt=prompt,1352 prompt=prompt,

1353 size="1024x1536",1353 size="1024x1536",

1354 quality="medium",1354 quality="medium",


1359 1359 

1360# Preserve the returned PNG bytes, including the alpha channel.1360# Preserve the returned PNG bytes, including the alpha channel.

1361for index, item in enumerate(result.data, start=1):1361for index, item in enumerate(result.data, start=1):

1362 Path(f"logo-generation-{index}-gpt-image-2.png").write_bytes(1362 Path(f"logo-generation-{index}-gpt-image-2.5-sunburst.png").write_bytes(

1363 base64.b64decode(item.b64_json)1363 base64.b64decode(item.b64_json)

1364 )1364 )

1365 1365 


1373"""1373"""

1374 1374 

1375result = client.images.edit(1375result = client.images.edit(

1376 model="gpt-image-2",1376 model="gpt-image-2.5-sunburst",

1377 image=[1377 image=[

1378 Path("input_images/shampoo.webp"),1378 ("shampoo.webp", Path("input_images/shampoo.webp"), "image/webp"),

1379 ],1379 ],

1380 prompt=prompt,1380 prompt=prompt,

1381 size="1024x1536",1381 size="1024x1536",


1384 output_format="png",1384 output_format="png",

1385)1385)

1386 1386 

1387Path("extract-product-gpt-image-2.png").write_bytes(1387Path("extract-product-gpt-image-2.5-sunburst.png").write_bytes(

1388 base64.b64decode(result.data[0].b64_json)1388 base64.b64decode(result.data[0].b64_json)

1389)1389)

1390```1390```

Details

456 456 

457async def send_update(457async def send_update(

458 connection: AsyncLiveConnection | AsyncSidebandConnection,458 connection: AsyncLiveConnection | AsyncSidebandConnection,

459 delegation_id: str,

459) -> None:460) -> None:

460 await connection.session.commentary.append(461 await connection.session.commentary.append(

461 event_id="result_123",462 event_id="result_123",

462 delegation_id="item_9tA2bF3h7K9m2P5q8R1s4",463 delegation_id=delegation_id,

463 content="The order shipped today and should arrive tomorrow.",464 content="The order shipped today and should arrive tomorrow.",

464 )465 )

465```466```


573 574 

574async def send_update(575async def send_update(

575 connection: AsyncLiveConnection | AsyncSidebandConnection,576 connection: AsyncLiveConnection | AsyncSidebandConnection,

577 delegation_id: str,

576) -> None:578) -> None:

577 await connection.session.thinking.append(579 await connection.session.thinking.append(

578 event_id="availability_progress",580 event_id="availability_progress",

579 delegation_id="item_123",581 delegation_id=delegation_id,

580 content="Checking Thursday availability. No appointment has been booked.",582 content="Checking Thursday availability. No appointment has been booked.",

581 )583 )

582```584```


640 642 

641async def send_update(643async def send_update(

642 connection: AsyncLiveConnection | AsyncSidebandConnection,644 connection: AsyncLiveConnection | AsyncSidebandConnection,

645 delegation_id: str,

643) -> None:646) -> None:

644 await connection.session.commentary.append(647 await connection.session.commentary.append(

645 event_id="appointment_result",648 event_id="appointment_result",

646 delegation_id="item_123",649 delegation_id=delegation_id,

647 content="Your appointment is confirmed for Thursday at 2:00 PM",650 content="Your appointment is confirmed for Thursday at 2:00 PM",

648 )651 )

649```652```

Details

53| [`model`](https://developers.openai.com/api/reference/resources/responses/methods/create#%28resource%29%20responses%20%3E%20%28method%29%20create%20%3E%20%28params%29%200.non_streaming%20%3E%20%28param%29%20model%20%3E%20%28schema%29) | A different model can use different weights and caching behavior. |53| [`model`](https://developers.openai.com/api/reference/resources/responses/methods/create#%28resource%29%20responses%20%3E%20%28method%29%20create%20%3E%20%28params%29%200.non_streaming%20%3E%20%28param%29%20model%20%3E%20%28schema%29) | A different model can use different weights and caching behavior. |

54| [`tools`](https://developers.openai.com/api/reference/resources/responses/methods/create#%28resource%29%20responses%20%3E%20%28method%29%20create%20%3E%20%28params%29%200.non_streaming%20%3E%20%28param%29%20tools%20%3E%20%28schema%29) | Changes tool names, descriptions, schemas, ordering, or tool-specific instructions. |54| [`tools`](https://developers.openai.com/api/reference/resources/responses/methods/create#%28resource%29%20responses%20%3E%20%28method%29%20create%20%3E%20%28params%29%200.non_streaming%20%3E%20%28param%29%20tools%20%3E%20%28schema%29) | Changes tool names, descriptions, schemas, ordering, or tool-specific instructions. |

55| [`parallel_tool_calls`](https://developers.openai.com/api/reference/resources/responses/methods/create#%28resource%29%20responses%20%3E%20%28method%29%20create%20%3E%20%28params%29%200.non_streaming%20%3E%20%28param%29%20parallel_tool_calls%20%3E%20%28schema%29) | Can change instructions about calling multiple tools in one turn. |55| [`parallel_tool_calls`](https://developers.openai.com/api/reference/resources/responses/methods/create#%28resource%29%20responses%20%3E%20%28method%29%20create%20%3E%20%28params%29%200.non_streaming%20%3E%20%28param%29%20parallel_tool_calls%20%3E%20%28schema%29) | Can change instructions about calling multiple tools in one turn. |

56| [`text.format`](https://developers.openai.com/api/reference/resources/responses/methods/create#%28resource%29%20responses%20%3E%20%28method%29%20create%20%3E%20%28params%29%200.non_streaming%20%3E%20%28param%29%20text%20%3E%20%28schema%29) ([Structured Outputs](https://developers.openai.com/api/docs/guides/structured-outputs)) | Adds output-format instructions and the requested schema. |56| [`text.format`](https://developers.openai.com/api/reference/resources/responses/methods/create#%28resource%29%20responses%20%3E%20%28method%29%20create%20%3E%20%28params%29%200.non_streaming%20%3E%20%28param%29%20text%20%3E%20%28schema%29) ([Structured Outputs](https://developers.openai.com/api/docs/guides/structured-outputs)) | On supported GPT-6 and later models, [append a format update](https://developers.openai.com/api/docs/guides/structured-outputs?api-mode=responses#change-the-response-format-mid-conversation) to keep the original schema in the prefix. |

57| [`reasoning.effort`](https://developers.openai.com/api/reference/resources/responses/methods/create#%28resource%29%20responses%20%3E%20%28method%29%20create%20%3E%20%28params%29%200.non_streaming%20%3E%20%28param%29%20reasoning%20%3E%20%28schema%29) | Can change model-side reasoning instructions. On supported models, use a [configuration update](#change-reasoning-effort-without-rewriting-the-prefix) to change effort while preserving the earlier prefix. |57| [`reasoning.effort`](https://developers.openai.com/api/reference/resources/responses/methods/create#%28resource%29%20responses%20%3E%20%28method%29%20create%20%3E%20%28params%29%200.non_streaming%20%3E%20%28param%29%20reasoning%20%3E%20%28schema%29) | Can change model-side reasoning instructions. On supported models, use a [configuration update](#change-reasoning-effort-without-rewriting-the-prefix) to change effort while preserving the earlier prefix. |

58| [`text.verbosity`](https://developers.openai.com/api/reference/resources/responses/methods/create#%28resource%29%20responses%20%3E%20%28method%29%20create%20%3E%20%28params%29%200.non_streaming%20%3E%20%28param%29%20text%20%3E%20%28schema%29) | Can change instructions about response detail. |58| [`text.verbosity`](https://developers.openai.com/api/reference/resources/responses/methods/create#%28resource%29%20responses%20%3E%20%28method%29%20create%20%3E%20%28params%29%200.non_streaming%20%3E%20%28param%29%20text%20%3E%20%28schema%29) | Can change instructions about response detail. |

59| [`context_management`](https://developers.openai.com/api/reference/resources/responses/methods/create#%28resource%29%20responses%20%3E%20%28method%29%20create%20%3E%20%28params%29%200.non_streaming%20%3E%20%28param%29%20context_management%20%3E%20%28schema%29) ([Compaction](https://developers.openai.com/api/docs/guides/compaction)) | Replaces earlier conversation content with a compacted context that can prevent reuse from the first changed token onward. |59| [`context_management`](https://developers.openai.com/api/reference/resources/responses/methods/create#%28resource%29%20responses%20%3E%20%28method%29%20create%20%3E%20%28params%29%200.non_streaming%20%3E%20%28param%29%20context_management%20%3E%20%28schema%29) ([Compaction](https://developers.openai.com/api/docs/guides/compaction)) | Replaces earlier conversation content with a compacted context that can prevent reuse from the first changed token onward. |


406 406 

407On supported GPT-6 and later models, append a `configuration_update` input item to [change reasoning effort during a conversation](https://developers.openai.com/api/docs/guides/reasoning?api-mode=responses#change-reasoning-mid-conversation) while preserving the earlier cached prefix. Keep the top-level `reasoning.effort` at its original value as changing that setting can rewrite instructions in the hidden system instructions.407On supported GPT-6 and later models, append a `configuration_update` input item to [change reasoning effort during a conversation](https://developers.openai.com/api/docs/guides/reasoning?api-mode=responses#change-reasoning-mid-conversation) while preserving the earlier cached prefix. Keep the top-level `reasoning.effort` at its original value as changing that setting can rewrite instructions in the hidden system instructions.

408 408 

409The latest configuration update controls the reasoning effort for subsequent responses. For example, append this item to the existing `input` array to switch to `high` reasoning for the subsequent requests:409The latest update to `reasoning.effort` controls the effort for later responses. Append this item to `input` to switch to `high` effort.

410 410 

411Item to append to the input array411Item to append to the input array

412 412 

Details

125| `prompt_cache_key_changed` | The supplied key changed between requests. This can be reported as a cache miss in response `usage` without a physical cache miss. | Omit `prompt_cache_key` unless your application needs separate cache accounting for customers or users. If you use keys, keep a stable key within each group. See [Separate cache accounting with keys](https://developers.openai.com/api/docs/guides/prompt-caching#separate-prompts-with-cache-keys). |125| `prompt_cache_key_changed` | The supplied key changed between requests. This can be reported as a cache miss in response `usage` without a physical cache miss. | Omit `prompt_cache_key` unless your application needs separate cache accounting for customers or users. If you use keys, keep a stable key within each group. See [Separate cache accounting with keys](https://developers.openai.com/api/docs/guides/prompt-caching#separate-prompts-with-cache-keys). |

126| `service_tier_changed` | The service tier used to process the request changed. | Keep the service tier consistent for requests expected to share a prefix. Check the returned `service_tier`, which can differ from the requested value. See [`service_tier`](https://developers.openai.com/api/reference/resources/responses/methods/create#%28resource%29%20responses%20%3E%20%28method%29%20create%20%3E%20%28params%29%200.non_streaming%20%3E%20%28param%29%20service_tier%20%3E%20%28schema%29) for supported values and behavior. |126| `service_tier_changed` | The service tier used to process the request changed. | Keep the service tier consistent for requests expected to share a prefix. Check the returned `service_tier`, which can differ from the requested value. See [`service_tier`](https://developers.openai.com/api/reference/resources/responses/methods/create#%28resource%29%20responses%20%3E%20%28method%29%20create%20%3E%20%28params%29%200.non_streaming%20%3E%20%28param%29%20service_tier%20%3E%20%28schema%29) for supported values and behavior. |

127| `tools_changed` | Tools were added, removed, or reordered, or their descriptions, schemas, or configuration changed. | Keep tool definitions and ordering stable. Use `tool_choice: "none"` to disable tools or `allowed_tools` to restrict which tools can run without changing the supplied tool list. See [Manage tools with append-only updates](https://developers.openai.com/api/docs/guides/prompt-caching#manage-tools-with-append-only-updates). |127| `tools_changed` | Tools were added, removed, or reordered, or their descriptions, schemas, or configuration changed. | Keep tool definitions and ordering stable. Use `tool_choice: "none"` to disable tools or `allowed_tools` to restrict which tools can run without changing the supplied tool list. See [Manage tools with append-only updates](https://developers.openai.com/api/docs/guides/prompt-caching#manage-tools-with-append-only-updates). |

128| `text_format_changed` | The output format or its schema changed. | Keep `text.format` and the schema consistent when the required output structure is unchanged. See [Structured Outputs](https://developers.openai.com/api/docs/guides/structured-outputs). |128| `text_format_changed` | The output format or its schema changed. | On supported GPT-6 and later models, keep the top-level `text.format` stable and [append a format update](https://developers.openai.com/api/docs/guides/structured-outputs?api-mode=responses#change-the-response-format-mid-conversation) when you need a different schema. |

129| `reasoning_effort_changed` | The reasoning effort changed. | On supported GPT-6 and later models, append a `configuration_update` input item to [change reasoning effort during a conversation](https://developers.openai.com/api/docs/guides/reasoning?api-mode=responses#change-reasoning-mid-conversation) while preserving the earlier cached prefix.<br />On older models, keep `reasoning.effort` consistent across requests intended to share a prefix. |129| `reasoning_effort_changed` | The reasoning effort changed. | On supported GPT-6 and later models, append a `configuration_update` input item to [change reasoning effort during a conversation](https://developers.openai.com/api/docs/guides/reasoning?api-mode=responses#change-reasoning-mid-conversation) while preserving the earlier cached prefix.<br />On older models, keep `reasoning.effort` consistent across requests intended to share a prefix. |

130| `verbosity_changed` | The response verbosity changed. | Keep `text.verbosity` consistent across requests intended to share a prefix. See [cache-affecting settings](https://developers.openai.com/api/docs/guides/prompt-caching#which-settings-affect-the-cached-prefix). |130| `verbosity_changed` | The response verbosity changed. | Keep `text.verbosity` consistent across requests intended to share a prefix. See [cache-affecting settings](https://developers.openai.com/api/docs/guides/prompt-caching#which-settings-affect-the-cached-prefix). |

131| `context_compacted` | Compaction replaced earlier conversation content. | Preserve stable instructions and let later turns build on the compacted context. Compare total input cost: fewer input tokens can still save money despite lower cache reuse. See [Compaction](https://developers.openai.com/api/docs/guides/compaction). |131| `context_compacted` | Compaction replaced earlier conversation content. | Preserve stable instructions and let later turns build on the compacted context. Compare total input cost: fewer input tokens can still save money despite lower cache reuse. See [Compaction](https://developers.openai.com/api/docs/guides/compaction). |

Details

2114 2114 

2115```python2115```python

2116from openai import OpenAI2116from openai import OpenAI

2117from jsonschema import Draft202012Validator, ValidationError

2117import json2118import json

2118 2119 

2119client = OpenAI()2120client = OpenAI()

2120 2121 

2121META_SCHEMA = {2122SCHEMA_DEFINITION = {

2122 "name": "metaschema",

2123 "schema": {

2124 "type": "object",2123 "type": "object",

2125 "properties": {2124 "properties": {

2126 "name": {"type": "string", "description": "The name of the schema"},2125 "description": {"type": "string"},

2127 "type": {2126 "type": {

2128 "type": "string",2127 "type": "string",

2129 "enum": ["object", "array", "string", "number", "boolean", "null"],2128 "enum": ["object", "array", "string", "number", "boolean", "null"],


2140 },2139 },

2141 "required": {"type": "array", "items": {"type": "string"}},2140 "required": {"type": "array", "items": {"type": "string"}},

2142 "additionalProperties": {"type": "boolean"},2141 "additionalProperties": {"type": "boolean"},

2143 },2142 "enum": {"type": "array", "minItems": 1, "uniqueItems": True},

2144 "required": ["type"],2143 "$ref": {"type": "string"},

2145 "additionalProperties": False,

2146 "if": {"properties": {"type": {"const": "object"}}},

2147 "then": {"required": ["properties"]},

2148 "$defs": {2144 "$defs": {

2149 "schema_definition": {

2150 "type": "object",

2151 "properties": {

2152 "type": {

2153 "type": "string",

2154 "enum": [

2155 "object",

2156 "array",

2157 "string",

2158 "number",

2159 "boolean",

2160 "null",

2161 ],

2162 },

2163 "properties": {

2164 "type": "object",2145 "type": "object",

2165 "additionalProperties": {"$ref": "#/$defs/schema_definition"},2146 "additionalProperties": {"$ref": "#/$defs/schema_definition"},

2166 },2147 },

2167 "items": {2148 "anyOf": {

2168 "anyOf": [

2169 {"$ref": "#/$defs/schema_definition"},

2170 {

2171 "type": "array",2149 "type": "array",

2150 "minItems": 1,

2172 "items": {"$ref": "#/$defs/schema_definition"},2151 "items": {"$ref": "#/$defs/schema_definition"},

2173 },2152 },

2174 ]

2175 },

2176 "required": {"type": "array", "items": {"type": "string"}},

2177 "additionalProperties": {"type": "boolean"},

2178 },2153 },

2179 "required": ["type"],

2180 "additionalProperties": False,2154 "additionalProperties": False,

2181 "if": {"properties": {"type": {"const": "object"}}},2155 "if": {"required": ["type"], "properties": {"type": {"const": "object"}}},

2182 "then": {"required": ["properties"]},2156 "then": {"required": ["properties"]},

2157}

2158 

2159META_SCHEMA = {

2160 "name": "metaschema",

2161 "schema": {

2162 **SCHEMA_DEFINITION,

2163 "required": ["type"],

2164 "properties": {

2165 "name": {"type": "string", "description": "The name of the schema"},

2166 **SCHEMA_DEFINITION["properties"],

2167 },

2168 "$defs": {

2169 "schema_definition": {

2170 **SCHEMA_DEFINITION,

2171 "anyOf": [

2172 {"required": ["type"]},

2173 {"required": ["$ref"]},

2174 {"required": ["anyOf"]},

2175 ],

2183 }2176 }

2184 },2177 },

2185 },2178 },


2353 2346 

2354 2347 

2355def generate_schema(description: str):2348def generate_schema(description: str):

2349 messages = [

2350 {"role": "system", "content": META_PROMPT},

2351 {"role": "user", "content": "Description:\n" + description},

2352 ]

2353 validator = Draft202012Validator(META_SCHEMA["schema"])

2354 # Generation is non-strict. Validate locally and allow one correction.

2355 for attempt in range(2):

2356 completion = client.chat.completions.create(2356 completion = client.chat.completions.create(

2357 model="gpt-5.6-terra",2357 model="gpt-5.6-terra",

2358 response_format={"type": "json_schema", "json_schema": META_SCHEMA},2358 response_format={"type": "json_schema", "json_schema": META_SCHEMA},

2359 messages=[2359 messages=messages,

2360 {2360 )

2361 "role": "system",2361 choice = completion.choices[0]

2362 "content": META_PROMPT,2362 if choice.finish_reason != "stop" or choice.message.refusal:

2363 },2363 raise ValueError("Schema generation did not complete successfully")

2364 content = choice.message.content

2365 schema = json.loads(content)

2366 try:

2367 validator.validate(schema)

2368 except ValidationError as error:

2369 if attempt == 1:

2370 raise

2371 messages.extend(

2372 [

2373 {"role": "assistant", "content": content},

2364 {2374 {

2365 "role": "user",2375 "role": "user",

2366 "content": "Description:\n" + description,2376 "content": (

2377 "Correct the schema to satisfy the original meta-schema. "

2378 f"Validation error at {error.json_path}: {error.message}. "

2379 "Return only the corrected JSON."

2380 ),

2367 },2381 },

2368 ],2382 ]

2369 )2383 )

2370 2384 else:

2371 return json.loads(completion.choices[0].message.content)2385 return schema

2372```2386```

2373 2387 

2374```go2388```go


2561 "type": "string",2575 "type": "string",

2562 "description": "The name of the schema"2576 "description": "The name of the schema"

2563 },2577 },

2578 "description": {

2579 "type": "string"

2580 },

2564 "type": {2581 "type": {

2565 "type": "string",2582 "type": "string",

2566 "enum": [2583 "enum": [


2599 },2616 },

2600 "additionalProperties": {2617 "additionalProperties": {

2601 "type": "boolean"2618 "type": "boolean"

2619 },

2620 "enum": {

2621 "type": "array",

2622 "minItems": 1,

2623 "uniqueItems": true

2624 },

2625 "$ref": {

2626 "type": "string"

2627 },

2628 "$defs": {

2629 "type": "object",

2630 "additionalProperties": {

2631 "$ref": "#/$defs/schema_definition"

2632 }

2633 },

2634 "anyOf": {

2635 "type": "array",

2636 "minItems": 1,

2637 "items": {

2638 "$ref": "#/$defs/schema_definition"

2639 }

2602 }2640 }

2603 },2641 },

2642 "additionalProperties": false,

2643 "if": {

2604 "required": [2644 "required": [

2605 "type"2645 "type"

2606 ],2646 ],

2607 "additionalProperties": false,

2608 "if": {

2609 "properties": {2647 "properties": {

2610 "type": {2648 "type": {

2611 "const": "object"2649 "const": "object"


2617 "properties"2655 "properties"

2618 ]2656 ]

2619 },2657 },

2658 "required": [

2659 "type"

2660 ],

2620 "$defs": {2661 "$defs": {

2621 "schema_definition": {2662 "schema_definition": {

2622 "type": "object",2663 "type": "object",


2662 },2703 },

2663 "additionalProperties": {2704 "additionalProperties": {

2664 "type": "boolean"2705 "type": "boolean"

2706 },

2707 "enum": {

2708 "type": "array",

2709 "minItems": 1,

2710 "uniqueItems": true

2711 },

2712 "$ref": {

2713 "type": "string"

2714 },

2715 "$defs": {

2716 "type": "object",

2717 "additionalProperties": {

2718 "$ref": "#/$defs/schema_definition"

2719 }

2720 },

2721 "anyOf": {

2722 "type": "array",

2723 "minItems": 1,

2724 "items": {

2725 "$ref": "#/$defs/schema_definition"

2726 }

2665 }2727 }

2666 },2728 },

2729 "additionalProperties": false,

2730 "if": {

2667 "required": [2731 "required": [

2668 "type"2732 "type"

2669 ],2733 ],

2670 "additionalProperties": false,

2671 "if": {

2672 "properties": {2734 "properties": {

2673 "type": {2735 "type": {

2674 "const": "object"2736 "const": "object"


2679 "required": [2741 "required": [

2680 "properties"2742 "properties"

2681 ]2743 ]

2744 },

2745 "anyOf": [

2746 {

2747 "required": [

2748 "type"

2749 ]

2750 },

2751 {

2752 "required": [

2753 "$ref"

2754 ]

2755 },

2756 {

2757 "required": [

2758 "anyOf"

2759 ]

2682 }2760 }

2761 ]

2683 }2762 }

2684 }2763 }

2685}`), &schema); err != nil {2764}`), &schema); err != nil {


3350require "openai"3429require "openai"

3351require "json"3430require "json"

3352 3431 

3353META_SCHEMA = {3432SCHEMA_DEFINITION = {

3354 "name" => "metaschema",

3355 "schema" => {

3356 "type" => "object",3433 "type" => "object",

3357 "properties" => {3434 "properties" => {

3358 "description" => { "type" => "string" },3435 "description" => {

3359 "name" => {3436 "type" => "string"

3360 "type" => "string",

3361 "description" => "The name of the schema"

3362 },3437 },

3363 "type" => {3438 "type" => {

3364 "type" => "string",3439 "type" => "string",

3365 "enum" => ["object", "array", "string", "number", "boolean", "null"]3440 "enum" => [

3441 "object",

3442 "array",

3443 "string",

3444 "number",

3445 "boolean",

3446 "null"

3447 ]

3366 },3448 },

3367 "properties" => {3449 "properties" => {

3368 "type" => "object",3450 "type" => "object",


3374 "anyOf" => [3456 "anyOf" => [

3375 {3457 {

3376 "$ref" => "#/$defs/schema_definition"3458 "$ref" => "#/$defs/schema_definition"

3377 }, {3459 },

3460 {

3378 "type" => "array",3461 "type" => "array",

3379 "items" => {3462 "items" => {

3380 "$ref" => "#/$defs/schema_definition"3463 "$ref" => "#/$defs/schema_definition"


3390 },3473 },

3391 "additionalProperties" => {3474 "additionalProperties" => {

3392 "type" => "boolean"3475 "type" => "boolean"

3393 }

3394 },3476 },

3395 "required" => ["type"],3477 "enum" => {

3396 "additionalProperties" => false,3478 "type" => "array",

3397 "if" => {3479 "minItems" => 1,

3398 "properties" => {3480 "uniqueItems" => true

3399 "type" => {

3400 "const" => "object"

3401 }

3402 }

3403 },3481 },

3404 "then" => {3482 "$ref" => {

3405 "required" => ["properties"]3483 "type" => "string"

3406 },3484 },

3407 "$defs" => {3485 "$defs" => {

3408 "schema_definition" => {

3409 "type" => "object",

3410 "properties" => {

3411 "description" => { "type" => "string" },

3412 "type" => {

3413 "type" => "string",

3414 "enum" => ["object", "array", "string", "number", "boolean", "null"]

3415 },

3416 "properties" => {

3417 "type" => "object",3486 "type" => "object",

3418 "additionalProperties" => {3487 "additionalProperties" => {

3419 "$ref" => "#/$defs/schema_definition"3488 "$ref" => "#/$defs/schema_definition"

3420 }3489 }

3421 },3490 },

3422 "items" => {3491 "anyOf" => {

3423 "anyOf" => [

3424 {

3425 "$ref" => "#/$defs/schema_definition"

3426 }, {

3427 "type" => "array",3492 "type" => "array",

3493 "minItems" => 1,

3428 "items" => {3494 "items" => {

3429 "$ref" => "#/$defs/schema_definition"3495 "$ref" => "#/$defs/schema_definition"

3430 }3496 }

3431 }3497 }

3432 ]

3433 },

3434 "required" => {

3435 "type" => "array",

3436 "items" => {

3437 "type" => "string"

3438 }

3439 },

3440 "additionalProperties" => {

3441 "type" => "boolean"

3442 }

3443 },3498 },

3444 "required" => ["type"],

3445 "additionalProperties" => false,3499 "additionalProperties" => false,

3446 "if" => {3500 "if" => {

3501 "required" => [

3502 "type"

3503 ],

3447 "properties" => {3504 "properties" => {

3448 "type" => {3505 "type" => {

3449 "const" => "object"3506 "const" => "object"


3451 }3508 }

3452 },3509 },

3453 "then" => {3510 "then" => {

3454 "required" => ["properties"]3511 "required" => [

3455 }3512 "properties"

3513 ]

3456 }3514 }

3515}

3516 

3517META_SCHEMA = {

3518 "name" => "metaschema",

3519 "schema" => SCHEMA_DEFINITION.merge(

3520 "required" => ["type"],

3521 "properties" => SCHEMA_DEFINITION.fetch("properties").merge(

3522 "name" => {

3523 "type" => "string",

3524 "description" => "The name of the schema"

3457 }3525 }

3526 ),

3527 "$defs" => {

3528 "schema_definition" => SCHEMA_DEFINITION.merge(

3529 "anyOf" => [{ "required" => ["type"] }, { "required" => ["$ref"] }, { "required" => ["anyOf"] }]

3530 )

3458 }3531 }

3532 )

3459}3533}

3460 3534 

3461META_PROMPT = <<~PROMPT.strip3535META_PROMPT = <<~PROMPT.strip


3922 "schema_definition": {3996 "schema_definition": {

3923 "type": "object",3997 "type": "object",

3924 "properties": {3998 "properties": {

3999 "description": {"type": "string"},

4000 "enum": {"type": "array", "minItems": 1, "uniqueItems": True},

3925 "type": {4001 "type": {

3926 "type": "string",4002 "type": "string",

3927 "enum": [4003 "enum": [


4316 },4392 },

4317 "additionalProperties": {4393 "additionalProperties": {

4318 "type": "boolean"4394 "type": "boolean"

4395 },

4396 "enum": {

4397 "type": "array",

4398 "minItems": 1,

4399 "uniqueItems": true

4319 }4400 }

4320 },4401 },

4321 "required": [4402 "required": [


4827 "type" => "object",4908 "type" => "object",

4828 "properties" => {4909 "properties" => {

4829 "description" => { "type" => "string" },4910 "description" => { "type" => "string" },

4911 "enum" => {

4912 "type" => "array",

4913 "minItems" => 1,

4914 "uniqueItems" => true

4915 },

4830 "type" => {4916 "type" => {

4831 "type" => "string",4917 "type" => "string",

4832 "enum" => ["object", "array", "string", "number", "boolean", "null"]4918 "enum" => ["object", "array", "string", "number", "boolean", "null"]

Details

41 41 

42response = client.responses.create(42response = client.responses.create(

43 prompt={43 prompt={

44 "prompt_id": prompt_id,44 "id": prompt_id,

45 "version": "1",45 "version": "1",

46 "variables": {46 "variables": {

47 "customer_name": "Acme",47 "customer_name": "Acme",

Details

566```566```

567 567 

568```ruby568```ruby

569connection.each do |event|569response_done = connection.find do |event|

570 next unless event.is_a?(OpenAI::Realtime::ResponseDoneEvent)570 next unless event.is_a?(OpenAI::Realtime::ResponseDoneEvent)

571 571 

572 puts("Response status: #{event.response.status}")572 puts("Response status: #{event.response.status}")


577 puts(content.text) if content.type == :output_text577 puts(content.text) if content.type == :output_text

578 end578 end

579 end579 end

580 break580 true

581end581end

582raise "Connection closed before the response completed" unless response_done

582```583```

583 584 

584 585 


876 877 

877def float_to_16bit_pcm(float32_array):878def float_to_16bit_pcm(float32_array):

878 clipped = [max(-1.0, min(1.0, x)) for x in float32_array]879 clipped = [max(-1.0, min(1.0, x)) for x in float32_array]

879 pcm16 = b"".join(struct.pack("<h", int(x * 32767)) for x in clipped)880 pcm16 = b"".join(struct.pack("<h", min(32767, int(x * 32768))) for x in clipped)

880 return pcm16881 return pcm16

881 882 

882 883 


1581```1582```

1582 1583 

1583```ruby1584```ruby

1584connection.each do |event|1585response_done = connection.find do |event|

1585 next unless event.is_a?(OpenAI::Realtime::ResponseDoneEvent)1586 next unless event.is_a?(OpenAI::Realtime::ResponseDoneEvent)

1586 next unless event.response.metadata&.fetch(:topic, nil) == "classification"1587 next unless event.response.metadata&.fetch(:topic, nil) == "classification"

1587 1588 


1593 puts("Classification: #{content.text}") if content.type == :output_text1594 puts("Classification: #{content.text}") if content.type == :output_text

1594 end1595 end

1595 end1596 end

1596 break1597 true

1597end1598end

1599raise "Connection closed before the response completed" unless response_done

1598```1600```

1599 1601 

1600 1602 


1776event = {1778event = {

1777 "type": "response.create",1779 "type": "response.create",

1778 "response": {1780 "response": {

1781 "output_modalities": ["text"],

1779 # An empty input array removes all prior context1782 # An empty input array removes all prior context

1780 "input": [],1783 "input": [],

1781 "instructions": prompt,1784 "instructions": prompt,

Details

252}252}

253 253 

254ws.send(json.dumps(event))254ws.send(json.dumps(event))

255ws.send(json.dumps({"type": "response.create"}))255ws.send(

256 json.dumps(

257 {

258 "type": "response.create",

259 "response": {"output_modalities": ["text"], "tool_choice": "none"},

260 }

261 )

262)

256```263```

257 264 

258```go265```go


1020 event = {1027 event = {

1021 "type": "conversation.item.create",1028 "type": "conversation.item.create",

1022 "item": {1029 "item": {

1023 "id": f"mcp_approval_{approval_request_id}",

1024 "type": "mcp_approval_response",1030 "type": "mcp_approval_response",

1025 "approval_request_id": approval_request_id,1031 "approval_request_id": approval_request_id,

1026 "approve": True,1032 "approve": True,


1165 "type": "response.create",1171 "type": "response.create",

1166 "response": {1172 "response": {

1167 "output_modalities": ["text"],1173 "output_modalities": ["text"],

1174 "tool_choice": "required",

1175 "parallel_tool_calls": False,

1168 "input": [1176 "input": [

1169 {1177 {

1170 "type": "message",1178 "type": "message",

Details

768)768)

769 769 

770# Keep every output item, including encrypted reasoning and assistant phase.770# Keep every output item, including encrypted reasoning and assistant phase.

771history.extend(item.model_dump() for item in first.output)771history.extend(item.to_dict() for item in first.output)

772history.append(772history.append(

773 {773 {

774 "role": "user",774 "role": "user",


952 952 

953Use `configuration_update` to increase reasoning effort for difficult work or reduce it for routine follow-ups. Add the update between responses while leaving the request-level `reasoning.effort` unchanged. This preserves the original prompt prefix for [prompt caching](https://developers.openai.com/api/docs/guides/prompt-caching).953Use `configuration_update` to increase reasoning effort for difficult work or reduce it for routine follow-ups. Add the update between responses while leaving the request-level `reasoning.effort` unchanged. This preserves the original prompt prefix for [prompt caching](https://developers.openai.com/api/docs/guides/prompt-caching).

954 954 

955Configuration updates are supported by the GPT-6 model family in standard,955On supported GPT-6 and later models, you can update reasoning effort and

956 single-agent mode. They change only reasoning effort.956 response format in standard, single-agent mode.

957 957 

958Add the following item before the next user message in the `input` array of an HTTP Responses request or a WebSocket `response.create` request:958Add the following item before the next user message in the `input` array of an HTTP Responses request or a WebSocket `response.create` request:

959 959 


1160 1160 

1161Preserve updates with `previous_response_id`, or replay them in their original positions when [managing conversation history manually](https://developers.openai.com/api/docs/guides/conversation-state#manually-manage-conversation-state). The response's `reasoning.effort` continues to report the request-level setting, not the effort selected by the update.1161Preserve updates with `previous_response_id`, or replay them in their original positions when [managing conversation history manually](https://developers.openai.com/api/docs/guides/conversation-state#manually-manage-conversation-state). The response's `reasoning.effort` continues to report the request-level setting, not the effort selected by the update.

1162 1162 

1163Do not place two `configuration_update` items directly next to each other in the conversation history; the API rejects adjacent updates.1163You can set `reasoning.effort` and [`text.format`](https://developers.openai.com/api/docs/guides/structured-outputs?api-mode=responses#change-the-response-format-mid-conversation) in the same `configuration_update` item. An update to either setting alone preserves the other.

1164 1164 

1165Do not combine configuration updates with automatic compaction or automatic truncation. The standalone `/responses/compact` endpoint also rejects histories containing these updates.1165Do not combine configuration updates with automatic compaction or automatic truncation. The standalone `/responses/compact` endpoint also rejects histories containing these updates.

1166 1166 

1167You can still explicitly compact history by including a `compaction_trigger` item in a `/responses` request. After compaction, add a fresh `configuration_update` with the desired effort before the next user message.1167You can still explicitly compact history by including a `compaction_trigger` item in a `/responses` request. After compaction, add a fresh `configuration_update` before the next user message. Restate each setting you changed, including the format if you changed it.

1168 1168 

1169Normal prompt caching requirements still apply. To send user instructions while a response is running, use [Mid-turn steering](https://developers.openai.com/api/docs/guides/steering).1169Normal prompt caching requirements still apply. To send user instructions while a response is running, use [Mid-turn steering](https://developers.openai.com/api/docs/guides/steering).

1170 1170 

Details

332history = [332history = [

333 {333 {

334 "role": "user",334 "role": "user",

335 "content": "Compare proposal alpha and proposal beta.",335 "content": (

336 "Use two subagents, one for proposal alpha and one for proposal beta. "

337 "Have each call get_proposal, then compare their findings."

338 ),

336 }339 }

337]340]

338 341 

Details

1357 "file_id": "file_456",1357 "file_id": "file_456",

1358 "chunking_strategy": {1358 "chunking_strategy": {

1359 "type": "static",1359 "type": "static",

1360 "static": {

1360 "max_chunk_size_tokens": 1200,1361 "max_chunk_size_tokens": 1200,

1361 "chunk_overlap_tokens": 2001362 "chunk_overlap_tokens": 200

1362 }1363 }

1363 }1364 }

1365 }

1364 ]1366 ]

1365)1367)

1366```1368```

Details

955 prompt="ZyntriQix, Digique Plus, CynapseFive, VortiQore V8, EchoNix Array, OrbitalLink Seven, DigiFractal Matrix, PULSE, RAPT, B.R.I.C.K., Q.U.A.R.T.Z., F.L.I.N.T.",955 prompt="ZyntriQix, Digique Plus, CynapseFive, VortiQore V8, EchoNix Array, OrbitalLink Seven, DigiFractal Matrix, PULSE, RAPT, B.R.I.C.K., Q.U.A.R.T.Z., F.L.I.N.T.",

956)956)

957 957 

958print(transcription.text)958print(transcription)

959```959```

960 960 

961```go961```go

Details

154 async with client.responses.connect() as connection:154 async with client.responses.connect() as connection:

155 await connection.response.create(155 await connection.response.create(

156 model="gpt-6-astra",156 model="gpt-6-astra",

157 store=False,

157 reasoning={"effort": "medium"},158 reasoning={"effort": "medium"},

158 input="Draft a project plan for building a task-tracking app.",159 input="Draft a project plan for building a task-tracking app.",

159 )160 )

Details

2568 },2568 },

2569 },2569 },

2570 },2570 },

2571 max_output_tokens=50,2571 max_output_tokens=1024,

2572 )2572 )

2573 2573 

2574 if (2574 if (


2902 2902 

2903 2903 

2904 2904 

2905Change the response format mid-conversation

2906 

2907 

2908 

2909To switch to a new schema between responses, append a `configuration_update` item to `input` before the next user message. Keep the original top-level `text.format` on each request so the earlier prompt prefix stays eligible for [prompt caching](https://developers.openai.com/api/docs/guides/prompt-caching).

2910 

2911Response format updates are available on supported GPT-6 and later models in

2912 standard, single-agent mode.

2913 

2914Suppose the previous turn described a shipment with 17 red crates and 26 blue crates in plain text. Continue the conversation with `previous_response_id` and pass the following array as `input`.

2915 

2916Switch from plain text to a structured crate count

2917 

2918```javascript

2919import OpenAI from "openai";

2920import { zodTextFormat } from "openai/helpers/zod";

2921import { z } from "zod";

2922 

2923const client = new OpenAI();

2924const model = "gpt-6-astra";

2925const CrateCount = z.object({ total_crates: z.number().int() });

2926 

2927const first = await client.responses.create({

2928 model,

2929 input:

2930 "Summarize this shipment in one sentence: 17 red crates and 26 blue crates.",

2931 store: true,

2932});

2933 

2934const format = zodTextFormat(CrateCount, "crate_count");

2935const second = await client.responses.parse({

2936 model,

2937 previous_response_id: first.id,

2938 input: [

2939 { type: "configuration_update", text: { format } },

2940 { role: "user", content: "How many crates are in the shipment?" },

2941 ],

2942});

2943 

2944if (second.status === "completed" && second.output_parsed) {

2945 console.log(second.output_parsed.total_crates);

2946}

2947```

2948 

2949```python

2950from openai import OpenAI

2951from pydantic import BaseModel, ConfigDict

2952 

2953 

2954class CrateCount(BaseModel):

2955 model_config = ConfigDict(extra="forbid")

2956 total_crates: int

2957 

2958 

2959client = OpenAI()

2960model = "gpt-6-astra"

2961 

2962first = client.responses.create(

2963 model=model,

2964 input="Summarize this shipment in one sentence: 17 red crates and 26 blue crates.",

2965 store=True,

2966)

2967 

2968second = client.responses.parse(

2969 model=model,

2970 previous_response_id=first.id,

2971 input=[

2972 {

2973 "type": "configuration_update",

2974 "text": {

2975 "format": {

2976 "type": "json_schema",

2977 "name": "crate_count",

2978 "schema": CrateCount.model_json_schema(),

2979 "strict": True,

2980 }

2981 },

2982 },

2983 {"role": "user", "content": "How many crates are in the shipment?"},

2984 ],

2985 parse_as=CrateCount,

2986)

2987 

2988if second.status == "completed" and second.output_parsed is not None:

2989 print(second.output_parsed.total_crates)

2990```

2991 

2992```go

2993package main

2994 

2995import (

2996 "context"

2997 "fmt"

2998 

2999 "github.com/openai/openai-go/v3"

3000 "github.com/openai/openai-go/v3/responses"

3001)

3002 

3003func main() {

3004 client := openai.NewClient()

3005 ctx := context.Background()

3006 const model = "gpt-6-astra"

3007 first, err := client.Responses.New(ctx, responses.ResponseNewParams{

3008 Model: model,

3009 Input: responses.ResponseNewParamsInputUnion{

3010 OfString: openai.String("Summarize this shipment in one sentence: 17 red crates and 26 blue crates."),

3011 },

3012 Store: openai.Bool(true),

3013 })

3014 if err != nil {

3015 panic(err)

3016 }

3017 

3018 format := responses.ResponseFormatTextJSONSchemaConfigParam{

3019 Name: "crate_count",

3020 Schema: map[string]any{

3021 "type": "object",

3022 "properties": map[string]any{"total_crates": map[string]any{"type": "integer"}},

3023 "required": []string{"total_crates"},

3024 "additionalProperties": false,

3025 },

3026 Strict: openai.Bool(true),

3027 }

3028 second, err := client.Responses.New(ctx, responses.ResponseNewParams{

3029 Model: model,

3030 PreviousResponseID: openai.String(first.ID),

3031 Input: responses.ResponseNewParamsInputUnion{OfInputItemList: responses.ResponseInputParam{

3032 {OfConfigurationUpdate: &responses.ResponseConfigurationUpdateItemParam{

3033 Text: responses.ResponseConfigurationUpdateItemParamText{

3034 Format: responses.ResponseConfigurationUpdateItemParamTextFormatUnion{OfJSONSchema: &format},

3035 },

3036 }},

3037 responses.ResponseInputItemParamOfMessage("How many crates are in the shipment?", responses.EasyInputMessageRoleUser),

3038 }},

3039 })

3040 if err != nil {

3041 panic(err)

3042 }

3043 if second.Status != responses.ResponseStatusCompleted {

3044 return

3045 }

3046 for _, item := range second.Output {

3047 if item.Type != "message" || (item.Phase != "" && item.Phase != responses.ResponseOutputMessagePhaseFinalAnswer) {

3048 continue

3049 }

3050 for _, part := range item.Content {

3051 if part.Type == "output_text" {

3052 fmt.Println(part.Text)

3053 }

3054 }

3055 }

3056}

3057```

3058 

3059```java

3060import com.openai.core.JsonValue;

3061import com.openai.models.responses.EasyInputMessage;

3062import com.openai.models.responses.ResponseConfigurationUpdateItemParam;

3063import com.openai.models.responses.ResponseCreateParams;

3064import com.openai.models.responses.ResponseFormatTextJsonSchemaConfig;

3065import com.openai.models.responses.ResponseInputItem;

3066import com.openai.models.responses.ResponseOutputMessage;

3067import com.openai.models.responses.ResponseStatus;

3068import java.util.List;

3069import java.util.Map;

3070 

3071String model = "gpt-6-astra";

3072 

3073var first =

3074 client

3075 .responses()

3076 .create(

3077 ResponseCreateParams.builder()

3078 .model(model)

3079 .input(

3080 "Summarize this shipment in one sentence: 17 red crates and 26 blue crates.")

3081 .store(true)

3082 .build());

3083 

3084var schema =

3085 Map.of(

3086 "type",

3087 "object",

3088 "properties",

3089 Map.of("total_crates", Map.of("type", "integer")),

3090 "required",

3091 List.of("total_crates"),

3092 "additionalProperties",

3093 false);

3094var format =

3095 ResponseFormatTextJsonSchemaConfig.builder()

3096 .name("crate_count")

3097 .schema(JsonValue.from(schema).convert(ResponseFormatTextJsonSchemaConfig.Schema.class))

3098 .strict(true)

3099 .build();

3100var update =

3101 ResponseConfigurationUpdateItemParam.builder()

3102 .text(ResponseConfigurationUpdateItemParam.Text.builder().format(format).build())

3103 .build();

3104var question =

3105 EasyInputMessage.builder()

3106 .role(EasyInputMessage.Role.USER)

3107 .content("How many crates are in the shipment?")

3108 .build();

3109 

3110var second =

3111 client

3112 .responses()

3113 .create(

3114 ResponseCreateParams.builder()

3115 .model(model)

3116 .previousResponseId(first.id())

3117 .inputOfResponse(

3118 List.of(

3119 ResponseInputItem.ofConfigurationUpdate(update),

3120 ResponseInputItem.ofEasyInputMessage(question)))

3121 .build());

3122if (!ResponseStatus.COMPLETED.equals(second.status().orElse(null))) {

3123 return;

3124}

3125second.output().stream()

3126 .flatMap(item -> item.message().stream())

3127 .filter(

3128 message ->

3129 message.phase().map(ResponseOutputMessage.Phase.FINAL_ANSWER::equals).orElse(true))

3130 .flatMap(message -> message.content().stream())

3131 .flatMap(content -> content.outputText().stream())

3132 .forEach(text -> System.out.println(text.text()));

3133```

3134 

3135```ruby

3136# gem install openai sorbet-runtime

3137require "openai"

3138require "openai/helpers/sorbet"

3139 

3140class CrateCount < T::Struct

3141 const :total_crates, Integer

3142end

3143 

3144client = OpenAI::Client.new

3145model = "gpt-6-astra"

3146 

3147first = client.responses.create(

3148 model: model,

3149 input: "Summarize this shipment in one sentence: 17 red crates and 26 blue crates.",

3150 store: true

3151)

3152 

3153second = client.responses.create(

3154 model: model,

3155 previous_response_id: first.id,

3156 input: [

3157 {

3158 type: :configuration_update,

3159 text: {

3160 format: {

3161 type: :json_schema,

3162 name: "crate_count",

3163 schema: OpenAI::StructuredOutput.from_sorbet(CrateCount),

3164 strict: true

3165 }

3166 }

3167 },

3168 {

3169 role: :user,

3170 content: "How many crates are in the shipment?"

3171 }

3172 ]

3173)

3174 

3175if second.status == OpenAI::Responses::ResponseStatus::COMPLETED

3176 second.output.grep(OpenAI::Responses::ResponseOutputMessage).each do |message|

3177 next unless message.phase.nil? || message.phase == :final_answer

3178 

3179 message.content.grep(OpenAI::Responses::ResponseOutputText).each do |part|

3180 count = part.parsed

3181 case count

3182 when CrateCount

3183 puts count.total_crates

3184 end

3185 end

3186 end

3187end

3188```

3189 

3190 

3191The expected answer is `{"total_crates":43}`. The response object's `text.format` still reports the original request-level format. After checking for refusals and incomplete responses, parse the answer with the schema from the latest format update.

3192 

3193Each format update replaces the whole format. It stays in effect across turns, including when you update only `reasoning.effort`. To switch back to plain text, append `{"type":"configuration_update","text":{"format":{"type":"text"}}}`. Updates accept `json_schema` and `text` only.

3194 

3195If you replay history manually, keep each update in its original position. After explicit compaction, restate each setting you changed. See [configuration update compatibility](https://developers.openai.com/api/docs/guides/reasoning?api-mode=responses#change-reasoning-mid-conversation).

3196 

3197 

3198 

2905 3199 

2906 3200 

2907Refusals with Structured Outputs3201Refusals with Structured Outputs

Details

238```python238```python

239from apply_patch_harness import apply_operation # your implementation239from apply_patch_harness import apply_operation # your implementation

240 240 

241results = []241for turn in range(9):

242for call in patch_calls:242 if response.status != "completed":

243 op = call["operation"]243 raise RuntimeError(f"Patch response ended with status {response.status}")

244 success, maybe_log_output = apply_operation(op)244 if not patch_calls:

245 break

246 if turn == 8:

247 raise RuntimeError("Patch workflow exceeded eight tool turns")

245 248 

249 results = []

250 for call in patch_calls:

251 success, log_output = apply_operation(call["operation"])

246 results.append(252 results.append(

247 {253 {

248 "type": "apply_patch_call_output",254 "type": "apply_patch_call_output",

249 "call_id": call["call_id"],255 "call_id": call["call_id"],

250 "status": "completed" if success else "failed",256 "status": "completed" if success else "failed",

251 "output": maybe_log_output,257 "output": log_output,

252 }258 }

253 )259 )

254 260 

255followup = client.responses.create(261 response = client.responses.create(

256 model="gpt-6-astra",262 model="gpt-6-astra",

257 previous_response_id=response.id,263 previous_response_id=response.id,

258 input=results,264 input=results,

259 tools=[{"type": "apply_patch"}],265 tools=[{"type": "apply_patch"}],

260)266 )

267 patch_calls = [

268 item.model_dump() for item in response.output if item.type == "apply_patch_call"

269 ]

270 

271print(response.output_text)

261```272```

262 273 

263```go274```go


471```482```

472 483 

473```python484```python

485from pathlib import Path

486 

474from agents import Agent, ApplyPatchTool, Runner, apply_diff487from agents import Agent, ApplyPatchTool, Runner, apply_diff

475 488 

476 489 

477class WorkspaceEditor:490class WorkspaceEditor:

491 def __init__(self, root="workspace"):

492 self.root = Path(root).resolve()

493 self.root.mkdir(parents=True, exist_ok=True)

494 

495 def _path(self, name):

496 path = self.root / name

497 resolved = path.resolve()

498 if resolved == self.root or not resolved.is_relative_to(self.root):

499 raise ValueError("Patch paths must stay inside the workspace")

500 return path

501 

478 async def create_file(self, operation):502 async def create_file(self, operation):

479 # convert the diff to the file content

480 content = apply_diff("", operation.diff, mode="create")503 content = apply_diff("", operation.diff, mode="create")

481 # write the file content to the file system504 path = self._path(operation.path)

505 path.parent.mkdir(parents=True, exist_ok=True)

506 with path.open("x", encoding="utf-8") as file:

507 file.write(content)

482 return {"status": "completed", "output": f"Created {operation.path}"}508 return {"status": "completed", "output": f"Created {operation.path}"}

483 509 

484 async def update_file(self, operation):510 async def update_file(self, operation):

485 # read the file content from the file system511 path = self._path(operation.path)

486 current = ""512 content = apply_diff(path.read_text(encoding="utf-8"), operation.diff)

487 # convert the diff to the new file content513 path.write_text(content, encoding="utf-8")

488 new_content = apply_diff(current, operation.diff)

489 # write the updated file content to the file system

490 return {"status": "completed", "output": f"Updated {operation.path}"}514 return {"status": "completed", "output": f"Updated {operation.path}"}

491 515 

492 async def delete_file(self, operation):516 async def delete_file(self, operation):

493 # delete the file from the file system517 self._path(operation.path).unlink()

494 return {"status": "completed", "output": f"Deleted {operation.path}"}518 return {"status": "completed", "output": f"Deleted {operation.path}"}

495 519 

496 520 


499agent = Agent(523agent = Agent(

500 name="Patch Assistant",524 name="Patch Assistant",

501 model="gpt-6-astra",525 model="gpt-6-astra",

502 instructions="You can edit files inside the /tmp directory using the apply_patch tool.",526 instructions="Use apply_patch to edit files in the workspace. Supply paths relative to that workspace.",

503 tools=[527 tools=[

504 ApplyPatchTool(528 ApplyPatchTool(

505 editor=editor,529 editor=editor,

Details

296 )296 )

297 297 

298 def keypress(self, action):298 def keypress(self, action):

299 keys = tuple(action.keys)299 keys = tuple(key.upper() for key in action.keys)

300 if keys not in (("CTRL", "A"), ("CTRL", "S")):300 if keys not in (("CTRL", "A"), ("CTRL", "S")):

301 raise ValueError("Only Select All and Save are allowed.")301 raise ValueError(

302 f"Only Select All and Save are allowed; received {action.keys!r}."

303 )

302 self.focus_editor()304 self.focus_editor()

303 desktop("xdotool", "key", "--clearmodifiers", "ctrl+" + keys[1].lower())305 desktop("xdotool", "key", "--clearmodifiers", "ctrl+" + keys[1].lower())

304 306 


446 448 

447with sync_playwright() as p:449with sync_playwright() as p:

448 browser = p.chromium.launch(450 browser = p.chromium.launch(

449 headless=False,451 headless=True,

450 chromium_sandbox=True,452 chromium_sandbox=True,

451 env={},453 env={},

452 args=["--disable-extensions", "--disable-file-system"],454 args=["--disable-extensions", "--disable-file-system"],

Details

1210client = OpenAI()1210client = OpenAI()

1211container_id = "cntr_123"1211container_id = "cntr_123"

1212 1212 

1213deleted = client.containers.delete(container_id)1213client.containers.delete(container_id)

1214 1214 

1215print(deleted)1215print("Container deleted")

1216```1216```

1217 1217 

1218```go1218```go

Details

409 input="Use the csv-insights skill and run locally to summarize today's CSV reports in this repo.",409 input="Use the csv-insights skill and run locally to summarize today's CSV reports in this repo.",

410)410)

411 411 

412print(response.output_text)412# Execute returned shell calls locally and submit their shell_call_output to continue.

413print(response.output)

413```414```

414 415 

415```go416```go

Details

94 connection.response.create(94 connection.response.create(

95 model="gpt-6-astra",95 model="gpt-6-astra",

96 service_tier="ultrafast",96 service_tier="ultrafast",

97 store=False, # Keep this conversation on the current connection.

97 previous_response_id=previous_response_id,98 previous_response_id=previous_response_id,

98 input=prompt,99 input=prompt,

99 )100 )

Details

1424```python1424```python

1425tools = [1425tools = [

1426 {1426 {

1427 "type": "function",

1427 "name": "lookup_account",1428 "name": "lookup_account",

1428 "description": """Retrieve a customer account using either an email or phone number to enable verification and account-specific actions.1429 "description": """Retrieve a customer account using either an email or phone number to enable verification and account-specific actions.

1429 1430 


1442 },1443 },

1443 },1444 },

1444 {1445 {

1446 "type": "function",

1445 "name": "check_outage",1447 "name": "check_outage",

1446 "description": """Check for network outages affecting a given service address and return status and ETA if applicable.1448 "description": """Check for network outages affecting a given service address and return status and ETA if applicable.

1447 1449 


2038 return {2040 return {

2039 "type": "session.update",2041 "type": "session.update",

2040 "session": {2042 "session": {

2043 "type": "realtime",

2041 "instructions": INSTRUCTIONS_BY_STATE[state],2044 "instructions": INSTRUCTIONS_BY_STATE[state],

2042 "tools": TOOLS_BY_STATE[state] + [build_state_change_tool(state)],2045 "tools": TOOLS_BY_STATE[state] + [build_state_change_tool(state)],

2043 },2046 },

Details

783def on_message(ws, message):783def on_message(ws, message):

784 global session_created784 global session_created

785 data = json.loads(message)785 data = json.loads(message)

786 print("Received event:", json.dumps(data, indent=2))

787 if data["type"] == "session.created":786 if data["type"] == "session.created":

788 session_created = True787 session_created = True

789 print("Connected to the Realtime API.")788 print("Connected to the Realtime API:", data["session"]["id"])

790 ws.close()789 ws.close()

791 elif data["type"] == "error":790 elif data["type"] == "error":

792 ws.close()791 ws.close()

Details

16 16 

17Install the WebSocket dependencies with `pip install "openai[realtime]>=3.8.0"` for Python, `npm install openai@^7.10.0 ws` for JavaScript, or `gem install openai async-websocket` for Ruby.17Install the WebSocket dependencies with `pip install "openai[realtime]>=3.8.0"` for Python, `npm install openai@^7.10.0 ws` for JavaScript, or `gem install openai async-websocket` for Ruby.

18 18 

19For Go, run `go get github.com/openai/openai-go/v3@v3.85.1`.19For Go, run `go get github.com/openai/openai-go/v3@v3.91.0`.

20For Java, add the Maven dependency `com.openai:openai-java:4.90.0` and use Java 17 or later for these examples.20For Java, add the Maven dependency `com.openai:openai-java:4.95.0` and use Java 17 or later for these examples.

21These Go and Java SDK versions provide native Responses WebSocket support.21These Go and Java SDK versions provide native Responses WebSocket support.

22 22 

23In WebSocket mode, start each turn by sending a `response.create` event from the client. The payload mirrors the normal [Responses create body](https://developers.openai.com/api/reference/resources/responses/methods/create), except that transport-specific fields like `stream` and `background` are not used.23In WebSocket mode, start each turn by sending a `response.create` event from the client. The payload mirrors the normal [Responses create body](https://developers.openai.com/api/reference/resources/responses/methods/create), except that transport-specific fields like `stream` and `background` are not used.

mcp.md +1 −1

Details

335 file_content = "No content available"335 file_content = "No content available"

336 336 

337 # Use filename as title and create proper URL for citations337 # Use filename as title and create proper URL for citations

338 filename = getattr(file_info, "filename", f"Document {id}")338 filename = openai_client.files.retrieve(file_id=id).filename

339 339 

340 result = FetchOutput(340 result = FetchOutput(

341 id=id,341 id=id,

Details

72from bs4 import BeautifulSoup72from bs4 import BeautifulSoup

73from collections import deque73from collections import deque

74from html.parser import HTMLParser74from html.parser import HTMLParser

75from urllib.parse import urlparse75from urllib.parse import urldefrag, urljoin, urlparse

76import os76import os

77 77 

78# Regex pattern to match a URL78# Regex pattern to match a URL


130```python130```python

131# Function to get the hyperlinks from a URL that are within the same domain131# Function to get the hyperlinks from a URL that are within the same domain

132def get_domain_hyperlinks(local_domain, url):132def get_domain_hyperlinks(local_domain, url):

133 clean_links = []133 links = set()

134 for link in set(get_hyperlinks(url)):134 for link in get_hyperlinks(url):

135 clean_link = None135 if not link or link.startswith("#"):

136 

137 # If the link is a URL, check if it is within the same domain

138 if re.search(HTTP_URL_PATTERN, link):

139 # Parse the URL and check if the domain is the same

140 url_obj = urlparse(link)

141 if url_obj.netloc == local_domain:

142 clean_link = link

143 

144 # If the link is not a URL, check if it is a relative link

145 else:

146 if link.startswith("/"):

147 link = link[1:]

148 elif link.startswith("#") or link.startswith("mailto:"):

149 continue136 continue

150 clean_link = "https://" + local_domain + "/" + link137 candidate, _ = urldefrag(urljoin(url, link))

151 138 parsed = urlparse(candidate)

152 if clean_link is not None:139 if parsed.scheme in {"http", "https"} and parsed.netloc == local_domain:

153 if clean_link.endswith("/"):140 links.add(candidate)

154 clean_link = clean_link[:-1]141 return list(links)

155 clean_links.append(clean_link)

156 

157 # Return the list of hyperlinks that are within the same domain

158 return list(set(clean_links))

159```142```

160 143 

161 144 


164```python147```python

165def crawl(url):148def crawl(url):

166 # Parse the URL and get the domain149 # Parse the URL and get the domain

167 local_domain = urlparse(url).netloc150 parsed = urlparse(url)

151 local_domain = parsed.netloc

152 url = parsed._replace(path=parsed.path or "/").geturl()

168 153 

169 # Create a queue to store the URLs to crawl154 # Create a queue to store the URLs to crawl

170 queue = deque([url])155 queue = deque([url])


353 338 

354# Function to split the text into chunks of a maximum number of tokens339# Function to split the text into chunks of a maximum number of tokens

355def split_into_many(text, max_tokens=max_tokens):340def split_into_many(text, max_tokens=max_tokens):

341 if max_tokens < 1:

342 raise ValueError("max_tokens must be positive.")

343 if not text.strip():

344 return []

356 345 

357 # Split the text into sentences

358 sentences = text.split(". ")346 sentences = text.split(". ")

359 

360 # Get the number of tokens for each sentence

361 n_tokens = [len(tokenizer.encode(" " + sentence)) for sentence in sentences]

362 

363 chunks = []347 chunks = []

364 tokens_so_far = 0348 chunk = ""

365 chunk = []349 for index, sentence in enumerate(sentences):

366 350 if index < len(sentences) - 1:

367 # Loop through the sentences and tokens joined together in a tuple351 sentence += "."

368 for sentence, token in zip(sentences, n_tokens):352 # Do not silently discard a sentence that needs finer-grained splitting.

369 # If the number of tokens so far plus the number of tokens in the current sentence is greater353 if len(tokenizer.encode(sentence)) > max_tokens:

370 # than the max number of tokens, then add the chunk to the list of chunks and reset354 raise ValueError("A sentence exceeds max_tokens; split it before chunking.")

371 # the chunk and tokens so far355 

372 if tokens_so_far + token > max_tokens:356 candidate = f"{chunk} {sentence}" if chunk else sentence

373 chunks.append(". ".join(chunk) + ".")357 if len(tokenizer.encode(candidate)) > max_tokens:

374 chunk = []358 chunks.append(chunk)

375 tokens_so_far = 0359 chunk = sentence

376 360 else:

377 # If the number of tokens in the current sentence is greater than the max number of361 chunk = candidate

378 # tokens, go to the next sentence

379 if token > max_tokens:

380 continue

381 

382 # Otherwise, add the sentence to the chunk and add the number of tokens to the total

383 chunk.append(sentence)

384 tokens_so_far += token + 1

385 362 

363 if chunk:

364 chunks.append(chunk)

386 return chunks365 return chunks

387 366 

388 367 


471Turning the embeddings into a NumPy array is the first step, which will provide more flexibility in how to use it given the many functions available that operate on NumPy arrays. It will also flatten the dimension to 1-D, which is the required format for many subsequent operations.450Turning the embeddings into a NumPy array is the first step, which will provide more flexibility in how to use it given the many functions available that operate on NumPy arrays. It will also flatten the dimension to 1-D, which is the required format for many subsequent operations.

472 451 

473```python452```python

453from ast import literal_eval

474import numpy as np454import numpy as np

475 455 

476df = pd.read_csv("processed/embeddings.csv", index_col=0)456df = pd.read_csv("processed/embeddings.csv", index_col=0)

477df["embeddings"] = df["embeddings"].apply(eval).apply(np.array)457df["embeddings"] = df["embeddings"].apply(literal_eval).apply(np.array)

478 458 

479df.head()459df.head()

480```460```