openai-agents 0.2.10__py3-none-any.whl → 0.2.11__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of openai-agents might be problematic. Click here for more details.

@@ -433,7 +433,7 @@ class Converter:
433
433
  converted_tool = {
434
434
  "type": "web_search",
435
435
  "filters": tool.filters.model_dump() if tool.filters is not None else None, # type: ignore [typeddict-item]
436
- "user_location": tool.user_location, # type: ignore [typeddict-item]
436
+ "user_location": tool.user_location,
437
437
  "search_context_size": tool.search_context_size,
438
438
  }
439
439
  includes = None
agents/realtime/model.py CHANGED
@@ -118,6 +118,12 @@ class RealtimeModelConfig(TypedDict):
118
118
  the OpenAI Realtime model will use the default OpenAI WebSocket URL.
119
119
  """
120
120
 
121
+ headers: NotRequired[dict[str, str]]
122
+ """The headers to use when connecting. If unset, the model will use a sane default.
123
+ Note that, when you set this, authorization header won't be set under the hood.
124
+ e.g., {"api-key": "your api key here"} for Azure OpenAI Realtime WebSocket connections.
125
+ """
126
+
121
127
  initial_model_settings: NotRequired[RealtimeSessionModelSettings]
122
128
  """The initial model settings to use when connecting."""
123
129
 
@@ -188,15 +188,23 @@ class OpenAIRealtimeWebSocketModel(RealtimeModel):
188
188
  else:
189
189
  self._tracing_config = "auto"
190
190
 
191
- if not api_key:
192
- raise UserError("API key is required but was not provided.")
193
-
194
191
  url = options.get("url", f"wss://api.openai.com/v1/realtime?model={self.model}")
195
192
 
196
- headers = {
197
- "Authorization": f"Bearer {api_key}",
198
- "OpenAI-Beta": "realtime=v1",
199
- }
193
+ headers: dict[str, str] = {}
194
+ if options.get("headers") is not None:
195
+ # For customizing request headers
196
+ headers.update(options["headers"])
197
+ else:
198
+ # OpenAI's Realtime API
199
+ if not api_key:
200
+ raise UserError("API key is required but was not provided.")
201
+
202
+ headers.update(
203
+ {
204
+ "Authorization": f"Bearer {api_key}",
205
+ "OpenAI-Beta": "realtime=v1",
206
+ }
207
+ )
200
208
  self._websocket = await websockets.connect(
201
209
  url,
202
210
  user_agent_header=_USER_AGENT,
@@ -490,9 +498,7 @@ class OpenAIRealtimeWebSocketModel(RealtimeModel):
490
498
  try:
491
499
  if "previous_item_id" in event and event["previous_item_id"] is None:
492
500
  event["previous_item_id"] = "" # TODO (rm) remove
493
- parsed: AllRealtimeServerEvents = self._server_event_type_adapter.validate_python(
494
- event
495
- )
501
+ parsed: AllRealtimeServerEvents = self._server_event_type_adapter.validate_python(event)
496
502
  except pydantic.ValidationError as e:
497
503
  logger.error(f"Failed to validate server event: {event}", exc_info=True)
498
504
  await self._emit_event(
@@ -583,11 +589,13 @@ class OpenAIRealtimeWebSocketModel(RealtimeModel):
583
589
  ):
584
590
  await self._handle_output_item(parsed.item)
585
591
  elif parsed.type == "input_audio_buffer.timeout_triggered":
586
- await self._emit_event(RealtimeModelInputAudioTimeoutTriggeredEvent(
587
- item_id=parsed.item_id,
588
- audio_start_ms=parsed.audio_start_ms,
589
- audio_end_ms=parsed.audio_end_ms,
590
- ))
592
+ await self._emit_event(
593
+ RealtimeModelInputAudioTimeoutTriggeredEvent(
594
+ item_id=parsed.item_id,
595
+ audio_start_ms=parsed.audio_start_ms,
596
+ audio_end_ms=parsed.audio_end_ms,
597
+ )
598
+ )
591
599
 
592
600
  def _update_created_session(self, session: OpenAISessionObject) -> None:
593
601
  self._created_session = session
agents/run.py CHANGED
@@ -8,7 +8,7 @@ from typing import Any, Callable, Generic, cast, get_args
8
8
 
9
9
  from openai.types.responses import (
10
10
  ResponseCompletedEvent,
11
- ResponseOutputItemAddedEvent,
11
+ ResponseOutputItemDoneEvent,
12
12
  )
13
13
  from openai.types.responses.response_prompt_param import (
14
14
  ResponsePromptParam,
@@ -994,10 +994,16 @@ class AgentRunner:
994
994
  )
995
995
 
996
996
  # Call hook just before the model is invoked, with the correct system_prompt.
997
- if agent.hooks:
998
- await agent.hooks.on_llm_start(
999
- context_wrapper, agent, filtered.instructions, filtered.input
1000
- )
997
+ await asyncio.gather(
998
+ hooks.on_llm_start(context_wrapper, agent, filtered.instructions, filtered.input),
999
+ (
1000
+ agent.hooks.on_llm_start(
1001
+ context_wrapper, agent, filtered.instructions, filtered.input
1002
+ )
1003
+ if agent.hooks
1004
+ else _coro.noop_coroutine()
1005
+ ),
1006
+ )
1001
1007
 
1002
1008
  # 1. Stream the output events
1003
1009
  async for event in model.stream_response(
@@ -1034,7 +1040,7 @@ class AgentRunner:
1034
1040
  )
1035
1041
  context_wrapper.usage.add(usage)
1036
1042
 
1037
- if isinstance(event, ResponseOutputItemAddedEvent):
1043
+ if isinstance(event, ResponseOutputItemDoneEvent):
1038
1044
  output_item = event.item
1039
1045
 
1040
1046
  if isinstance(output_item, _TOOL_CALL_TYPES):
@@ -1056,8 +1062,15 @@ class AgentRunner:
1056
1062
  streamed_result._event_queue.put_nowait(RawResponsesStreamEvent(data=event))
1057
1063
 
1058
1064
  # Call hook just after the model response is finalized.
1059
- if agent.hooks and final_response is not None:
1060
- await agent.hooks.on_llm_end(context_wrapper, agent, final_response)
1065
+ if final_response is not None:
1066
+ await asyncio.gather(
1067
+ (
1068
+ agent.hooks.on_llm_end(context_wrapper, agent, final_response)
1069
+ if agent.hooks
1070
+ else _coro.noop_coroutine()
1071
+ ),
1072
+ hooks.on_llm_end(context_wrapper, agent, final_response),
1073
+ )
1061
1074
 
1062
1075
  # 2. At this point, the streaming is complete for this turn of the agent loop.
1063
1076
  if not final_response:
@@ -1150,6 +1163,7 @@ class AgentRunner:
1150
1163
  output_schema,
1151
1164
  all_tools,
1152
1165
  handoffs,
1166
+ hooks,
1153
1167
  context_wrapper,
1154
1168
  run_config,
1155
1169
  tool_use_tracker,
@@ -1345,6 +1359,7 @@ class AgentRunner:
1345
1359
  output_schema: AgentOutputSchemaBase | None,
1346
1360
  all_tools: list[Tool],
1347
1361
  handoffs: list[Handoff],
1362
+ hooks: RunHooks[TContext],
1348
1363
  context_wrapper: RunContextWrapper[TContext],
1349
1364
  run_config: RunConfig,
1350
1365
  tool_use_tracker: AgentToolUseTracker,
@@ -1364,14 +1379,21 @@ class AgentRunner:
1364
1379
  model = cls._get_model(agent, run_config)
1365
1380
  model_settings = agent.model_settings.resolve(run_config.model_settings)
1366
1381
  model_settings = RunImpl.maybe_reset_tool_choice(agent, tool_use_tracker, model_settings)
1367
- # If the agent has hooks, we need to call them before and after the LLM call
1368
- if agent.hooks:
1369
- await agent.hooks.on_llm_start(
1370
- context_wrapper,
1371
- agent,
1372
- filtered.instructions, # Use filtered instructions
1373
- filtered.input, # Use filtered input
1374
- )
1382
+
1383
+ # If we have run hooks, or if the agent has hooks, we need to call them before the LLM call
1384
+ await asyncio.gather(
1385
+ hooks.on_llm_start(context_wrapper, agent, filtered.instructions, filtered.input),
1386
+ (
1387
+ agent.hooks.on_llm_start(
1388
+ context_wrapper,
1389
+ agent,
1390
+ filtered.instructions, # Use filtered instructions
1391
+ filtered.input, # Use filtered input
1392
+ )
1393
+ if agent.hooks
1394
+ else _coro.noop_coroutine()
1395
+ ),
1396
+ )
1375
1397
 
1376
1398
  new_response = await model.get_response(
1377
1399
  system_instructions=filtered.instructions,
@@ -1387,12 +1409,19 @@ class AgentRunner:
1387
1409
  conversation_id=conversation_id,
1388
1410
  prompt=prompt_config,
1389
1411
  )
1390
- # If the agent has hooks, we need to call them after the LLM call
1391
- if agent.hooks:
1392
- await agent.hooks.on_llm_end(context_wrapper, agent, new_response)
1393
1412
 
1394
1413
  context_wrapper.usage.add(new_response.usage)
1395
1414
 
1415
+ # If we have run hooks, or if the agent has hooks, we need to call them after the LLM call
1416
+ await asyncio.gather(
1417
+ (
1418
+ agent.hooks.on_llm_end(context_wrapper, agent, new_response)
1419
+ if agent.hooks
1420
+ else _coro.noop_coroutine()
1421
+ ),
1422
+ hooks.on_llm_end(context_wrapper, agent, new_response),
1423
+ )
1424
+
1396
1425
  return new_response
1397
1426
 
1398
1427
  @classmethod
agents/tool.py CHANGED
@@ -12,8 +12,8 @@ from openai.types.responses.response_computer_tool_call import (
12
12
  ResponseComputerToolCall,
13
13
  )
14
14
  from openai.types.responses.response_output_item import LocalShellCall, McpApprovalRequest
15
- from openai.types.responses.tool import WebSearchToolFilters
16
15
  from openai.types.responses.tool_param import CodeInterpreter, ImageGeneration, Mcp
16
+ from openai.types.responses.web_search_tool import Filters as WebSearchToolFilters
17
17
  from openai.types.responses.web_search_tool_param import UserLocation
18
18
  from pydantic import ValidationError
19
19
  from typing_extensions import Concatenate, NotRequired, ParamSpec, TypedDict
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: openai-agents
3
- Version: 0.2.10
3
+ Version: 0.2.11
4
4
  Summary: OpenAI Agents SDK
5
5
  Project-URL: Homepage, https://openai.github.io/openai-agents-python/
6
6
  Project-URL: Repository, https://github.com/openai/openai-agents-python
@@ -21,7 +21,7 @@ Classifier: Typing :: Typed
21
21
  Requires-Python: >=3.9
22
22
  Requires-Dist: griffe<2,>=1.5.6
23
23
  Requires-Dist: mcp<2,>=1.11.0; python_version >= '3.10'
24
- Requires-Dist: openai<2,>=1.102.0
24
+ Requires-Dist: openai<2,>=1.104.1
25
25
  Requires-Dist: pydantic<3,>=2.10
26
26
  Requires-Dist: requests<3,>=2.0
27
27
  Requires-Dist: types-requests<3,>=2.0
@@ -17,11 +17,11 @@ agents/prompts.py,sha256=Ss5y_7s2HFcRAOAKu4WTxQszs5ybI8TfbxgEYdnj9sg,2231
17
17
  agents/py.typed,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
18
18
  agents/repl.py,sha256=NX0BE5YDnmGQ2rdQsmLm3CKkQZ5m4GC95xXmUsAXJVs,2539
19
19
  agents/result.py,sha256=YCGYHoc5X1_vLKu5QiK6F8C1ZXI3tTfLXaZoqbYgUMA,10753
20
- agents/run.py,sha256=sEqyIa5MAbOFOmDv5qp2BrJN8TizwiyiSo_q19Ca2gc,61298
20
+ agents/run.py,sha256=pPVHg6NexEriaBSAOHjDaioEi5pKnEcUXkSaofIxtNM,62260
21
21
  agents/run_context.py,sha256=vuSUQM8O4CLensQY27-22fOqECnw7yvwL9U3WO8b_bk,851
22
22
  agents/stream_events.py,sha256=VFyTu-DT3ZMnHLtMbg-X_lxec0doQxNfx-hVxLB0BpI,1700
23
23
  agents/strict_schema.py,sha256=_KuEJkglmq-Fj3HSeYP4WqTvqrxbSKu6gezfz5Brhh0,5775
24
- agents/tool.py,sha256=jOmz-EMmROCERdGgOQaJyvY6ZyyNz93ByBc4y-loisQ,17009
24
+ agents/tool.py,sha256=1B2GgRlPIAhiS4uxzot9mpdaAOJyIKzikzCzIDPawDE,17031
25
25
  agents/tool_context.py,sha256=lbnctijZeanXAThddkklF7vDrXK1Ie2_wx6JZPCOihI,1434
26
26
  agents/usage.py,sha256=Tb5udGd3DPgD0JBdRD8fDctTE4M-zKML5uRn8ZG1yBc,1675
27
27
  agents/version.py,sha256=_1knUwzSK-HUeZTpRUkk6Z-CIcurqXuEplbV5TLJ08E,230
@@ -52,7 +52,7 @@ agents/models/interface.py,sha256=-AFUHC8iRuGZmtQwguDw4s-M4OPL2y2mct4TAmWvVrU,40
52
52
  agents/models/multi_provider.py,sha256=aiDbls5G4YomPfN6qH1pGlj41WS5jlDp2T82zm6qcnM,5578
53
53
  agents/models/openai_chatcompletions.py,sha256=abwQj8CqUHa2KB4NC_DVeJhZOygyAnr4N4maZtYhchU,13321
54
54
  agents/models/openai_provider.py,sha256=vBu3mlgDBrI_cZVVmfnWBHoPlJlsmld3lfdX8sNQQAM,3624
55
- agents/models/openai_responses.py,sha256=XFR8gl25V4ZiyCIqExU3Xk4Lxtxh-afcFSuVJCeYwII,18255
55
+ agents/models/openai_responses.py,sha256=MagaTTlq0tpTzQbOiSHHLOURcthu_dnNp71Lwq3lqjs,18222
56
56
  agents/realtime/README.md,sha256=5YCYXH5ULmlWoWo1PE9TlbHjeYgjnp-xY8ZssSFY2Vk,126
57
57
  agents/realtime/__init__.py,sha256=7qvzK8QJuHRnPHxDgDj21v8-lnSN4Uurg9znwJv_Tqg,4923
58
58
  agents/realtime/_default_tracker.py,sha256=4OMxBvD1MnZmMn6JZYKL42uWhVzvK6NdDLDfPP54d78,1765
@@ -62,10 +62,10 @@ agents/realtime/config.py,sha256=49ZsKY9ySBFRfiL3RGWW1aVNhahzmoNATb3Buj2npJk,596
62
62
  agents/realtime/events.py,sha256=eANiNNyYlp_1Ybdl-MOwXRVTDtrK9hfgn6iw0xNxnaY,5889
63
63
  agents/realtime/handoffs.py,sha256=avLFix5kEutel57IRcddssGiVHzGptOzWL9OqPaLVh8,6702
64
64
  agents/realtime/items.py,sha256=psT6AH65qmngmPsgwk6CXacVo5tEDYq0Za3EitHFpTA,5052
65
- agents/realtime/model.py,sha256=RJBA8-Dkd2JTqGzbKacoX4dN_qTWn_p7npL73To3ymw,6143
65
+ agents/realtime/model.py,sha256=Lnb9pEcvnlIdXJUcldVyioaX5lpmrBou5FZoNJe4XfA,6457
66
66
  agents/realtime/model_events.py,sha256=YixBKmzlCrhtzCosj0SysyZpyHbZ90455gDr4Kr7Ey8,4338
67
67
  agents/realtime/model_inputs.py,sha256=OW2bn3wD5_pXLunDUf35jhG2q_bTKbC_D7Qu-83aOEA,2243
68
- agents/realtime/openai_realtime.py,sha256=cVOxBYNwqn38WTSVK-A2E2pHrw0bGSmren2q7670pPU,31361
68
+ agents/realtime/openai_realtime.py,sha256=MVg_OzVLmC7vHWr580P42TJlY32PzGAvY40JaUmM6x0,31676
69
69
  agents/realtime/runner.py,sha256=KfU7utmc9QFH2htIKN2IN9H-5EnB0qN9ezmvlRTnOm4,2511
70
70
  agents/realtime/session.py,sha256=hPIxQSsVh5whkgYnEpxk_AgvG3suuDVnpPyqVoPJBRM,26822
71
71
  agents/tracing/__init__.py,sha256=5HO_6na5S6EwICgwl50OMtxiIIosUrqalhvldlYvSVc,2991
@@ -102,7 +102,7 @@ agents/voice/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSu
102
102
  agents/voice/models/openai_model_provider.py,sha256=Khn0uT-VhsEbe7_OhBMGFQzXNwL80gcWZyTHl3CaBII,3587
103
103
  agents/voice/models/openai_stt.py,sha256=LcVDS7f1pmbm--PWX-IaV9uLg9uv5_L3vSCbVnTJeGs,16864
104
104
  agents/voice/models/openai_tts.py,sha256=4KoLQuFDHKu5a1VTJlu9Nj3MHwMlrn9wfT_liJDJ2dw,1477
105
- openai_agents-0.2.10.dist-info/METADATA,sha256=1imjcLQahGjZnwblAnDOdGVUJBXcLkG-3IG1xYlAEfw,12381
106
- openai_agents-0.2.10.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
107
- openai_agents-0.2.10.dist-info/licenses/LICENSE,sha256=E994EspT7Krhy0qGiES7WYNzBHrh1YDk3r--8d1baRU,1063
108
- openai_agents-0.2.10.dist-info/RECORD,,
105
+ openai_agents-0.2.11.dist-info/METADATA,sha256=Uo-6qX652GabhL5x0gMkYNoLCaXx4maS2xfavemZeJ8,12381
106
+ openai_agents-0.2.11.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
107
+ openai_agents-0.2.11.dist-info/licenses/LICENSE,sha256=E994EspT7Krhy0qGiES7WYNzBHrh1YDk3r--8d1baRU,1063
108
+ openai_agents-0.2.11.dist-info/RECORD,,