openai-agents 0.0.16__py3-none-any.whl → 0.0.17__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.
- agents/__init__.py +2 -0
- agents/_run_impl.py +4 -0
- agents/agent.py +19 -3
- agents/agent_output.py +1 -1
- agents/exceptions.py +38 -5
- agents/extensions/models/litellm_model.py +2 -1
- agents/extensions/visualization.py +35 -18
- agents/handoffs.py +1 -1
- agents/mcp/server.py +5 -5
- agents/mcp/util.py +1 -1
- agents/models/openai_chatcompletions.py +17 -5
- agents/result.py +43 -13
- agents/run.py +33 -6
- agents/stream_events.py +1 -0
- agents/tool.py +16 -1
- agents/tracing/processors.py +29 -3
- agents/util/_pretty_print.py +12 -0
- agents/voice/model.py +2 -0
- {openai_agents-0.0.16.dist-info → openai_agents-0.0.17.dist-info}/METADATA +1 -1
- {openai_agents-0.0.16.dist-info → openai_agents-0.0.17.dist-info}/RECORD +22 -22
- {openai_agents-0.0.16.dist-info → openai_agents-0.0.17.dist-info}/WHEEL +0 -0
- {openai_agents-0.0.16.dist-info → openai_agents-0.0.17.dist-info}/licenses/LICENSE +0 -0
agents/__init__.py
CHANGED
|
@@ -14,6 +14,7 @@ from .exceptions import (
|
|
|
14
14
|
MaxTurnsExceeded,
|
|
15
15
|
ModelBehaviorError,
|
|
16
16
|
OutputGuardrailTripwireTriggered,
|
|
17
|
+
RunErrorDetails,
|
|
17
18
|
UserError,
|
|
18
19
|
)
|
|
19
20
|
from .guardrail import (
|
|
@@ -204,6 +205,7 @@ __all__ = [
|
|
|
204
205
|
"AgentHooks",
|
|
205
206
|
"RunContextWrapper",
|
|
206
207
|
"TContext",
|
|
208
|
+
"RunErrorDetails",
|
|
207
209
|
"RunResult",
|
|
208
210
|
"RunResultStreaming",
|
|
209
211
|
"RunConfig",
|
agents/_run_impl.py
CHANGED
|
@@ -33,6 +33,7 @@ from openai.types.responses.response_output_item import (
|
|
|
33
33
|
ImageGenerationCall,
|
|
34
34
|
LocalShellCall,
|
|
35
35
|
McpApprovalRequest,
|
|
36
|
+
McpCall,
|
|
36
37
|
McpListTools,
|
|
37
38
|
)
|
|
38
39
|
from openai.types.responses.response_reasoning_item import ResponseReasoningItem
|
|
@@ -456,6 +457,9 @@ class RunImpl:
|
|
|
456
457
|
)
|
|
457
458
|
elif isinstance(output, McpListTools):
|
|
458
459
|
items.append(MCPListToolsItem(raw_item=output, agent=agent))
|
|
460
|
+
elif isinstance(output, McpCall):
|
|
461
|
+
items.append(ToolCallItem(raw_item=output, agent=agent))
|
|
462
|
+
tools_used.append("mcp")
|
|
459
463
|
elif isinstance(output, ImageGenerationCall):
|
|
460
464
|
items.append(ToolCallItem(raw_item=output, agent=agent))
|
|
461
465
|
tools_used.append("image_generation")
|
agents/agent.py
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
+
import asyncio
|
|
3
4
|
import dataclasses
|
|
4
5
|
import inspect
|
|
5
6
|
from collections.abc import Awaitable
|
|
@@ -17,7 +18,7 @@ from .mcp import MCPUtil
|
|
|
17
18
|
from .model_settings import ModelSettings
|
|
18
19
|
from .models.interface import Model
|
|
19
20
|
from .run_context import RunContextWrapper, TContext
|
|
20
|
-
from .tool import FunctionToolResult, Tool, function_tool
|
|
21
|
+
from .tool import FunctionTool, FunctionToolResult, Tool, function_tool
|
|
21
22
|
from .util import _transforms
|
|
22
23
|
from .util._types import MaybeAwaitable
|
|
23
24
|
|
|
@@ -246,7 +247,22 @@ class Agent(Generic[TContext]):
|
|
|
246
247
|
convert_schemas_to_strict = self.mcp_config.get("convert_schemas_to_strict", False)
|
|
247
248
|
return await MCPUtil.get_all_function_tools(self.mcp_servers, convert_schemas_to_strict)
|
|
248
249
|
|
|
249
|
-
async def get_all_tools(self) -> list[Tool]:
|
|
250
|
+
async def get_all_tools(self, run_context: RunContextWrapper[Any]) -> list[Tool]:
|
|
250
251
|
"""All agent tools, including MCP tools and function tools."""
|
|
251
252
|
mcp_tools = await self.get_mcp_tools()
|
|
252
|
-
|
|
253
|
+
|
|
254
|
+
async def _check_tool_enabled(tool: Tool) -> bool:
|
|
255
|
+
if not isinstance(tool, FunctionTool):
|
|
256
|
+
return True
|
|
257
|
+
|
|
258
|
+
attr = tool.is_enabled
|
|
259
|
+
if isinstance(attr, bool):
|
|
260
|
+
return attr
|
|
261
|
+
res = attr(run_context, self)
|
|
262
|
+
if inspect.isawaitable(res):
|
|
263
|
+
return bool(await res)
|
|
264
|
+
return bool(res)
|
|
265
|
+
|
|
266
|
+
results = await asyncio.gather(*(_check_tool_enabled(t) for t in self.tools))
|
|
267
|
+
enabled: list[Tool] = [t for t, ok in zip(self.tools, results) if ok]
|
|
268
|
+
return [*mcp_tools, *enabled]
|
agents/agent_output.py
CHANGED
|
@@ -38,7 +38,7 @@ class AgentOutputSchemaBase(abc.ABC):
|
|
|
38
38
|
@abc.abstractmethod
|
|
39
39
|
def is_strict_json_schema(self) -> bool:
|
|
40
40
|
"""Whether the JSON schema is in strict mode. Strict mode constrains the JSON schema
|
|
41
|
-
features, but guarantees
|
|
41
|
+
features, but guarantees valid JSON. See here for details:
|
|
42
42
|
https://platform.openai.com/docs/guides/structured-outputs#supported-schemas
|
|
43
43
|
"""
|
|
44
44
|
pass
|
agents/exceptions.py
CHANGED
|
@@ -1,12 +1,42 @@
|
|
|
1
|
-
from
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from dataclasses import dataclass
|
|
4
|
+
from typing import TYPE_CHECKING, Any
|
|
2
5
|
|
|
3
6
|
if TYPE_CHECKING:
|
|
7
|
+
from .agent import Agent
|
|
4
8
|
from .guardrail import InputGuardrailResult, OutputGuardrailResult
|
|
9
|
+
from .items import ModelResponse, RunItem, TResponseInputItem
|
|
10
|
+
from .run_context import RunContextWrapper
|
|
11
|
+
|
|
12
|
+
from .util._pretty_print import pretty_print_run_error_details
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@dataclass
|
|
16
|
+
class RunErrorDetails:
|
|
17
|
+
"""Data collected from an agent run when an exception occurs."""
|
|
18
|
+
|
|
19
|
+
input: str | list[TResponseInputItem]
|
|
20
|
+
new_items: list[RunItem]
|
|
21
|
+
raw_responses: list[ModelResponse]
|
|
22
|
+
last_agent: Agent[Any]
|
|
23
|
+
context_wrapper: RunContextWrapper[Any]
|
|
24
|
+
input_guardrail_results: list[InputGuardrailResult]
|
|
25
|
+
output_guardrail_results: list[OutputGuardrailResult]
|
|
26
|
+
|
|
27
|
+
def __str__(self) -> str:
|
|
28
|
+
return pretty_print_run_error_details(self)
|
|
5
29
|
|
|
6
30
|
|
|
7
31
|
class AgentsException(Exception):
|
|
8
32
|
"""Base class for all exceptions in the Agents SDK."""
|
|
9
33
|
|
|
34
|
+
run_data: RunErrorDetails | None
|
|
35
|
+
|
|
36
|
+
def __init__(self, *args: object) -> None:
|
|
37
|
+
super().__init__(*args)
|
|
38
|
+
self.run_data = None
|
|
39
|
+
|
|
10
40
|
|
|
11
41
|
class MaxTurnsExceeded(AgentsException):
|
|
12
42
|
"""Exception raised when the maximum number of turns is exceeded."""
|
|
@@ -15,6 +45,7 @@ class MaxTurnsExceeded(AgentsException):
|
|
|
15
45
|
|
|
16
46
|
def __init__(self, message: str):
|
|
17
47
|
self.message = message
|
|
48
|
+
super().__init__(message)
|
|
18
49
|
|
|
19
50
|
|
|
20
51
|
class ModelBehaviorError(AgentsException):
|
|
@@ -26,6 +57,7 @@ class ModelBehaviorError(AgentsException):
|
|
|
26
57
|
|
|
27
58
|
def __init__(self, message: str):
|
|
28
59
|
self.message = message
|
|
60
|
+
super().__init__(message)
|
|
29
61
|
|
|
30
62
|
|
|
31
63
|
class UserError(AgentsException):
|
|
@@ -35,15 +67,16 @@ class UserError(AgentsException):
|
|
|
35
67
|
|
|
36
68
|
def __init__(self, message: str):
|
|
37
69
|
self.message = message
|
|
70
|
+
super().__init__(message)
|
|
38
71
|
|
|
39
72
|
|
|
40
73
|
class InputGuardrailTripwireTriggered(AgentsException):
|
|
41
74
|
"""Exception raised when a guardrail tripwire is triggered."""
|
|
42
75
|
|
|
43
|
-
guardrail_result:
|
|
76
|
+
guardrail_result: InputGuardrailResult
|
|
44
77
|
"""The result data of the guardrail that was triggered."""
|
|
45
78
|
|
|
46
|
-
def __init__(self, guardrail_result:
|
|
79
|
+
def __init__(self, guardrail_result: InputGuardrailResult):
|
|
47
80
|
self.guardrail_result = guardrail_result
|
|
48
81
|
super().__init__(
|
|
49
82
|
f"Guardrail {guardrail_result.guardrail.__class__.__name__} triggered tripwire"
|
|
@@ -53,10 +86,10 @@ class InputGuardrailTripwireTriggered(AgentsException):
|
|
|
53
86
|
class OutputGuardrailTripwireTriggered(AgentsException):
|
|
54
87
|
"""Exception raised when a guardrail tripwire is triggered."""
|
|
55
88
|
|
|
56
|
-
guardrail_result:
|
|
89
|
+
guardrail_result: OutputGuardrailResult
|
|
57
90
|
"""The result data of the guardrail that was triggered."""
|
|
58
91
|
|
|
59
|
-
def __init__(self, guardrail_result:
|
|
92
|
+
def __init__(self, guardrail_result: OutputGuardrailResult):
|
|
60
93
|
self.guardrail_result = guardrail_result
|
|
61
94
|
super().__init__(
|
|
62
95
|
f"Guardrail {guardrail_result.guardrail.__class__.__name__} triggered tripwire"
|
|
@@ -5,7 +5,6 @@ import time
|
|
|
5
5
|
from collections.abc import AsyncIterator
|
|
6
6
|
from typing import Any, Literal, cast, overload
|
|
7
7
|
|
|
8
|
-
import litellm.types
|
|
9
8
|
from openai.types.responses.response_usage import InputTokensDetails, OutputTokensDetails
|
|
10
9
|
|
|
11
10
|
from agents.exceptions import ModelBehaviorError
|
|
@@ -112,11 +111,13 @@ class LitellmModel(Model):
|
|
|
112
111
|
cached_tokens=getattr(
|
|
113
112
|
response_usage.prompt_tokens_details, "cached_tokens", 0
|
|
114
113
|
)
|
|
114
|
+
or 0
|
|
115
115
|
),
|
|
116
116
|
output_tokens_details=OutputTokensDetails(
|
|
117
117
|
reasoning_tokens=getattr(
|
|
118
118
|
response_usage.completion_tokens_details, "reasoning_tokens", 0
|
|
119
119
|
)
|
|
120
|
+
or 0
|
|
120
121
|
),
|
|
121
122
|
)
|
|
122
123
|
if response.usage
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from
|
|
1
|
+
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
import graphviz # type: ignore
|
|
4
4
|
|
|
@@ -31,7 +31,9 @@ def get_main_graph(agent: Agent) -> str:
|
|
|
31
31
|
return "".join(parts)
|
|
32
32
|
|
|
33
33
|
|
|
34
|
-
def get_all_nodes(
|
|
34
|
+
def get_all_nodes(
|
|
35
|
+
agent: Agent, parent: Agent | None = None, visited: set[str] | None = None
|
|
36
|
+
) -> str:
|
|
35
37
|
"""
|
|
36
38
|
Recursively generates the nodes for the given agent and its handoffs in DOT format.
|
|
37
39
|
|
|
@@ -41,17 +43,23 @@ def get_all_nodes(agent: Agent, parent: Optional[Agent] = None) -> str:
|
|
|
41
43
|
Returns:
|
|
42
44
|
str: The DOT format string representing the nodes.
|
|
43
45
|
"""
|
|
46
|
+
if visited is None:
|
|
47
|
+
visited = set()
|
|
48
|
+
if agent.name in visited:
|
|
49
|
+
return ""
|
|
50
|
+
visited.add(agent.name)
|
|
51
|
+
|
|
44
52
|
parts = []
|
|
45
53
|
|
|
46
54
|
# Start and end the graph
|
|
47
|
-
parts.append(
|
|
48
|
-
'"__start__" [label="__start__", shape=ellipse, style=filled, '
|
|
49
|
-
"fillcolor=lightblue, width=0.5, height=0.3];"
|
|
50
|
-
'"__end__" [label="__end__", shape=ellipse, style=filled, '
|
|
51
|
-
"fillcolor=lightblue, width=0.5, height=0.3];"
|
|
52
|
-
)
|
|
53
|
-
# Ensure parent agent node is colored
|
|
54
55
|
if not parent:
|
|
56
|
+
parts.append(
|
|
57
|
+
'"__start__" [label="__start__", shape=ellipse, style=filled, '
|
|
58
|
+
"fillcolor=lightblue, width=0.5, height=0.3];"
|
|
59
|
+
'"__end__" [label="__end__", shape=ellipse, style=filled, '
|
|
60
|
+
"fillcolor=lightblue, width=0.5, height=0.3];"
|
|
61
|
+
)
|
|
62
|
+
# Ensure parent agent node is colored
|
|
55
63
|
parts.append(
|
|
56
64
|
f'"{agent.name}" [label="{agent.name}", shape=box, style=filled, '
|
|
57
65
|
"fillcolor=lightyellow, width=1.5, height=0.8];"
|
|
@@ -71,17 +79,20 @@ def get_all_nodes(agent: Agent, parent: Optional[Agent] = None) -> str:
|
|
|
71
79
|
f"fillcolor=lightyellow, width=1.5, height=0.8];"
|
|
72
80
|
)
|
|
73
81
|
if isinstance(handoff, Agent):
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
82
|
+
if handoff.name not in visited:
|
|
83
|
+
parts.append(
|
|
84
|
+
f'"{handoff.name}" [label="{handoff.name}", '
|
|
85
|
+
f"shape=box, style=filled, style=rounded, "
|
|
86
|
+
f"fillcolor=lightyellow, width=1.5, height=0.8];"
|
|
87
|
+
)
|
|
88
|
+
parts.append(get_all_nodes(handoff, agent, visited))
|
|
80
89
|
|
|
81
90
|
return "".join(parts)
|
|
82
91
|
|
|
83
92
|
|
|
84
|
-
def get_all_edges(
|
|
93
|
+
def get_all_edges(
|
|
94
|
+
agent: Agent, parent: Agent | None = None, visited: set[str] | None = None
|
|
95
|
+
) -> str:
|
|
85
96
|
"""
|
|
86
97
|
Recursively generates the edges for the given agent and its handoffs in DOT format.
|
|
87
98
|
|
|
@@ -92,6 +103,12 @@ def get_all_edges(agent: Agent, parent: Optional[Agent] = None) -> str:
|
|
|
92
103
|
Returns:
|
|
93
104
|
str: The DOT format string representing the edges.
|
|
94
105
|
"""
|
|
106
|
+
if visited is None:
|
|
107
|
+
visited = set()
|
|
108
|
+
if agent.name in visited:
|
|
109
|
+
return ""
|
|
110
|
+
visited.add(agent.name)
|
|
111
|
+
|
|
95
112
|
parts = []
|
|
96
113
|
|
|
97
114
|
if not parent:
|
|
@@ -109,7 +126,7 @@ def get_all_edges(agent: Agent, parent: Optional[Agent] = None) -> str:
|
|
|
109
126
|
if isinstance(handoff, Agent):
|
|
110
127
|
parts.append(f"""
|
|
111
128
|
"{agent.name}" -> "{handoff.name}";""")
|
|
112
|
-
parts.append(get_all_edges(handoff, agent))
|
|
129
|
+
parts.append(get_all_edges(handoff, agent, visited))
|
|
113
130
|
|
|
114
131
|
if not agent.handoffs and not isinstance(agent, Tool): # type: ignore
|
|
115
132
|
parts.append(f'"{agent.name}" -> "__end__";')
|
|
@@ -117,7 +134,7 @@ def get_all_edges(agent: Agent, parent: Optional[Agent] = None) -> str:
|
|
|
117
134
|
return "".join(parts)
|
|
118
135
|
|
|
119
136
|
|
|
120
|
-
def draw_graph(agent: Agent, filename:
|
|
137
|
+
def draw_graph(agent: Agent, filename: str | None = None) -> graphviz.Source:
|
|
121
138
|
"""
|
|
122
139
|
Draws the graph for the given agent and optionally saves it as a PNG file.
|
|
123
140
|
|
agents/handoffs.py
CHANGED
|
@@ -168,7 +168,7 @@ def handoff(
|
|
|
168
168
|
input_filter: a function that filters the inputs that are passed to the next agent.
|
|
169
169
|
"""
|
|
170
170
|
assert (on_handoff and input_type) or not (on_handoff and input_type), (
|
|
171
|
-
"You must provide either both
|
|
171
|
+
"You must provide either both on_handoff and input_type, or neither"
|
|
172
172
|
)
|
|
173
173
|
type_adapter: TypeAdapter[Any] | None
|
|
174
174
|
if input_type is not None:
|
agents/mcp/server.py
CHANGED
|
@@ -88,7 +88,7 @@ class _MCPServerWithClientSession(MCPServer, abc.ABC):
|
|
|
88
88
|
tuple[
|
|
89
89
|
MemoryObjectReceiveStream[SessionMessage | Exception],
|
|
90
90
|
MemoryObjectSendStream[SessionMessage],
|
|
91
|
-
GetSessionIdCallback | None
|
|
91
|
+
GetSessionIdCallback | None,
|
|
92
92
|
]
|
|
93
93
|
]:
|
|
94
94
|
"""Create the streams for the server."""
|
|
@@ -243,7 +243,7 @@ class MCPServerStdio(_MCPServerWithClientSession):
|
|
|
243
243
|
tuple[
|
|
244
244
|
MemoryObjectReceiveStream[SessionMessage | Exception],
|
|
245
245
|
MemoryObjectSendStream[SessionMessage],
|
|
246
|
-
GetSessionIdCallback | None
|
|
246
|
+
GetSessionIdCallback | None,
|
|
247
247
|
]
|
|
248
248
|
]:
|
|
249
249
|
"""Create the streams for the server."""
|
|
@@ -314,7 +314,7 @@ class MCPServerSse(_MCPServerWithClientSession):
|
|
|
314
314
|
tuple[
|
|
315
315
|
MemoryObjectReceiveStream[SessionMessage | Exception],
|
|
316
316
|
MemoryObjectSendStream[SessionMessage],
|
|
317
|
-
GetSessionIdCallback | None
|
|
317
|
+
GetSessionIdCallback | None,
|
|
318
318
|
]
|
|
319
319
|
]:
|
|
320
320
|
"""Create the streams for the server."""
|
|
@@ -394,7 +394,7 @@ class MCPServerStreamableHttp(_MCPServerWithClientSession):
|
|
|
394
394
|
tuple[
|
|
395
395
|
MemoryObjectReceiveStream[SessionMessage | Exception],
|
|
396
396
|
MemoryObjectSendStream[SessionMessage],
|
|
397
|
-
GetSessionIdCallback | None
|
|
397
|
+
GetSessionIdCallback | None,
|
|
398
398
|
]
|
|
399
399
|
]:
|
|
400
400
|
"""Create the streams for the server."""
|
|
@@ -403,7 +403,7 @@ class MCPServerStreamableHttp(_MCPServerWithClientSession):
|
|
|
403
403
|
headers=self.params.get("headers", None),
|
|
404
404
|
timeout=self.params.get("timeout", timedelta(seconds=30)),
|
|
405
405
|
sse_read_timeout=self.params.get("sse_read_timeout", timedelta(seconds=60 * 5)),
|
|
406
|
-
terminate_on_close=self.params.get("terminate_on_close", True)
|
|
406
|
+
terminate_on_close=self.params.get("terminate_on_close", True),
|
|
407
407
|
)
|
|
408
408
|
|
|
409
409
|
@property
|
agents/mcp/util.py
CHANGED
|
@@ -116,7 +116,7 @@ class MCPUtil:
|
|
|
116
116
|
if len(result.content) == 1:
|
|
117
117
|
tool_output = result.content[0].model_dump_json()
|
|
118
118
|
elif len(result.content) > 1:
|
|
119
|
-
tool_output = json.dumps([item.model_dump() for item in result.content])
|
|
119
|
+
tool_output = json.dumps([item.model_dump(mode="json") for item in result.content])
|
|
120
120
|
else:
|
|
121
121
|
logger.error(f"Errored MCP tool result: {result}")
|
|
122
122
|
tool_output = "Error running tool."
|
|
@@ -71,12 +71,22 @@ class OpenAIChatCompletionsModel(Model):
|
|
|
71
71
|
stream=False,
|
|
72
72
|
)
|
|
73
73
|
|
|
74
|
+
first_choice = response.choices[0]
|
|
75
|
+
message = first_choice.message
|
|
76
|
+
|
|
74
77
|
if _debug.DONT_LOG_MODEL_DATA:
|
|
75
78
|
logger.debug("Received model response")
|
|
76
79
|
else:
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
+
if message is not None:
|
|
81
|
+
logger.debug(
|
|
82
|
+
"LLM resp:\n%s\n",
|
|
83
|
+
json.dumps(message.model_dump(), indent=2),
|
|
84
|
+
)
|
|
85
|
+
else:
|
|
86
|
+
logger.debug(
|
|
87
|
+
"LLM resp had no message. finish_reason: %s",
|
|
88
|
+
first_choice.finish_reason,
|
|
89
|
+
)
|
|
80
90
|
|
|
81
91
|
usage = (
|
|
82
92
|
Usage(
|
|
@@ -101,13 +111,15 @@ class OpenAIChatCompletionsModel(Model):
|
|
|
101
111
|
else Usage()
|
|
102
112
|
)
|
|
103
113
|
if tracing.include_data():
|
|
104
|
-
span_generation.span_data.output =
|
|
114
|
+
span_generation.span_data.output = (
|
|
115
|
+
[message.model_dump()] if message is not None else []
|
|
116
|
+
)
|
|
105
117
|
span_generation.span_data.usage = {
|
|
106
118
|
"input_tokens": usage.input_tokens,
|
|
107
119
|
"output_tokens": usage.output_tokens,
|
|
108
120
|
}
|
|
109
121
|
|
|
110
|
-
items = Converter.message_to_output_items(
|
|
122
|
+
items = Converter.message_to_output_items(message) if message is not None else []
|
|
111
123
|
|
|
112
124
|
return ModelResponse(
|
|
113
125
|
output=items,
|
agents/result.py
CHANGED
|
@@ -11,14 +11,22 @@ from typing_extensions import TypeVar
|
|
|
11
11
|
from ._run_impl import QueueCompleteSentinel
|
|
12
12
|
from .agent import Agent
|
|
13
13
|
from .agent_output import AgentOutputSchemaBase
|
|
14
|
-
from .exceptions import
|
|
14
|
+
from .exceptions import (
|
|
15
|
+
AgentsException,
|
|
16
|
+
InputGuardrailTripwireTriggered,
|
|
17
|
+
MaxTurnsExceeded,
|
|
18
|
+
RunErrorDetails,
|
|
19
|
+
)
|
|
15
20
|
from .guardrail import InputGuardrailResult, OutputGuardrailResult
|
|
16
21
|
from .items import ItemHelpers, ModelResponse, RunItem, TResponseInputItem
|
|
17
22
|
from .logger import logger
|
|
18
23
|
from .run_context import RunContextWrapper
|
|
19
24
|
from .stream_events import StreamEvent
|
|
20
25
|
from .tracing import Trace
|
|
21
|
-
from .util._pretty_print import
|
|
26
|
+
from .util._pretty_print import (
|
|
27
|
+
pretty_print_result,
|
|
28
|
+
pretty_print_run_result_streaming,
|
|
29
|
+
)
|
|
22
30
|
|
|
23
31
|
if TYPE_CHECKING:
|
|
24
32
|
from ._run_impl import QueueCompleteSentinel
|
|
@@ -206,31 +214,53 @@ class RunResultStreaming(RunResultBase):
|
|
|
206
214
|
if self._stored_exception:
|
|
207
215
|
raise self._stored_exception
|
|
208
216
|
|
|
217
|
+
def _create_error_details(self) -> RunErrorDetails:
|
|
218
|
+
"""Return a `RunErrorDetails` object considering the current attributes of the class."""
|
|
219
|
+
return RunErrorDetails(
|
|
220
|
+
input=self.input,
|
|
221
|
+
new_items=self.new_items,
|
|
222
|
+
raw_responses=self.raw_responses,
|
|
223
|
+
last_agent=self.current_agent,
|
|
224
|
+
context_wrapper=self.context_wrapper,
|
|
225
|
+
input_guardrail_results=self.input_guardrail_results,
|
|
226
|
+
output_guardrail_results=self.output_guardrail_results,
|
|
227
|
+
)
|
|
228
|
+
|
|
209
229
|
def _check_errors(self):
|
|
210
230
|
if self.current_turn > self.max_turns:
|
|
211
|
-
|
|
231
|
+
max_turns_exc = MaxTurnsExceeded(f"Max turns ({self.max_turns}) exceeded")
|
|
232
|
+
max_turns_exc.run_data = self._create_error_details()
|
|
233
|
+
self._stored_exception = max_turns_exc
|
|
212
234
|
|
|
213
235
|
# Fetch all the completed guardrail results from the queue and raise if needed
|
|
214
236
|
while not self._input_guardrail_queue.empty():
|
|
215
237
|
guardrail_result = self._input_guardrail_queue.get_nowait()
|
|
216
238
|
if guardrail_result.output.tripwire_triggered:
|
|
217
|
-
|
|
239
|
+
tripwire_exc = InputGuardrailTripwireTriggered(guardrail_result)
|
|
240
|
+
tripwire_exc.run_data = self._create_error_details()
|
|
241
|
+
self._stored_exception = tripwire_exc
|
|
218
242
|
|
|
219
243
|
# Check the tasks for any exceptions
|
|
220
244
|
if self._run_impl_task and self._run_impl_task.done():
|
|
221
|
-
|
|
222
|
-
if
|
|
223
|
-
|
|
245
|
+
run_impl_exc = self._run_impl_task.exception()
|
|
246
|
+
if run_impl_exc and isinstance(run_impl_exc, Exception):
|
|
247
|
+
if isinstance(run_impl_exc, AgentsException) and run_impl_exc.run_data is None:
|
|
248
|
+
run_impl_exc.run_data = self._create_error_details()
|
|
249
|
+
self._stored_exception = run_impl_exc
|
|
224
250
|
|
|
225
251
|
if self._input_guardrails_task and self._input_guardrails_task.done():
|
|
226
|
-
|
|
227
|
-
if
|
|
228
|
-
|
|
252
|
+
in_guard_exc = self._input_guardrails_task.exception()
|
|
253
|
+
if in_guard_exc and isinstance(in_guard_exc, Exception):
|
|
254
|
+
if isinstance(in_guard_exc, AgentsException) and in_guard_exc.run_data is None:
|
|
255
|
+
in_guard_exc.run_data = self._create_error_details()
|
|
256
|
+
self._stored_exception = in_guard_exc
|
|
229
257
|
|
|
230
258
|
if self._output_guardrails_task and self._output_guardrails_task.done():
|
|
231
|
-
|
|
232
|
-
if
|
|
233
|
-
|
|
259
|
+
out_guard_exc = self._output_guardrails_task.exception()
|
|
260
|
+
if out_guard_exc and isinstance(out_guard_exc, Exception):
|
|
261
|
+
if isinstance(out_guard_exc, AgentsException) and out_guard_exc.run_data is None:
|
|
262
|
+
out_guard_exc.run_data = self._create_error_details()
|
|
263
|
+
self._stored_exception = out_guard_exc
|
|
234
264
|
|
|
235
265
|
def _cleanup_tasks(self):
|
|
236
266
|
if self._run_impl_task and not self._run_impl_task.done():
|
agents/run.py
CHANGED
|
@@ -26,6 +26,7 @@ from .exceptions import (
|
|
|
26
26
|
MaxTurnsExceeded,
|
|
27
27
|
ModelBehaviorError,
|
|
28
28
|
OutputGuardrailTripwireTriggered,
|
|
29
|
+
RunErrorDetails,
|
|
29
30
|
)
|
|
30
31
|
from .guardrail import InputGuardrail, InputGuardrailResult, OutputGuardrail, OutputGuardrailResult
|
|
31
32
|
from .handoffs import Handoff, HandoffInputFilter, handoff
|
|
@@ -180,6 +181,8 @@ class Runner:
|
|
|
180
181
|
|
|
181
182
|
try:
|
|
182
183
|
while True:
|
|
184
|
+
all_tools = await cls._get_all_tools(current_agent, context_wrapper)
|
|
185
|
+
|
|
183
186
|
# Start an agent span if we don't have one. This span is ended if the current
|
|
184
187
|
# agent changes, or if the agent loop ends.
|
|
185
188
|
if current_span is None:
|
|
@@ -195,8 +198,6 @@ class Runner:
|
|
|
195
198
|
output_type=output_type_name,
|
|
196
199
|
)
|
|
197
200
|
current_span.start(mark_as_current=True)
|
|
198
|
-
|
|
199
|
-
all_tools = await cls._get_all_tools(current_agent)
|
|
200
201
|
current_span.span_data.tools = [t.name for t in all_tools]
|
|
201
202
|
|
|
202
203
|
current_turn += 1
|
|
@@ -283,6 +284,17 @@ class Runner:
|
|
|
283
284
|
raise AgentsException(
|
|
284
285
|
f"Unknown next step type: {type(turn_result.next_step)}"
|
|
285
286
|
)
|
|
287
|
+
except AgentsException as exc:
|
|
288
|
+
exc.run_data = RunErrorDetails(
|
|
289
|
+
input=original_input,
|
|
290
|
+
new_items=generated_items,
|
|
291
|
+
raw_responses=model_responses,
|
|
292
|
+
last_agent=current_agent,
|
|
293
|
+
context_wrapper=context_wrapper,
|
|
294
|
+
input_guardrail_results=input_guardrail_results,
|
|
295
|
+
output_guardrail_results=[],
|
|
296
|
+
)
|
|
297
|
+
raise
|
|
286
298
|
finally:
|
|
287
299
|
if current_span:
|
|
288
300
|
current_span.finish(reset_current=True)
|
|
@@ -513,6 +525,8 @@ class Runner:
|
|
|
513
525
|
if streamed_result.is_complete:
|
|
514
526
|
break
|
|
515
527
|
|
|
528
|
+
all_tools = await cls._get_all_tools(current_agent, context_wrapper)
|
|
529
|
+
|
|
516
530
|
# Start an agent span if we don't have one. This span is ended if the current
|
|
517
531
|
# agent changes, or if the agent loop ends.
|
|
518
532
|
if current_span is None:
|
|
@@ -528,8 +542,6 @@ class Runner:
|
|
|
528
542
|
output_type=output_type_name,
|
|
529
543
|
)
|
|
530
544
|
current_span.start(mark_as_current=True)
|
|
531
|
-
|
|
532
|
-
all_tools = await cls._get_all_tools(current_agent)
|
|
533
545
|
tool_names = [t.name for t in all_tools]
|
|
534
546
|
current_span.span_data.tools = tool_names
|
|
535
547
|
current_turn += 1
|
|
@@ -609,6 +621,19 @@ class Runner:
|
|
|
609
621
|
streamed_result._event_queue.put_nowait(QueueCompleteSentinel())
|
|
610
622
|
elif isinstance(turn_result.next_step, NextStepRunAgain):
|
|
611
623
|
pass
|
|
624
|
+
except AgentsException as exc:
|
|
625
|
+
streamed_result.is_complete = True
|
|
626
|
+
streamed_result._event_queue.put_nowait(QueueCompleteSentinel())
|
|
627
|
+
exc.run_data = RunErrorDetails(
|
|
628
|
+
input=streamed_result.input,
|
|
629
|
+
new_items=streamed_result.new_items,
|
|
630
|
+
raw_responses=streamed_result.raw_responses,
|
|
631
|
+
last_agent=current_agent,
|
|
632
|
+
context_wrapper=context_wrapper,
|
|
633
|
+
input_guardrail_results=streamed_result.input_guardrail_results,
|
|
634
|
+
output_guardrail_results=streamed_result.output_guardrail_results,
|
|
635
|
+
)
|
|
636
|
+
raise
|
|
612
637
|
except Exception as e:
|
|
613
638
|
if current_span:
|
|
614
639
|
_error_tracing.attach_error_to_span(
|
|
@@ -955,8 +980,10 @@ class Runner:
|
|
|
955
980
|
return handoffs
|
|
956
981
|
|
|
957
982
|
@classmethod
|
|
958
|
-
async def _get_all_tools(
|
|
959
|
-
|
|
983
|
+
async def _get_all_tools(
|
|
984
|
+
cls, agent: Agent[Any], context_wrapper: RunContextWrapper[Any]
|
|
985
|
+
) -> list[Tool]:
|
|
986
|
+
return await agent.get_all_tools(context_wrapper)
|
|
960
987
|
|
|
961
988
|
@classmethod
|
|
962
989
|
def _get_model(cls, agent: Agent[Any], run_config: RunConfig) -> Model:
|
agents/stream_events.py
CHANGED
agents/tool.py
CHANGED
|
@@ -4,7 +4,7 @@ import inspect
|
|
|
4
4
|
import json
|
|
5
5
|
from collections.abc import Awaitable
|
|
6
6
|
from dataclasses import dataclass
|
|
7
|
-
from typing import Any, Callable, Literal, Union, overload
|
|
7
|
+
from typing import TYPE_CHECKING, Any, Callable, Literal, Union, overload
|
|
8
8
|
|
|
9
9
|
from openai.types.responses.file_search_tool_param import Filters, RankingOptions
|
|
10
10
|
from openai.types.responses.response_output_item import LocalShellCall, McpApprovalRequest
|
|
@@ -24,6 +24,9 @@ from .tracing import SpanError
|
|
|
24
24
|
from .util import _error_tracing
|
|
25
25
|
from .util._types import MaybeAwaitable
|
|
26
26
|
|
|
27
|
+
if TYPE_CHECKING:
|
|
28
|
+
from .agent import Agent
|
|
29
|
+
|
|
27
30
|
ToolParams = ParamSpec("ToolParams")
|
|
28
31
|
|
|
29
32
|
ToolFunctionWithoutContext = Callable[ToolParams, Any]
|
|
@@ -74,6 +77,11 @@ class FunctionTool:
|
|
|
74
77
|
"""Whether the JSON schema is in strict mode. We **strongly** recommend setting this to True,
|
|
75
78
|
as it increases the likelihood of correct JSON input."""
|
|
76
79
|
|
|
80
|
+
is_enabled: bool | Callable[[RunContextWrapper[Any], Agent[Any]], MaybeAwaitable[bool]] = True
|
|
81
|
+
"""Whether the tool is enabled. Either a bool or a Callable that takes the run context and agent
|
|
82
|
+
and returns whether the tool is enabled. You can use this to dynamically enable/disable a tool
|
|
83
|
+
based on your context/state."""
|
|
84
|
+
|
|
77
85
|
|
|
78
86
|
@dataclass
|
|
79
87
|
class FileSearchTool:
|
|
@@ -262,6 +270,7 @@ def function_tool(
|
|
|
262
270
|
use_docstring_info: bool = True,
|
|
263
271
|
failure_error_function: ToolErrorFunction | None = None,
|
|
264
272
|
strict_mode: bool = True,
|
|
273
|
+
is_enabled: bool | Callable[[RunContextWrapper[Any], Agent[Any]], MaybeAwaitable[bool]] = True,
|
|
265
274
|
) -> FunctionTool:
|
|
266
275
|
"""Overload for usage as @function_tool (no parentheses)."""
|
|
267
276
|
...
|
|
@@ -276,6 +285,7 @@ def function_tool(
|
|
|
276
285
|
use_docstring_info: bool = True,
|
|
277
286
|
failure_error_function: ToolErrorFunction | None = None,
|
|
278
287
|
strict_mode: bool = True,
|
|
288
|
+
is_enabled: bool | Callable[[RunContextWrapper[Any], Agent[Any]], MaybeAwaitable[bool]] = True,
|
|
279
289
|
) -> Callable[[ToolFunction[...]], FunctionTool]:
|
|
280
290
|
"""Overload for usage as @function_tool(...)."""
|
|
281
291
|
...
|
|
@@ -290,6 +300,7 @@ def function_tool(
|
|
|
290
300
|
use_docstring_info: bool = True,
|
|
291
301
|
failure_error_function: ToolErrorFunction | None = default_tool_error_function,
|
|
292
302
|
strict_mode: bool = True,
|
|
303
|
+
is_enabled: bool | Callable[[RunContextWrapper[Any], Agent[Any]], MaybeAwaitable[bool]] = True,
|
|
293
304
|
) -> FunctionTool | Callable[[ToolFunction[...]], FunctionTool]:
|
|
294
305
|
"""
|
|
295
306
|
Decorator to create a FunctionTool from a function. By default, we will:
|
|
@@ -318,6 +329,9 @@ def function_tool(
|
|
|
318
329
|
If False, it allows non-strict JSON schemas. For example, if a parameter has a default
|
|
319
330
|
value, it will be optional, additional properties are allowed, etc. See here for more:
|
|
320
331
|
https://platform.openai.com/docs/guides/structured-outputs?api-mode=responses#supported-schemas
|
|
332
|
+
is_enabled: Whether the tool is enabled. Can be a bool or a callable that takes the run
|
|
333
|
+
context and agent and returns whether the tool is enabled. Disabled tools are hidden
|
|
334
|
+
from the LLM at runtime.
|
|
321
335
|
"""
|
|
322
336
|
|
|
323
337
|
def _create_function_tool(the_func: ToolFunction[...]) -> FunctionTool:
|
|
@@ -407,6 +421,7 @@ def function_tool(
|
|
|
407
421
|
params_json_schema=schema.params_json_schema,
|
|
408
422
|
on_invoke_tool=_on_invoke_tool,
|
|
409
423
|
strict_json_schema=strict_mode,
|
|
424
|
+
is_enabled=is_enabled,
|
|
410
425
|
)
|
|
411
426
|
|
|
412
427
|
# If func is actually a callable, we were used as @function_tool with no parentheses
|
agents/tracing/processors.py
CHANGED
|
@@ -188,10 +188,27 @@ class BatchTraceProcessor(TracingProcessor):
|
|
|
188
188
|
# Track when we next *must* perform a scheduled export
|
|
189
189
|
self._next_export_time = time.time() + self._schedule_delay
|
|
190
190
|
|
|
191
|
-
|
|
192
|
-
self._worker_thread.
|
|
191
|
+
# We lazily start the background worker thread the first time a span/trace is queued.
|
|
192
|
+
self._worker_thread: threading.Thread | None = None
|
|
193
|
+
self._thread_start_lock = threading.Lock()
|
|
194
|
+
|
|
195
|
+
def _ensure_thread_started(self) -> None:
|
|
196
|
+
# Fast path without holding the lock
|
|
197
|
+
if self._worker_thread and self._worker_thread.is_alive():
|
|
198
|
+
return
|
|
199
|
+
|
|
200
|
+
# Double-checked locking to avoid starting multiple threads
|
|
201
|
+
with self._thread_start_lock:
|
|
202
|
+
if self._worker_thread and self._worker_thread.is_alive():
|
|
203
|
+
return
|
|
204
|
+
|
|
205
|
+
self._worker_thread = threading.Thread(target=self._run, daemon=True)
|
|
206
|
+
self._worker_thread.start()
|
|
193
207
|
|
|
194
208
|
def on_trace_start(self, trace: Trace) -> None:
|
|
209
|
+
# Ensure the background worker is running before we enqueue anything.
|
|
210
|
+
self._ensure_thread_started()
|
|
211
|
+
|
|
195
212
|
try:
|
|
196
213
|
self._queue.put_nowait(trace)
|
|
197
214
|
except queue.Full:
|
|
@@ -206,6 +223,9 @@ class BatchTraceProcessor(TracingProcessor):
|
|
|
206
223
|
pass
|
|
207
224
|
|
|
208
225
|
def on_span_end(self, span: Span[Any]) -> None:
|
|
226
|
+
# Ensure the background worker is running before we enqueue anything.
|
|
227
|
+
self._ensure_thread_started()
|
|
228
|
+
|
|
209
229
|
try:
|
|
210
230
|
self._queue.put_nowait(span)
|
|
211
231
|
except queue.Full:
|
|
@@ -216,7 +236,13 @@ class BatchTraceProcessor(TracingProcessor):
|
|
|
216
236
|
Called when the application stops. We signal our thread to stop, then join it.
|
|
217
237
|
"""
|
|
218
238
|
self._shutdown_event.set()
|
|
219
|
-
|
|
239
|
+
|
|
240
|
+
# Only join if we ever started the background thread; otherwise flush synchronously.
|
|
241
|
+
if self._worker_thread and self._worker_thread.is_alive():
|
|
242
|
+
self._worker_thread.join(timeout=timeout)
|
|
243
|
+
else:
|
|
244
|
+
# No background thread: process any remaining items synchronously.
|
|
245
|
+
self._export_batches(force=True)
|
|
220
246
|
|
|
221
247
|
def force_flush(self):
|
|
222
248
|
"""
|
agents/util/_pretty_print.py
CHANGED
|
@@ -3,6 +3,7 @@ from typing import TYPE_CHECKING
|
|
|
3
3
|
from pydantic import BaseModel
|
|
4
4
|
|
|
5
5
|
if TYPE_CHECKING:
|
|
6
|
+
from ..exceptions import RunErrorDetails
|
|
6
7
|
from ..result import RunResult, RunResultBase, RunResultStreaming
|
|
7
8
|
|
|
8
9
|
|
|
@@ -38,6 +39,17 @@ def pretty_print_result(result: "RunResult") -> str:
|
|
|
38
39
|
return output
|
|
39
40
|
|
|
40
41
|
|
|
42
|
+
def pretty_print_run_error_details(result: "RunErrorDetails") -> str:
|
|
43
|
+
output = "RunErrorDetails:"
|
|
44
|
+
output += f'\n- Last agent: Agent(name="{result.last_agent.name}", ...)'
|
|
45
|
+
output += f"\n- {len(result.new_items)} new item(s)"
|
|
46
|
+
output += f"\n- {len(result.raw_responses)} raw response(s)"
|
|
47
|
+
output += f"\n- {len(result.input_guardrail_results)} input guardrail result(s)"
|
|
48
|
+
output += "\n(See `RunErrorDetails` for more details)"
|
|
49
|
+
|
|
50
|
+
return output
|
|
51
|
+
|
|
52
|
+
|
|
41
53
|
def pretty_print_run_result_streaming(result: "RunResultStreaming") -> str:
|
|
42
54
|
output = "RunResultStreaming:"
|
|
43
55
|
output += f'\n- Current agent: Agent(name="{result.current_agent.name}", ...)'
|
agents/voice/model.py
CHANGED
|
@@ -17,9 +17,11 @@ DEFAULT_TTS_BUFFER_SIZE = 120
|
|
|
17
17
|
TTSVoice = Literal["alloy", "ash", "coral", "echo", "fable", "onyx", "nova", "sage", "shimmer"]
|
|
18
18
|
"""Exportable type for the TTSModelSettings voice enum"""
|
|
19
19
|
|
|
20
|
+
|
|
20
21
|
@dataclass
|
|
21
22
|
class TTSModelSettings:
|
|
22
23
|
"""Settings for a TTS model."""
|
|
24
|
+
|
|
23
25
|
voice: TTSVoice | None = None
|
|
24
26
|
"""
|
|
25
27
|
The voice to use for the TTS model. If not provided, the default voice for the respective model
|
|
@@ -1,37 +1,37 @@
|
|
|
1
|
-
agents/__init__.py,sha256=
|
|
1
|
+
agents/__init__.py,sha256=ZnZazUPdfh19uNOgNyu2OBQr5zz2DdUrKgam3Y9BAk4,7438
|
|
2
2
|
agents/_config.py,sha256=ANrM7GP2VSQehDkMc9qocxkUlPwqU-i5sieMJyEwxpM,796
|
|
3
3
|
agents/_debug.py,sha256=7OKys2lDjeCtGggTkM53m_8vw0WIr3yt-_JPBDAnsw0,608
|
|
4
|
-
agents/_run_impl.py,sha256=
|
|
5
|
-
agents/agent.py,sha256=
|
|
6
|
-
agents/agent_output.py,sha256=
|
|
4
|
+
agents/_run_impl.py,sha256=DyIodrzaWNdydZWDKJT6wGg3v445jwBUOwxb5mM-c58,42742
|
|
5
|
+
agents/agent.py,sha256=eeOWjR-a0xOB4Ctt9OTl93rEr_VRAkynN2M0vfx2nTs,11195
|
|
6
|
+
agents/agent_output.py,sha256=cVIVwpsgOfloCHL0BD9DSCBCzW_s3T4LesDhvJRu2Uc,7127
|
|
7
7
|
agents/computer.py,sha256=XD44UgiUWSfniv-xKwwDP6wFKVwBiZkpaL1hO-0-7ZA,2516
|
|
8
|
-
agents/exceptions.py,sha256=
|
|
8
|
+
agents/exceptions.py,sha256=NHMdHE0cZ6AdA6UgUylTzVHAX05Ol1CkO814a0FdZcs,2862
|
|
9
9
|
agents/function_schema.py,sha256=k4GTdxf5bvcisVr9b4xSdTGzkB5oP3XZnJMdouABCsw,12909
|
|
10
10
|
agents/guardrail.py,sha256=vWWcApo9s_6aHapQ5AMko08MqC8Jrlk-J5iqIRctCDQ,9291
|
|
11
|
-
agents/handoffs.py,sha256=
|
|
11
|
+
agents/handoffs.py,sha256=mWvtgWMJjSIlhUR9xf-pXOJbWVCKxNBXytP9tsPGWII,9045
|
|
12
12
|
agents/items.py,sha256=lXFc_gKLEqwXIcyMKk4Q-6Rjry0MWD93xlvk4Y1W970,9695
|
|
13
13
|
agents/lifecycle.py,sha256=wYFG6PLSKQ7bICKVbB8oGtdoJNINGq9obh2RSKlAkDE,2938
|
|
14
14
|
agents/logger.py,sha256=p_ef7vWKpBev5FFybPJjhrCCQizK08Yy1A2EDO1SNNg,60
|
|
15
15
|
agents/model_settings.py,sha256=7s9YjfHBVz1f1a-V3dd-8eMe-IAgfDXhQgChI27Kz00,3326
|
|
16
16
|
agents/py.typed,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
|
17
|
-
agents/result.py,sha256=
|
|
18
|
-
agents/run.py,sha256=
|
|
17
|
+
agents/result.py,sha256=YCGYHoc5X1_vLKu5QiK6F8C1ZXI3tTfLXaZoqbYgUMA,10753
|
|
18
|
+
agents/run.py,sha256=cGvRtw9Ck7gEthmdnUBtb82lD7y0JgIZFsjMXbkCJZY,41816
|
|
19
19
|
agents/run_context.py,sha256=vuSUQM8O4CLensQY27-22fOqECnw7yvwL9U3WO8b_bk,851
|
|
20
|
-
agents/stream_events.py,sha256=
|
|
20
|
+
agents/stream_events.py,sha256=VFyTu-DT3ZMnHLtMbg-X_lxec0doQxNfx-hVxLB0BpI,1700
|
|
21
21
|
agents/strict_schema.py,sha256=_KuEJkglmq-Fj3HSeYP4WqTvqrxbSKu6gezfz5Brhh0,5775
|
|
22
|
-
agents/tool.py,sha256=
|
|
22
|
+
agents/tool.py,sha256=yDUuR6oAO2NufHoJqKtqLExGx6ClHPTYYPsdraf39P0,15675
|
|
23
23
|
agents/usage.py,sha256=GB83eElU-DVkdutGObGDSX5vJNy8ssu3Xbpp5LlHfwU,1643
|
|
24
24
|
agents/version.py,sha256=_1knUwzSK-HUeZTpRUkk6Z-CIcurqXuEplbV5TLJ08E,230
|
|
25
25
|
agents/extensions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
26
26
|
agents/extensions/handoff_filters.py,sha256=2cXxu1JROez96CpTiGuT9PIuaIrIE8ksP01fX83krKM,1977
|
|
27
27
|
agents/extensions/handoff_prompt.py,sha256=oGWN0uNh3Z1L7E-Ev2up8W084fFrDNOsLDy7P6bcmic,1006
|
|
28
|
-
agents/extensions/visualization.py,sha256=
|
|
28
|
+
agents/extensions/visualization.py,sha256=g2eEwW22qe3A4WtH37LwaHhK3QZE9FYHVw9IcOVpwbk,4699
|
|
29
29
|
agents/extensions/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
30
|
-
agents/extensions/models/litellm_model.py,sha256=
|
|
30
|
+
agents/extensions/models/litellm_model.py,sha256=zcjdGI2EyhKqiXnobl_WPuPL8_zl2sGDOz7bul3Kjzs,14447
|
|
31
31
|
agents/extensions/models/litellm_provider.py,sha256=wTm00Anq8YoNb9AnyT0JOunDG-HCDm_98ORNy7aNJdw,928
|
|
32
32
|
agents/mcp/__init__.py,sha256=_aDpMTvYCe1IezOEasZ0vmombBM8r7BD8lpXiKi-UlM,499
|
|
33
|
-
agents/mcp/server.py,sha256=
|
|
34
|
-
agents/mcp/util.py,sha256=
|
|
33
|
+
agents/mcp/server.py,sha256=mP_JxJzz00prX_0SzTZO38bjvhj4A61icypUjvxdG4k,15915
|
|
34
|
+
agents/mcp/util.py,sha256=qXbAo9O-yv0JfmZBxDJIQ8ieHMTNWTEX5lnSVBv637k,5243
|
|
35
35
|
agents/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
36
36
|
agents/models/_openai_shared.py,sha256=4Ngwo2Fv2RXY61Pqck1cYPkSln2tDnb8Ai-ao4QG-iE,836
|
|
37
37
|
agents/models/chatcmpl_converter.py,sha256=Sae-ITlhQz8_SiFiSat7Z-lavqIuczduOXR_PF_f6cs,18126
|
|
@@ -40,14 +40,14 @@ agents/models/chatcmpl_stream_handler.py,sha256=sDl8O7AKxpWxAq7-bgCUClD5JySUnbQ8
|
|
|
40
40
|
agents/models/fake_id.py,sha256=lbXjUUSMeAQ8eFx4V5QLUnBClHE6adJlYYav55RlG5w,268
|
|
41
41
|
agents/models/interface.py,sha256=eEpiIBn9MxsmXUK1HPpn3c7TYPduBYC7tsWnDHSYJHo,3553
|
|
42
42
|
agents/models/multi_provider.py,sha256=aiDbls5G4YomPfN6qH1pGlj41WS5jlDp2T82zm6qcnM,5578
|
|
43
|
-
agents/models/openai_chatcompletions.py,sha256=
|
|
43
|
+
agents/models/openai_chatcompletions.py,sha256=aSE1cww-C-6p5PXpslo70X-V0MHqbN6msLhnawFbhJU,11445
|
|
44
44
|
agents/models/openai_provider.py,sha256=NMxTNaoTa329GrA7jj51LC02pb_e2eFh-PCvWADJrkY,3478
|
|
45
45
|
agents/models/openai_responses.py,sha256=JFajISS-sYYxKhb66tZ5cYPEqIYOj6ap762Z-87c7fE,15368
|
|
46
46
|
agents/tracing/__init__.py,sha256=-hJeEiNvgyQdEXpFTrr_qu_XYREvIrF5KyePDtovSak,2804
|
|
47
47
|
agents/tracing/create.py,sha256=kkMf2pp5Te20YkiSvf3Xj3J9qMibQCjEAxZs1Lr_kTE,18124
|
|
48
48
|
agents/tracing/logger.py,sha256=J4KUDRSGa7x5UVfUwWe-gbKwoaq8AeETRqkPt3QvtGg,68
|
|
49
49
|
agents/tracing/processor_interface.py,sha256=wNyZCwNJko5CrUIWD_lMou5ppQ67CFYwvWRsJRM3up8,1659
|
|
50
|
-
agents/tracing/processors.py,sha256=
|
|
50
|
+
agents/tracing/processors.py,sha256=lOdZHwo0rQAflVkKWOZinnWyLtS0stALyydiFOC0gss,11389
|
|
51
51
|
agents/tracing/scope.py,sha256=u17_m8RPpGvbHrTkaO_kDi5ROBWhfOAIgBe7suiaRD4,1445
|
|
52
52
|
agents/tracing/setup.py,sha256=YnEDTaRG_b510vtsXbOaCUZ0nf7MOr1ULvOpQOHtdBs,6776
|
|
53
53
|
agents/tracing/span_data.py,sha256=nI2Fbu1ORE8ybE6m6RuddTJF5E5xFmEj8Mq5bSFv4bE,9017
|
|
@@ -58,7 +58,7 @@ agents/util/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
|
58
58
|
agents/util/_coro.py,sha256=S38XUYFC7bqTELSgMUBsAX1GoRlIrV7coupcUAWH__4,45
|
|
59
59
|
agents/util/_error_tracing.py,sha256=hdkYNx180b18lP0PSB1toE5atNHsMg_Bm9Osw812vLo,421
|
|
60
60
|
agents/util/_json.py,sha256=eKeQeMlQkBXRFeL3ilNZFmszGyfhtzZdW_GW_As6dcg,972
|
|
61
|
-
agents/util/_pretty_print.py,sha256=
|
|
61
|
+
agents/util/_pretty_print.py,sha256=pnrM81KRG4G21jZnYrYBCkPgtUeP8qcnJm-9tpAV1WA,2738
|
|
62
62
|
agents/util/_transforms.py,sha256=CZe74NOHkHneyo4fHYfFWksCSTn-kXtEyejL9P0_xlA,270
|
|
63
63
|
agents/util/_types.py,sha256=8KxYfCw0gYSMWcQmacJoc3Q7Lc46LmT-AWvhF10KJ-E,160
|
|
64
64
|
agents/voice/__init__.py,sha256=4VWBUjyoXC6dGFuk-oZQGg8T32bFxVwy371c-zDK-EU,1537
|
|
@@ -66,7 +66,7 @@ agents/voice/events.py,sha256=4aPAZC0__ocgmg_mcX4c1zv9Go-YdKIVItQ2kYgtye0,1216
|
|
|
66
66
|
agents/voice/exceptions.py,sha256=QcyfvaUTBe4gxbFP82oDSa_puzZ4Z4O4k01B8pAHnK0,233
|
|
67
67
|
agents/voice/imports.py,sha256=VaE5I8aJTP9Zl_0-y9dx1UcAP7KPRDMaikFK2jFnn8s,348
|
|
68
68
|
agents/voice/input.py,sha256=FSbdHMIdLVKX4vYcmf3WBJ5dAlh5zMDjCAuGfXOZTQs,2910
|
|
69
|
-
agents/voice/model.py,sha256=
|
|
69
|
+
agents/voice/model.py,sha256=LWnIWEwU0-aFkff3kbTKkxejnYqzS2XHG5Qm2YcrzFI,5956
|
|
70
70
|
agents/voice/pipeline.py,sha256=5LKTTDytQt4QlZzVKgbB9x3X2zA-TeR94FTi15vIUc0,6259
|
|
71
71
|
agents/voice/pipeline_config.py,sha256=_cynbnzxvQijxkGrMYHJzIV54F9bRvDsPV24qexVO8c,1759
|
|
72
72
|
agents/voice/result.py,sha256=Yx9JCMGCE9OfXacaBFfFLQJRwkNo5-h4Nqm9OPnemU4,11107
|
|
@@ -76,7 +76,7 @@ agents/voice/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSu
|
|
|
76
76
|
agents/voice/models/openai_model_provider.py,sha256=Khn0uT-VhsEbe7_OhBMGFQzXNwL80gcWZyTHl3CaBII,3587
|
|
77
77
|
agents/voice/models/openai_stt.py,sha256=rRsldkvkPhH4T0waX1dhccEqIwmPYh-teK_LRvBgiNI,16882
|
|
78
78
|
agents/voice/models/openai_tts.py,sha256=4KoLQuFDHKu5a1VTJlu9Nj3MHwMlrn9wfT_liJDJ2dw,1477
|
|
79
|
-
openai_agents-0.0.
|
|
80
|
-
openai_agents-0.0.
|
|
81
|
-
openai_agents-0.0.
|
|
82
|
-
openai_agents-0.0.
|
|
79
|
+
openai_agents-0.0.17.dist-info/METADATA,sha256=2SF0ZEolF_69dW0eTSWGuJc_RLuOAnYkqvBqj4IgqCw,8163
|
|
80
|
+
openai_agents-0.0.17.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
81
|
+
openai_agents-0.0.17.dist-info/licenses/LICENSE,sha256=E994EspT7Krhy0qGiES7WYNzBHrh1YDk3r--8d1baRU,1063
|
|
82
|
+
openai_agents-0.0.17.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|