openai-agents 0.0.4__py3-none-any.whl → 0.0.5__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 +10 -5
- agents/_run_impl.py +101 -22
- agents/agent.py +55 -7
- agents/agent_output.py +4 -4
- agents/function_schema.py +4 -0
- agents/guardrail.py +1 -1
- agents/handoffs.py +4 -4
- agents/items.py +4 -2
- agents/models/openai_chatcompletions.py +6 -1
- agents/result.py +7 -0
- agents/run.py +10 -10
- agents/tool.py +34 -10
- agents/tracing/create.py +1 -1
- agents/tracing/processors.py +2 -2
- agents/tracing/scope.py +1 -1
- agents/tracing/setup.py +1 -1
- agents/tracing/span_data.py +2 -2
- agents/tracing/spans.py +1 -1
- agents/tracing/traces.py +1 -1
- agents/util/__init__.py +0 -0
- agents/util/_coro.py +2 -0
- agents/util/_error_tracing.py +16 -0
- agents/util/_json.py +31 -0
- agents/util/_pretty_print.py +56 -0
- agents/util/_transforms.py +11 -0
- agents/util/_types.py +7 -0
- {openai_agents-0.0.4.dist-info → openai_agents-0.0.5.dist-info}/METADATA +4 -4
- openai_agents-0.0.5.dist-info/RECORD +55 -0
- agents/_utils.py +0 -61
- openai_agents-0.0.4.dist-info/RECORD +0 -49
- {openai_agents-0.0.4.dist-info → openai_agents-0.0.5.dist-info}/WHEEL +0 -0
- {openai_agents-0.0.4.dist-info → openai_agents-0.0.5.dist-info}/licenses/LICENSE +0 -0
agents/__init__.py
CHANGED
|
@@ -5,7 +5,7 @@ from typing import Literal
|
|
|
5
5
|
from openai import AsyncOpenAI
|
|
6
6
|
|
|
7
7
|
from . import _config
|
|
8
|
-
from .agent import Agent
|
|
8
|
+
from .agent import Agent, ToolsToFinalOutputFunction, ToolsToFinalOutputResult
|
|
9
9
|
from .agent_output import AgentOutputSchema
|
|
10
10
|
from .computer import AsyncComputer, Button, Computer, Environment
|
|
11
11
|
from .exceptions import (
|
|
@@ -57,6 +57,7 @@ from .tool import (
|
|
|
57
57
|
ComputerTool,
|
|
58
58
|
FileSearchTool,
|
|
59
59
|
FunctionTool,
|
|
60
|
+
FunctionToolResult,
|
|
60
61
|
Tool,
|
|
61
62
|
WebSearchTool,
|
|
62
63
|
default_tool_error_function,
|
|
@@ -73,6 +74,7 @@ from .tracing import (
|
|
|
73
74
|
SpanData,
|
|
74
75
|
SpanError,
|
|
75
76
|
Trace,
|
|
77
|
+
TracingProcessor,
|
|
76
78
|
add_trace_processor,
|
|
77
79
|
agent_span,
|
|
78
80
|
custom_span,
|
|
@@ -129,14 +131,15 @@ def set_default_openai_api(api: Literal["chat_completions", "responses"]) -> Non
|
|
|
129
131
|
|
|
130
132
|
def enable_verbose_stdout_logging():
|
|
131
133
|
"""Enables verbose logging to stdout. This is useful for debugging."""
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
logger.addHandler(logging.StreamHandler(sys.stdout))
|
|
134
|
+
logger = logging.getLogger("openai.agents")
|
|
135
|
+
logger.setLevel(logging.DEBUG)
|
|
136
|
+
logger.addHandler(logging.StreamHandler(sys.stdout))
|
|
136
137
|
|
|
137
138
|
|
|
138
139
|
__all__ = [
|
|
139
140
|
"Agent",
|
|
141
|
+
"ToolsToFinalOutputFunction",
|
|
142
|
+
"ToolsToFinalOutputResult",
|
|
140
143
|
"Runner",
|
|
141
144
|
"Model",
|
|
142
145
|
"ModelProvider",
|
|
@@ -190,6 +193,7 @@ __all__ = [
|
|
|
190
193
|
"AgentUpdatedStreamEvent",
|
|
191
194
|
"StreamEvent",
|
|
192
195
|
"FunctionTool",
|
|
196
|
+
"FunctionToolResult",
|
|
193
197
|
"ComputerTool",
|
|
194
198
|
"FileSearchTool",
|
|
195
199
|
"Tool",
|
|
@@ -209,6 +213,7 @@ __all__ = [
|
|
|
209
213
|
"set_tracing_disabled",
|
|
210
214
|
"trace",
|
|
211
215
|
"Trace",
|
|
216
|
+
"TracingProcessor",
|
|
212
217
|
"SpanError",
|
|
213
218
|
"Span",
|
|
214
219
|
"SpanData",
|
agents/_run_impl.py
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
import asyncio
|
|
4
|
+
import inspect
|
|
5
|
+
from collections.abc import Awaitable
|
|
4
6
|
from dataclasses import dataclass
|
|
5
|
-
from typing import TYPE_CHECKING, Any
|
|
7
|
+
from typing import TYPE_CHECKING, Any, cast
|
|
6
8
|
|
|
7
9
|
from openai.types.responses import (
|
|
8
10
|
ResponseComputerToolCall,
|
|
@@ -25,8 +27,7 @@ from openai.types.responses.response_computer_tool_call import (
|
|
|
25
27
|
from openai.types.responses.response_input_param import ComputerCallOutput
|
|
26
28
|
from openai.types.responses.response_reasoning_item import ResponseReasoningItem
|
|
27
29
|
|
|
28
|
-
from . import
|
|
29
|
-
from .agent import Agent
|
|
30
|
+
from .agent import Agent, ToolsToFinalOutputResult
|
|
30
31
|
from .agent_output import AgentOutputSchema
|
|
31
32
|
from .computer import AsyncComputer, Computer
|
|
32
33
|
from .exceptions import AgentsException, ModelBehaviorError, UserError
|
|
@@ -49,7 +50,7 @@ from .logger import logger
|
|
|
49
50
|
from .models.interface import ModelTracing
|
|
50
51
|
from .run_context import RunContextWrapper, TContext
|
|
51
52
|
from .stream_events import RunItemStreamEvent, StreamEvent
|
|
52
|
-
from .tool import ComputerTool, FunctionTool
|
|
53
|
+
from .tool import ComputerTool, FunctionTool, FunctionToolResult
|
|
53
54
|
from .tracing import (
|
|
54
55
|
SpanError,
|
|
55
56
|
Trace,
|
|
@@ -59,6 +60,7 @@ from .tracing import (
|
|
|
59
60
|
handoff_span,
|
|
60
61
|
trace,
|
|
61
62
|
)
|
|
63
|
+
from .util import _coro, _error_tracing
|
|
62
64
|
|
|
63
65
|
if TYPE_CHECKING:
|
|
64
66
|
from .run import RunConfig
|
|
@@ -70,6 +72,8 @@ class QueueCompleteSentinel:
|
|
|
70
72
|
|
|
71
73
|
QUEUE_COMPLETE_SENTINEL = QueueCompleteSentinel()
|
|
72
74
|
|
|
75
|
+
_NOT_FINAL_OUTPUT = ToolsToFinalOutputResult(is_final_output=False, final_output=None)
|
|
76
|
+
|
|
73
77
|
|
|
74
78
|
@dataclass
|
|
75
79
|
class ToolRunHandoff:
|
|
@@ -199,7 +203,7 @@ class RunImpl:
|
|
|
199
203
|
config=run_config,
|
|
200
204
|
),
|
|
201
205
|
)
|
|
202
|
-
new_step_items.extend(function_results)
|
|
206
|
+
new_step_items.extend([result.run_item for result in function_results])
|
|
203
207
|
new_step_items.extend(computer_results)
|
|
204
208
|
|
|
205
209
|
# Second, check if there are any handoffs
|
|
@@ -216,6 +220,36 @@ class RunImpl:
|
|
|
216
220
|
run_config=run_config,
|
|
217
221
|
)
|
|
218
222
|
|
|
223
|
+
# Third, we'll check if the tool use should result in a final output
|
|
224
|
+
check_tool_use = await cls._check_for_final_output_from_tools(
|
|
225
|
+
agent=agent,
|
|
226
|
+
tool_results=function_results,
|
|
227
|
+
context_wrapper=context_wrapper,
|
|
228
|
+
config=run_config,
|
|
229
|
+
)
|
|
230
|
+
|
|
231
|
+
if check_tool_use.is_final_output:
|
|
232
|
+
# If the output type is str, then let's just stringify it
|
|
233
|
+
if not agent.output_type or agent.output_type is str:
|
|
234
|
+
check_tool_use.final_output = str(check_tool_use.final_output)
|
|
235
|
+
|
|
236
|
+
if check_tool_use.final_output is None:
|
|
237
|
+
logger.error(
|
|
238
|
+
"Model returned a final output of None. Not raising an error because we assume"
|
|
239
|
+
"you know what you're doing."
|
|
240
|
+
)
|
|
241
|
+
|
|
242
|
+
return await cls.execute_final_output(
|
|
243
|
+
agent=agent,
|
|
244
|
+
original_input=original_input,
|
|
245
|
+
new_response=new_response,
|
|
246
|
+
pre_step_items=pre_step_items,
|
|
247
|
+
new_step_items=new_step_items,
|
|
248
|
+
final_output=check_tool_use.final_output,
|
|
249
|
+
hooks=hooks,
|
|
250
|
+
context_wrapper=context_wrapper,
|
|
251
|
+
)
|
|
252
|
+
|
|
219
253
|
# Now we can check if the model also produced a final output
|
|
220
254
|
message_items = [item for item in new_step_items if isinstance(item, MessageOutputItem)]
|
|
221
255
|
|
|
@@ -293,7 +327,7 @@ class RunImpl:
|
|
|
293
327
|
elif isinstance(output, ResponseComputerToolCall):
|
|
294
328
|
items.append(ToolCallItem(raw_item=output, agent=agent))
|
|
295
329
|
if not computer_tool:
|
|
296
|
-
|
|
330
|
+
_error_tracing.attach_error_to_current_span(
|
|
297
331
|
SpanError(
|
|
298
332
|
message="Computer tool not found",
|
|
299
333
|
data={},
|
|
@@ -324,7 +358,7 @@ class RunImpl:
|
|
|
324
358
|
# Regular function tool call
|
|
325
359
|
else:
|
|
326
360
|
if output.name not in function_map:
|
|
327
|
-
|
|
361
|
+
_error_tracing.attach_error_to_current_span(
|
|
328
362
|
SpanError(
|
|
329
363
|
message="Tool not found",
|
|
330
364
|
data={"tool_name": output.name},
|
|
@@ -355,10 +389,10 @@ class RunImpl:
|
|
|
355
389
|
hooks: RunHooks[TContext],
|
|
356
390
|
context_wrapper: RunContextWrapper[TContext],
|
|
357
391
|
config: RunConfig,
|
|
358
|
-
) -> list[
|
|
392
|
+
) -> list[FunctionToolResult]:
|
|
359
393
|
async def run_single_tool(
|
|
360
394
|
func_tool: FunctionTool, tool_call: ResponseFunctionToolCall
|
|
361
|
-
) ->
|
|
395
|
+
) -> Any:
|
|
362
396
|
with function_span(func_tool.name) as span_fn:
|
|
363
397
|
if config.trace_include_sensitive_data:
|
|
364
398
|
span_fn.span_data.input = tool_call.arguments
|
|
@@ -368,7 +402,7 @@ class RunImpl:
|
|
|
368
402
|
(
|
|
369
403
|
agent.hooks.on_tool_start(context_wrapper, agent, func_tool)
|
|
370
404
|
if agent.hooks
|
|
371
|
-
else
|
|
405
|
+
else _coro.noop_coroutine()
|
|
372
406
|
),
|
|
373
407
|
func_tool.on_invoke_tool(context_wrapper, tool_call.arguments),
|
|
374
408
|
)
|
|
@@ -378,11 +412,11 @@ class RunImpl:
|
|
|
378
412
|
(
|
|
379
413
|
agent.hooks.on_tool_end(context_wrapper, agent, func_tool, result)
|
|
380
414
|
if agent.hooks
|
|
381
|
-
else
|
|
415
|
+
else _coro.noop_coroutine()
|
|
382
416
|
),
|
|
383
417
|
)
|
|
384
418
|
except Exception as e:
|
|
385
|
-
|
|
419
|
+
_error_tracing.attach_error_to_current_span(
|
|
386
420
|
SpanError(
|
|
387
421
|
message="Error running tool",
|
|
388
422
|
data={"tool_name": func_tool.name, "error": str(e)},
|
|
@@ -404,10 +438,14 @@ class RunImpl:
|
|
|
404
438
|
results = await asyncio.gather(*tasks)
|
|
405
439
|
|
|
406
440
|
return [
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
441
|
+
FunctionToolResult(
|
|
442
|
+
tool=tool_run.function_tool,
|
|
443
|
+
output=result,
|
|
444
|
+
run_item=ToolCallOutputItem(
|
|
445
|
+
output=result,
|
|
446
|
+
raw_item=ItemHelpers.tool_call_output_item(tool_run.tool_call, str(result)),
|
|
447
|
+
agent=agent,
|
|
448
|
+
),
|
|
411
449
|
)
|
|
412
450
|
for tool_run, result in zip(tool_runs, results)
|
|
413
451
|
]
|
|
@@ -502,7 +540,7 @@ class RunImpl:
|
|
|
502
540
|
source=agent,
|
|
503
541
|
)
|
|
504
542
|
if agent.hooks
|
|
505
|
-
else
|
|
543
|
+
else _coro.noop_coroutine()
|
|
506
544
|
),
|
|
507
545
|
)
|
|
508
546
|
|
|
@@ -520,7 +558,7 @@ class RunImpl:
|
|
|
520
558
|
new_items=tuple(new_step_items),
|
|
521
559
|
)
|
|
522
560
|
if not callable(input_filter):
|
|
523
|
-
|
|
561
|
+
_error_tracing.attach_error_to_span(
|
|
524
562
|
span_handoff,
|
|
525
563
|
SpanError(
|
|
526
564
|
message="Invalid input filter",
|
|
@@ -530,7 +568,7 @@ class RunImpl:
|
|
|
530
568
|
raise UserError(f"Invalid input filter: {input_filter}")
|
|
531
569
|
filtered = input_filter(handoff_input_data)
|
|
532
570
|
if not isinstance(filtered, HandoffInputData):
|
|
533
|
-
|
|
571
|
+
_error_tracing.attach_error_to_span(
|
|
534
572
|
span_handoff,
|
|
535
573
|
SpanError(
|
|
536
574
|
message="Invalid input filter result",
|
|
@@ -591,7 +629,7 @@ class RunImpl:
|
|
|
591
629
|
hooks.on_agent_end(context_wrapper, agent, final_output),
|
|
592
630
|
agent.hooks.on_end(context_wrapper, agent, final_output)
|
|
593
631
|
if agent.hooks
|
|
594
|
-
else
|
|
632
|
+
else _coro.noop_coroutine(),
|
|
595
633
|
)
|
|
596
634
|
|
|
597
635
|
@classmethod
|
|
@@ -646,6 +684,47 @@ class RunImpl:
|
|
|
646
684
|
if event:
|
|
647
685
|
queue.put_nowait(event)
|
|
648
686
|
|
|
687
|
+
@classmethod
|
|
688
|
+
async def _check_for_final_output_from_tools(
|
|
689
|
+
cls,
|
|
690
|
+
*,
|
|
691
|
+
agent: Agent[TContext],
|
|
692
|
+
tool_results: list[FunctionToolResult],
|
|
693
|
+
context_wrapper: RunContextWrapper[TContext],
|
|
694
|
+
config: RunConfig,
|
|
695
|
+
) -> ToolsToFinalOutputResult:
|
|
696
|
+
"""Returns (i, final_output)."""
|
|
697
|
+
if not tool_results:
|
|
698
|
+
return _NOT_FINAL_OUTPUT
|
|
699
|
+
|
|
700
|
+
if agent.tool_use_behavior == "run_llm_again":
|
|
701
|
+
return _NOT_FINAL_OUTPUT
|
|
702
|
+
elif agent.tool_use_behavior == "stop_on_first_tool":
|
|
703
|
+
return ToolsToFinalOutputResult(
|
|
704
|
+
is_final_output=True, final_output=tool_results[0].output
|
|
705
|
+
)
|
|
706
|
+
elif isinstance(agent.tool_use_behavior, dict):
|
|
707
|
+
names = agent.tool_use_behavior.get("stop_at_tool_names", [])
|
|
708
|
+
for tool_result in tool_results:
|
|
709
|
+
if tool_result.tool.name in names:
|
|
710
|
+
return ToolsToFinalOutputResult(
|
|
711
|
+
is_final_output=True, final_output=tool_result.output
|
|
712
|
+
)
|
|
713
|
+
return ToolsToFinalOutputResult(is_final_output=False, final_output=None)
|
|
714
|
+
elif callable(agent.tool_use_behavior):
|
|
715
|
+
if inspect.iscoroutinefunction(agent.tool_use_behavior):
|
|
716
|
+
return await cast(
|
|
717
|
+
Awaitable[ToolsToFinalOutputResult],
|
|
718
|
+
agent.tool_use_behavior(context_wrapper, tool_results),
|
|
719
|
+
)
|
|
720
|
+
else:
|
|
721
|
+
return cast(
|
|
722
|
+
ToolsToFinalOutputResult, agent.tool_use_behavior(context_wrapper, tool_results)
|
|
723
|
+
)
|
|
724
|
+
|
|
725
|
+
logger.error(f"Invalid tool_use_behavior: {agent.tool_use_behavior}")
|
|
726
|
+
raise UserError(f"Invalid tool_use_behavior: {agent.tool_use_behavior}")
|
|
727
|
+
|
|
649
728
|
|
|
650
729
|
class TraceCtxManager:
|
|
651
730
|
"""Creates a trace only if there is no current trace, and manages the trace lifecycle."""
|
|
@@ -706,7 +785,7 @@ class ComputerAction:
|
|
|
706
785
|
(
|
|
707
786
|
agent.hooks.on_tool_start(context_wrapper, agent, action.computer_tool)
|
|
708
787
|
if agent.hooks
|
|
709
|
-
else
|
|
788
|
+
else _coro.noop_coroutine()
|
|
710
789
|
),
|
|
711
790
|
output_func,
|
|
712
791
|
)
|
|
@@ -716,7 +795,7 @@ class ComputerAction:
|
|
|
716
795
|
(
|
|
717
796
|
agent.hooks.on_tool_end(context_wrapper, agent, action.computer_tool, output)
|
|
718
797
|
if agent.hooks
|
|
719
|
-
else
|
|
798
|
+
else _coro.noop_coroutine()
|
|
720
799
|
),
|
|
721
800
|
)
|
|
722
801
|
|
agents/agent.py
CHANGED
|
@@ -4,10 +4,10 @@ import dataclasses
|
|
|
4
4
|
import inspect
|
|
5
5
|
from collections.abc import Awaitable
|
|
6
6
|
from dataclasses import dataclass, field
|
|
7
|
-
from typing import TYPE_CHECKING, Any, Callable, Generic, cast
|
|
7
|
+
from typing import TYPE_CHECKING, Any, Callable, Generic, Literal, cast
|
|
8
|
+
|
|
9
|
+
from typing_extensions import TypeAlias, TypedDict
|
|
8
10
|
|
|
9
|
-
from . import _utils
|
|
10
|
-
from ._utils import MaybeAwaitable
|
|
11
11
|
from .guardrail import InputGuardrail, OutputGuardrail
|
|
12
12
|
from .handoffs import Handoff
|
|
13
13
|
from .items import ItemHelpers
|
|
@@ -15,20 +15,49 @@ from .logger import logger
|
|
|
15
15
|
from .model_settings import ModelSettings
|
|
16
16
|
from .models.interface import Model
|
|
17
17
|
from .run_context import RunContextWrapper, TContext
|
|
18
|
-
from .tool import Tool, function_tool
|
|
18
|
+
from .tool import FunctionToolResult, Tool, function_tool
|
|
19
|
+
from .util import _transforms
|
|
20
|
+
from .util._types import MaybeAwaitable
|
|
19
21
|
|
|
20
22
|
if TYPE_CHECKING:
|
|
21
23
|
from .lifecycle import AgentHooks
|
|
22
24
|
from .result import RunResult
|
|
23
25
|
|
|
24
26
|
|
|
27
|
+
@dataclass
|
|
28
|
+
class ToolsToFinalOutputResult:
|
|
29
|
+
is_final_output: bool
|
|
30
|
+
"""Whether this is the final output. If False, the LLM will run again and receive the tool call
|
|
31
|
+
output.
|
|
32
|
+
"""
|
|
33
|
+
|
|
34
|
+
final_output: Any | None = None
|
|
35
|
+
"""The final output. Can be None if `is_final_output` is False, otherwise must match the
|
|
36
|
+
`output_type` of the agent.
|
|
37
|
+
"""
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
ToolsToFinalOutputFunction: TypeAlias = Callable[
|
|
41
|
+
[RunContextWrapper[TContext], list[FunctionToolResult]],
|
|
42
|
+
MaybeAwaitable[ToolsToFinalOutputResult],
|
|
43
|
+
]
|
|
44
|
+
"""A function that takes a run context and a list of tool results, and returns a
|
|
45
|
+
`ToolToFinalOutputResult`.
|
|
46
|
+
"""
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
class StopAtTools(TypedDict):
|
|
50
|
+
stop_at_tool_names: list[str]
|
|
51
|
+
"""A list of tool names, any of which will stop the agent from running further."""
|
|
52
|
+
|
|
53
|
+
|
|
25
54
|
@dataclass
|
|
26
55
|
class Agent(Generic[TContext]):
|
|
27
56
|
"""An agent is an AI model configured with instructions, tools, guardrails, handoffs and more.
|
|
28
57
|
|
|
29
58
|
We strongly recommend passing `instructions`, which is the "system prompt" for the agent. In
|
|
30
|
-
addition, you can pass `
|
|
31
|
-
when the agent is used inside tools/handoffs.
|
|
59
|
+
addition, you can pass `handoff_description`, which is a human-readable description of the
|
|
60
|
+
agent, used when the agent is used inside tools/handoffs.
|
|
32
61
|
|
|
33
62
|
Agents are generic on the context type. The context is a (mutable) object you create. It is
|
|
34
63
|
passed to tool functions, handoffs, guardrails, etc.
|
|
@@ -95,6 +124,25 @@ class Agent(Generic[TContext]):
|
|
|
95
124
|
"""A class that receives callbacks on various lifecycle events for this agent.
|
|
96
125
|
"""
|
|
97
126
|
|
|
127
|
+
tool_use_behavior: (
|
|
128
|
+
Literal["run_llm_again", "stop_on_first_tool"] | StopAtTools | ToolsToFinalOutputFunction
|
|
129
|
+
) = "run_llm_again"
|
|
130
|
+
"""This lets you configure how tool use is handled.
|
|
131
|
+
- "run_llm_again": The default behavior. Tools are run, and then the LLM receives the results
|
|
132
|
+
and gets to respond.
|
|
133
|
+
- "stop_on_first_tool": The output of the first tool call is used as the final output. This
|
|
134
|
+
means that the LLM does not process the result of the tool call.
|
|
135
|
+
- A list of tool names: The agent will stop running if any of the tools in the list are called.
|
|
136
|
+
The final output will be the output of the first matching tool call. The LLM does not
|
|
137
|
+
process the result of the tool call.
|
|
138
|
+
- A function: If you pass a function, it will be called with the run context and the list of
|
|
139
|
+
tool results. It must return a `ToolToFinalOutputResult`, which determines whether the tool
|
|
140
|
+
calls result in a final output.
|
|
141
|
+
|
|
142
|
+
NOTE: This configuration is specific to FunctionTools. Hosted tools, such as file search,
|
|
143
|
+
web search, etc are always processed by the LLM.
|
|
144
|
+
"""
|
|
145
|
+
|
|
98
146
|
def clone(self, **kwargs: Any) -> Agent[TContext]:
|
|
99
147
|
"""Make a copy of the agent, with the given arguments changed. For example, you could do:
|
|
100
148
|
```
|
|
@@ -126,7 +174,7 @@ class Agent(Generic[TContext]):
|
|
|
126
174
|
"""
|
|
127
175
|
|
|
128
176
|
@function_tool(
|
|
129
|
-
name_override=tool_name or
|
|
177
|
+
name_override=tool_name or _transforms.transform_string_function_style(self.name),
|
|
130
178
|
description_override=tool_description or "",
|
|
131
179
|
)
|
|
132
180
|
async def run_agent(context: RunContextWrapper, input: str) -> str:
|
agents/agent_output.py
CHANGED
|
@@ -4,10 +4,10 @@ from typing import Any
|
|
|
4
4
|
from pydantic import BaseModel, TypeAdapter
|
|
5
5
|
from typing_extensions import TypedDict, get_args, get_origin
|
|
6
6
|
|
|
7
|
-
from . import _utils
|
|
8
7
|
from .exceptions import ModelBehaviorError, UserError
|
|
9
8
|
from .strict_schema import ensure_strict_json_schema
|
|
10
9
|
from .tracing import SpanError
|
|
10
|
+
from .util import _error_tracing, _json
|
|
11
11
|
|
|
12
12
|
_WRAPPER_DICT_KEY = "response"
|
|
13
13
|
|
|
@@ -87,10 +87,10 @@ class AgentOutputSchema:
|
|
|
87
87
|
"""Validate a JSON string against the output type. Returns the validated object, or raises
|
|
88
88
|
a `ModelBehaviorError` if the JSON is invalid.
|
|
89
89
|
"""
|
|
90
|
-
validated =
|
|
90
|
+
validated = _json.validate_json(json_str, self._type_adapter, partial)
|
|
91
91
|
if self._is_wrapped:
|
|
92
92
|
if not isinstance(validated, dict):
|
|
93
|
-
|
|
93
|
+
_error_tracing.attach_error_to_current_span(
|
|
94
94
|
SpanError(
|
|
95
95
|
message="Invalid JSON",
|
|
96
96
|
data={"details": f"Expected a dict, got {type(validated)}"},
|
|
@@ -101,7 +101,7 @@ class AgentOutputSchema:
|
|
|
101
101
|
)
|
|
102
102
|
|
|
103
103
|
if _WRAPPER_DICT_KEY not in validated:
|
|
104
|
-
|
|
104
|
+
_error_tracing.attach_error_to_current_span(
|
|
105
105
|
SpanError(
|
|
106
106
|
message="Invalid JSON",
|
|
107
107
|
data={"details": f"Could not find key {_WRAPPER_DICT_KEY} in JSON"},
|
agents/function_schema.py
CHANGED
|
@@ -33,6 +33,9 @@ class FuncSchema:
|
|
|
33
33
|
"""The signature of the function."""
|
|
34
34
|
takes_context: bool = False
|
|
35
35
|
"""Whether the function takes a RunContextWrapper argument (must be the first argument)."""
|
|
36
|
+
strict_json_schema: bool = True
|
|
37
|
+
"""Whether the JSON schema is in strict mode. We **strongly** recommend setting this to True,
|
|
38
|
+
as it increases the likelihood of correct JSON input."""
|
|
36
39
|
|
|
37
40
|
def to_call_args(self, data: BaseModel) -> tuple[list[Any], dict[str, Any]]:
|
|
38
41
|
"""
|
|
@@ -337,4 +340,5 @@ def function_schema(
|
|
|
337
340
|
params_json_schema=json_schema,
|
|
338
341
|
signature=sig,
|
|
339
342
|
takes_context=takes_context,
|
|
343
|
+
strict_json_schema=strict_json_schema,
|
|
340
344
|
)
|
agents/guardrail.py
CHANGED
|
@@ -7,10 +7,10 @@ from typing import TYPE_CHECKING, Any, Callable, Generic, Union, overload
|
|
|
7
7
|
|
|
8
8
|
from typing_extensions import TypeVar
|
|
9
9
|
|
|
10
|
-
from ._utils import MaybeAwaitable
|
|
11
10
|
from .exceptions import UserError
|
|
12
11
|
from .items import TResponseInputItem
|
|
13
12
|
from .run_context import RunContextWrapper, TContext
|
|
13
|
+
from .util._types import MaybeAwaitable
|
|
14
14
|
|
|
15
15
|
if TYPE_CHECKING:
|
|
16
16
|
from .agent import Agent
|
agents/handoffs.py
CHANGED
|
@@ -8,12 +8,12 @@ from typing import TYPE_CHECKING, Any, Callable, Generic, cast, overload
|
|
|
8
8
|
from pydantic import TypeAdapter
|
|
9
9
|
from typing_extensions import TypeAlias, TypeVar
|
|
10
10
|
|
|
11
|
-
from . import _utils
|
|
12
11
|
from .exceptions import ModelBehaviorError, UserError
|
|
13
12
|
from .items import RunItem, TResponseInputItem
|
|
14
13
|
from .run_context import RunContextWrapper, TContext
|
|
15
14
|
from .strict_schema import ensure_strict_json_schema
|
|
16
15
|
from .tracing.spans import SpanError
|
|
16
|
+
from .util import _error_tracing, _json, _transforms
|
|
17
17
|
|
|
18
18
|
if TYPE_CHECKING:
|
|
19
19
|
from .agent import Agent
|
|
@@ -104,7 +104,7 @@ class Handoff(Generic[TContext]):
|
|
|
104
104
|
|
|
105
105
|
@classmethod
|
|
106
106
|
def default_tool_name(cls, agent: Agent[Any]) -> str:
|
|
107
|
-
return
|
|
107
|
+
return _transforms.transform_string_function_style(f"transfer_to_{agent.name}")
|
|
108
108
|
|
|
109
109
|
@classmethod
|
|
110
110
|
def default_tool_description(cls, agent: Agent[Any]) -> str:
|
|
@@ -192,7 +192,7 @@ def handoff(
|
|
|
192
192
|
) -> Agent[Any]:
|
|
193
193
|
if input_type is not None and type_adapter is not None:
|
|
194
194
|
if input_json is None:
|
|
195
|
-
|
|
195
|
+
_error_tracing.attach_error_to_current_span(
|
|
196
196
|
SpanError(
|
|
197
197
|
message="Handoff function expected non-null input, but got None",
|
|
198
198
|
data={"details": "input_json is None"},
|
|
@@ -200,7 +200,7 @@ def handoff(
|
|
|
200
200
|
)
|
|
201
201
|
raise ModelBehaviorError("Handoff function expected non-null input, but got None")
|
|
202
202
|
|
|
203
|
-
validated_input =
|
|
203
|
+
validated_input = _json.validate_json(
|
|
204
204
|
json_str=input_json,
|
|
205
205
|
type_adapter=type_adapter,
|
|
206
206
|
partial=False,
|
agents/items.py
CHANGED
|
@@ -129,8 +129,10 @@ class ToolCallOutputItem(RunItemBase[Union[FunctionCallOutput, ComputerCallOutpu
|
|
|
129
129
|
raw_item: FunctionCallOutput | ComputerCallOutput
|
|
130
130
|
"""The raw item from the model."""
|
|
131
131
|
|
|
132
|
-
output:
|
|
133
|
-
"""The output of the tool call.
|
|
132
|
+
output: Any
|
|
133
|
+
"""The output of the tool call. This is whatever the tool call returned; the `raw_item`
|
|
134
|
+
contains a string representation of the output.
|
|
135
|
+
"""
|
|
134
136
|
|
|
135
137
|
type: Literal["tool_call_output_item"] = "tool_call_output_item"
|
|
136
138
|
|
|
@@ -54,7 +54,7 @@ from openai.types.responses import (
|
|
|
54
54
|
ResponseUsage,
|
|
55
55
|
)
|
|
56
56
|
from openai.types.responses.response_input_param import FunctionCallOutput, ItemReference, Message
|
|
57
|
-
from openai.types.responses.response_usage import OutputTokensDetails
|
|
57
|
+
from openai.types.responses.response_usage import InputTokensDetails, OutputTokensDetails
|
|
58
58
|
|
|
59
59
|
from .. import _debug
|
|
60
60
|
from ..agent_output import AgentOutputSchema
|
|
@@ -420,6 +420,11 @@ class OpenAIChatCompletionsModel(Model):
|
|
|
420
420
|
and usage.completion_tokens_details.reasoning_tokens
|
|
421
421
|
else 0
|
|
422
422
|
),
|
|
423
|
+
input_tokens_details=InputTokensDetails(
|
|
424
|
+
cached_tokens=usage.prompt_tokens_details.cached_tokens
|
|
425
|
+
if usage.prompt_tokens_details and usage.prompt_tokens_details.cached_tokens
|
|
426
|
+
else 0
|
|
427
|
+
),
|
|
423
428
|
)
|
|
424
429
|
if usage
|
|
425
430
|
else None
|
agents/result.py
CHANGED
|
@@ -17,6 +17,7 @@ from .items import ItemHelpers, ModelResponse, RunItem, TResponseInputItem
|
|
|
17
17
|
from .logger import logger
|
|
18
18
|
from .stream_events import StreamEvent
|
|
19
19
|
from .tracing import Trace
|
|
20
|
+
from .util._pretty_print import pretty_print_result, pretty_print_run_result_streaming
|
|
20
21
|
|
|
21
22
|
if TYPE_CHECKING:
|
|
22
23
|
from ._run_impl import QueueCompleteSentinel
|
|
@@ -89,6 +90,9 @@ class RunResult(RunResultBase):
|
|
|
89
90
|
"""The last agent that was run."""
|
|
90
91
|
return self._last_agent
|
|
91
92
|
|
|
93
|
+
def __str__(self) -> str:
|
|
94
|
+
return pretty_print_result(self)
|
|
95
|
+
|
|
92
96
|
|
|
93
97
|
@dataclass
|
|
94
98
|
class RunResultStreaming(RunResultBase):
|
|
@@ -216,3 +220,6 @@ class RunResultStreaming(RunResultBase):
|
|
|
216
220
|
|
|
217
221
|
if self._output_guardrails_task and not self._output_guardrails_task.done():
|
|
218
222
|
self._output_guardrails_task.cancel()
|
|
223
|
+
|
|
224
|
+
def __str__(self) -> str:
|
|
225
|
+
return pretty_print_run_result_streaming(self)
|
agents/run.py
CHANGED
|
@@ -7,7 +7,6 @@ from typing import Any, cast
|
|
|
7
7
|
|
|
8
8
|
from openai.types.responses import ResponseCompletedEvent
|
|
9
9
|
|
|
10
|
-
from . import Model, _utils
|
|
11
10
|
from ._run_impl import (
|
|
12
11
|
NextStepFinalOutput,
|
|
13
12
|
NextStepHandoff,
|
|
@@ -33,7 +32,7 @@ from .items import ItemHelpers, ModelResponse, RunItem, TResponseInputItem
|
|
|
33
32
|
from .lifecycle import RunHooks
|
|
34
33
|
from .logger import logger
|
|
35
34
|
from .model_settings import ModelSettings
|
|
36
|
-
from .models.interface import ModelProvider
|
|
35
|
+
from .models.interface import Model, ModelProvider
|
|
37
36
|
from .models.openai_provider import OpenAIProvider
|
|
38
37
|
from .result import RunResult, RunResultStreaming
|
|
39
38
|
from .run_context import RunContextWrapper, TContext
|
|
@@ -41,6 +40,7 @@ from .stream_events import AgentUpdatedStreamEvent, RawResponsesStreamEvent
|
|
|
41
40
|
from .tracing import Span, SpanError, agent_span, get_current_trace, trace
|
|
42
41
|
from .tracing.span_data import AgentSpanData
|
|
43
42
|
from .usage import Usage
|
|
43
|
+
from .util import _coro, _error_tracing
|
|
44
44
|
|
|
45
45
|
DEFAULT_MAX_TURNS = 10
|
|
46
46
|
|
|
@@ -193,7 +193,7 @@ class Runner:
|
|
|
193
193
|
|
|
194
194
|
current_turn += 1
|
|
195
195
|
if current_turn > max_turns:
|
|
196
|
-
|
|
196
|
+
_error_tracing.attach_error_to_span(
|
|
197
197
|
current_span,
|
|
198
198
|
SpanError(
|
|
199
199
|
message="Max turns exceeded",
|
|
@@ -447,7 +447,7 @@ class Runner:
|
|
|
447
447
|
for done in asyncio.as_completed(guardrail_tasks):
|
|
448
448
|
result = await done
|
|
449
449
|
if result.output.tripwire_triggered:
|
|
450
|
-
|
|
450
|
+
_error_tracing.attach_error_to_span(
|
|
451
451
|
parent_span,
|
|
452
452
|
SpanError(
|
|
453
453
|
message="Guardrail tripwire triggered",
|
|
@@ -511,7 +511,7 @@ class Runner:
|
|
|
511
511
|
streamed_result.current_turn = current_turn
|
|
512
512
|
|
|
513
513
|
if current_turn > max_turns:
|
|
514
|
-
|
|
514
|
+
_error_tracing.attach_error_to_span(
|
|
515
515
|
current_span,
|
|
516
516
|
SpanError(
|
|
517
517
|
message="Max turns exceeded",
|
|
@@ -583,7 +583,7 @@ class Runner:
|
|
|
583
583
|
pass
|
|
584
584
|
except Exception as e:
|
|
585
585
|
if current_span:
|
|
586
|
-
|
|
586
|
+
_error_tracing.attach_error_to_span(
|
|
587
587
|
current_span,
|
|
588
588
|
SpanError(
|
|
589
589
|
message="Error in agent run",
|
|
@@ -615,7 +615,7 @@ class Runner:
|
|
|
615
615
|
(
|
|
616
616
|
agent.hooks.on_start(context_wrapper, agent)
|
|
617
617
|
if agent.hooks
|
|
618
|
-
else
|
|
618
|
+
else _coro.noop_coroutine()
|
|
619
619
|
),
|
|
620
620
|
)
|
|
621
621
|
|
|
@@ -705,7 +705,7 @@ class Runner:
|
|
|
705
705
|
(
|
|
706
706
|
agent.hooks.on_start(context_wrapper, agent)
|
|
707
707
|
if agent.hooks
|
|
708
|
-
else
|
|
708
|
+
else _coro.noop_coroutine()
|
|
709
709
|
),
|
|
710
710
|
)
|
|
711
711
|
|
|
@@ -796,7 +796,7 @@ class Runner:
|
|
|
796
796
|
# Cancel all guardrail tasks if a tripwire is triggered.
|
|
797
797
|
for t in guardrail_tasks:
|
|
798
798
|
t.cancel()
|
|
799
|
-
|
|
799
|
+
_error_tracing.attach_error_to_current_span(
|
|
800
800
|
SpanError(
|
|
801
801
|
message="Guardrail tripwire triggered",
|
|
802
802
|
data={"guardrail": result.guardrail.get_name()},
|
|
@@ -834,7 +834,7 @@ class Runner:
|
|
|
834
834
|
# Cancel all guardrail tasks if a tripwire is triggered.
|
|
835
835
|
for t in guardrail_tasks:
|
|
836
836
|
t.cancel()
|
|
837
|
-
|
|
837
|
+
_error_tracing.attach_error_to_current_span(
|
|
838
838
|
SpanError(
|
|
839
839
|
message="Guardrail tripwire triggered",
|
|
840
840
|
data={"guardrail": result.guardrail.get_name()},
|
agents/tool.py
CHANGED
|
@@ -11,14 +11,16 @@ from openai.types.responses.web_search_tool_param import UserLocation
|
|
|
11
11
|
from pydantic import ValidationError
|
|
12
12
|
from typing_extensions import Concatenate, ParamSpec
|
|
13
13
|
|
|
14
|
-
from . import _debug
|
|
15
|
-
from ._utils import MaybeAwaitable
|
|
14
|
+
from . import _debug
|
|
16
15
|
from .computer import AsyncComputer, Computer
|
|
17
16
|
from .exceptions import ModelBehaviorError
|
|
18
17
|
from .function_schema import DocstringStyle, function_schema
|
|
18
|
+
from .items import RunItem
|
|
19
19
|
from .logger import logger
|
|
20
20
|
from .run_context import RunContextWrapper
|
|
21
21
|
from .tracing import SpanError
|
|
22
|
+
from .util import _error_tracing
|
|
23
|
+
from .util._types import MaybeAwaitable
|
|
22
24
|
|
|
23
25
|
ToolParams = ParamSpec("ToolParams")
|
|
24
26
|
|
|
@@ -28,6 +30,18 @@ ToolFunctionWithContext = Callable[Concatenate[RunContextWrapper[Any], ToolParam
|
|
|
28
30
|
ToolFunction = Union[ToolFunctionWithoutContext[ToolParams], ToolFunctionWithContext[ToolParams]]
|
|
29
31
|
|
|
30
32
|
|
|
33
|
+
@dataclass
|
|
34
|
+
class FunctionToolResult:
|
|
35
|
+
tool: FunctionTool
|
|
36
|
+
"""The tool that was run."""
|
|
37
|
+
|
|
38
|
+
output: Any
|
|
39
|
+
"""The output of the tool."""
|
|
40
|
+
|
|
41
|
+
run_item: RunItem
|
|
42
|
+
"""The run item that was produced as a result of the tool call."""
|
|
43
|
+
|
|
44
|
+
|
|
31
45
|
@dataclass
|
|
32
46
|
class FunctionTool:
|
|
33
47
|
"""A tool that wraps a function. In most cases, you should use the `function_tool` helpers to
|
|
@@ -43,15 +57,15 @@ class FunctionTool:
|
|
|
43
57
|
params_json_schema: dict[str, Any]
|
|
44
58
|
"""The JSON schema for the tool's parameters."""
|
|
45
59
|
|
|
46
|
-
on_invoke_tool: Callable[[RunContextWrapper[Any], str], Awaitable[
|
|
60
|
+
on_invoke_tool: Callable[[RunContextWrapper[Any], str], Awaitable[Any]]
|
|
47
61
|
"""A function that invokes the tool with the given context and parameters. The params passed
|
|
48
62
|
are:
|
|
49
63
|
1. The tool run context.
|
|
50
64
|
2. The arguments from the LLM, as a JSON string.
|
|
51
65
|
|
|
52
|
-
You must return a string representation of the tool output
|
|
53
|
-
raise an Exception (which will cause the run to fail) or
|
|
54
|
-
will be sent back to the LLM).
|
|
66
|
+
You must return a string representation of the tool output, or something we can call `str()` on.
|
|
67
|
+
In case of errors, you can either raise an Exception (which will cause the run to fail) or
|
|
68
|
+
return a string error message (which will be sent back to the LLM).
|
|
55
69
|
"""
|
|
56
70
|
|
|
57
71
|
strict_json_schema: bool = True
|
|
@@ -137,6 +151,7 @@ def function_tool(
|
|
|
137
151
|
docstring_style: DocstringStyle | None = None,
|
|
138
152
|
use_docstring_info: bool = True,
|
|
139
153
|
failure_error_function: ToolErrorFunction | None = None,
|
|
154
|
+
strict_mode: bool = True,
|
|
140
155
|
) -> FunctionTool:
|
|
141
156
|
"""Overload for usage as @function_tool (no parentheses)."""
|
|
142
157
|
...
|
|
@@ -150,6 +165,7 @@ def function_tool(
|
|
|
150
165
|
docstring_style: DocstringStyle | None = None,
|
|
151
166
|
use_docstring_info: bool = True,
|
|
152
167
|
failure_error_function: ToolErrorFunction | None = None,
|
|
168
|
+
strict_mode: bool = True,
|
|
153
169
|
) -> Callable[[ToolFunction[...]], FunctionTool]:
|
|
154
170
|
"""Overload for usage as @function_tool(...)."""
|
|
155
171
|
...
|
|
@@ -163,6 +179,7 @@ def function_tool(
|
|
|
163
179
|
docstring_style: DocstringStyle | None = None,
|
|
164
180
|
use_docstring_info: bool = True,
|
|
165
181
|
failure_error_function: ToolErrorFunction | None = default_tool_error_function,
|
|
182
|
+
strict_mode: bool = True,
|
|
166
183
|
) -> FunctionTool | Callable[[ToolFunction[...]], FunctionTool]:
|
|
167
184
|
"""
|
|
168
185
|
Decorator to create a FunctionTool from a function. By default, we will:
|
|
@@ -186,6 +203,11 @@ def function_tool(
|
|
|
186
203
|
failure_error_function: If provided, use this function to generate an error message when
|
|
187
204
|
the tool call fails. The error message is sent to the LLM. If you pass None, then no
|
|
188
205
|
error message will be sent and instead an Exception will be raised.
|
|
206
|
+
strict_mode: Whether to enable strict mode for the tool's JSON schema. We *strongly*
|
|
207
|
+
recommend setting this to True, as it increases the likelihood of correct JSON input.
|
|
208
|
+
If False, it allows non-strict JSON schemas. For example, if a parameter has a default
|
|
209
|
+
value, it will be optional, additional properties are allowed, etc. See here for more:
|
|
210
|
+
https://platform.openai.com/docs/guides/structured-outputs?api-mode=responses#supported-schemas
|
|
189
211
|
"""
|
|
190
212
|
|
|
191
213
|
def _create_function_tool(the_func: ToolFunction[...]) -> FunctionTool:
|
|
@@ -195,9 +217,10 @@ def function_tool(
|
|
|
195
217
|
description_override=description_override,
|
|
196
218
|
docstring_style=docstring_style,
|
|
197
219
|
use_docstring_info=use_docstring_info,
|
|
220
|
+
strict_json_schema=strict_mode,
|
|
198
221
|
)
|
|
199
222
|
|
|
200
|
-
async def _on_invoke_tool_impl(ctx: RunContextWrapper[Any], input: str) ->
|
|
223
|
+
async def _on_invoke_tool_impl(ctx: RunContextWrapper[Any], input: str) -> Any:
|
|
201
224
|
try:
|
|
202
225
|
json_data: dict[str, Any] = json.loads(input) if input else {}
|
|
203
226
|
except Exception as e:
|
|
@@ -244,9 +267,9 @@ def function_tool(
|
|
|
244
267
|
else:
|
|
245
268
|
logger.debug(f"Tool {schema.name} returned {result}")
|
|
246
269
|
|
|
247
|
-
return
|
|
270
|
+
return result
|
|
248
271
|
|
|
249
|
-
async def _on_invoke_tool(ctx: RunContextWrapper[Any], input: str) ->
|
|
272
|
+
async def _on_invoke_tool(ctx: RunContextWrapper[Any], input: str) -> Any:
|
|
250
273
|
try:
|
|
251
274
|
return await _on_invoke_tool_impl(ctx, input)
|
|
252
275
|
except Exception as e:
|
|
@@ -257,7 +280,7 @@ def function_tool(
|
|
|
257
280
|
if inspect.isawaitable(result):
|
|
258
281
|
return await result
|
|
259
282
|
|
|
260
|
-
|
|
283
|
+
_error_tracing.attach_error_to_current_span(
|
|
261
284
|
SpanError(
|
|
262
285
|
message="Error running tool (non-fatal)",
|
|
263
286
|
data={
|
|
@@ -273,6 +296,7 @@ def function_tool(
|
|
|
273
296
|
description=schema.description or "",
|
|
274
297
|
params_json_schema=schema.params_json_schema,
|
|
275
298
|
on_invoke_tool=_on_invoke_tool,
|
|
299
|
+
strict_json_schema=strict_mode,
|
|
276
300
|
)
|
|
277
301
|
|
|
278
302
|
# If func is actually a callable, we were used as @function_tool with no parentheses
|
agents/tracing/create.py
CHANGED
|
@@ -3,7 +3,7 @@ from __future__ import annotations
|
|
|
3
3
|
from collections.abc import Mapping, Sequence
|
|
4
4
|
from typing import TYPE_CHECKING, Any
|
|
5
5
|
|
|
6
|
-
from
|
|
6
|
+
from ..logger import logger
|
|
7
7
|
from .setup import GLOBAL_TRACE_PROVIDER
|
|
8
8
|
from .span_data import (
|
|
9
9
|
AgentSpanData,
|
agents/tracing/processors.py
CHANGED
|
@@ -9,7 +9,7 @@ from typing import Any
|
|
|
9
9
|
|
|
10
10
|
import httpx
|
|
11
11
|
|
|
12
|
-
from
|
|
12
|
+
from ..logger import logger
|
|
13
13
|
from .processor_interface import TracingExporter, TracingProcessor
|
|
14
14
|
from .spans import Span
|
|
15
15
|
from .traces import Trace
|
|
@@ -40,7 +40,7 @@ class BackendSpanExporter(TracingExporter):
|
|
|
40
40
|
"""
|
|
41
41
|
Args:
|
|
42
42
|
api_key: The API key for the "Authorization" header. Defaults to
|
|
43
|
-
`os.environ["
|
|
43
|
+
`os.environ["OPENAI_API_KEY"]` if not provided.
|
|
44
44
|
organization: The OpenAI organization to use. Defaults to
|
|
45
45
|
`os.environ["OPENAI_ORG_ID"]` if not provided.
|
|
46
46
|
project: The OpenAI project to use. Defaults to
|
agents/tracing/scope.py
CHANGED
agents/tracing/setup.py
CHANGED
|
@@ -4,8 +4,8 @@ import os
|
|
|
4
4
|
import threading
|
|
5
5
|
from typing import Any
|
|
6
6
|
|
|
7
|
+
from ..logger import logger
|
|
7
8
|
from . import util
|
|
8
|
-
from .logger import logger
|
|
9
9
|
from .processor_interface import TracingProcessor
|
|
10
10
|
from .scope import Scope
|
|
11
11
|
from .spans import NoOpSpan, Span, SpanImpl, TSpanData
|
agents/tracing/span_data.py
CHANGED
|
@@ -51,7 +51,7 @@ class AgentSpanData(SpanData):
|
|
|
51
51
|
class FunctionSpanData(SpanData):
|
|
52
52
|
__slots__ = ("name", "input", "output")
|
|
53
53
|
|
|
54
|
-
def __init__(self, name: str, input: str | None, output:
|
|
54
|
+
def __init__(self, name: str, input: str | None, output: Any | None):
|
|
55
55
|
self.name = name
|
|
56
56
|
self.input = input
|
|
57
57
|
self.output = output
|
|
@@ -65,7 +65,7 @@ class FunctionSpanData(SpanData):
|
|
|
65
65
|
"type": self.type,
|
|
66
66
|
"name": self.name,
|
|
67
67
|
"input": self.input,
|
|
68
|
-
"output": self.output,
|
|
68
|
+
"output": str(self.output) if self.output else None,
|
|
69
69
|
}
|
|
70
70
|
|
|
71
71
|
|
agents/tracing/spans.py
CHANGED
|
@@ -6,8 +6,8 @@ from typing import Any, Generic, TypeVar
|
|
|
6
6
|
|
|
7
7
|
from typing_extensions import TypedDict
|
|
8
8
|
|
|
9
|
+
from ..logger import logger
|
|
9
10
|
from . import util
|
|
10
|
-
from .logger import logger
|
|
11
11
|
from .processor_interface import TracingProcessor
|
|
12
12
|
from .scope import Scope
|
|
13
13
|
from .span_data import SpanData
|
agents/tracing/traces.py
CHANGED
agents/util/__init__.py
ADDED
|
File without changes
|
agents/util/_coro.py
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
from typing import Any
|
|
2
|
+
|
|
3
|
+
from ..logger import logger
|
|
4
|
+
from ..tracing import Span, SpanError, get_current_span
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def attach_error_to_span(span: Span[Any], error: SpanError) -> None:
|
|
8
|
+
span.set_error(error)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def attach_error_to_current_span(error: SpanError) -> None:
|
|
12
|
+
span = get_current_span()
|
|
13
|
+
if span:
|
|
14
|
+
attach_error_to_span(span, error)
|
|
15
|
+
else:
|
|
16
|
+
logger.warning(f"No span to add error {error} to")
|
agents/util/_json.py
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import Literal
|
|
4
|
+
|
|
5
|
+
from pydantic import TypeAdapter, ValidationError
|
|
6
|
+
from typing_extensions import TypeVar
|
|
7
|
+
|
|
8
|
+
from ..exceptions import ModelBehaviorError
|
|
9
|
+
from ..tracing import SpanError
|
|
10
|
+
from ._error_tracing import attach_error_to_current_span
|
|
11
|
+
|
|
12
|
+
T = TypeVar("T")
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def validate_json(json_str: str, type_adapter: TypeAdapter[T], partial: bool) -> T:
|
|
16
|
+
partial_setting: bool | Literal["off", "on", "trailing-strings"] = (
|
|
17
|
+
"trailing-strings" if partial else False
|
|
18
|
+
)
|
|
19
|
+
try:
|
|
20
|
+
validated = type_adapter.validate_json(json_str, experimental_allow_partial=partial_setting)
|
|
21
|
+
return validated
|
|
22
|
+
except ValidationError as e:
|
|
23
|
+
attach_error_to_current_span(
|
|
24
|
+
SpanError(
|
|
25
|
+
message="Invalid JSON provided",
|
|
26
|
+
data={},
|
|
27
|
+
)
|
|
28
|
+
)
|
|
29
|
+
raise ModelBehaviorError(
|
|
30
|
+
f"Invalid JSON when parsing {json_str} for {type_adapter}; {e}"
|
|
31
|
+
) from e
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
from typing import TYPE_CHECKING
|
|
2
|
+
|
|
3
|
+
from pydantic import BaseModel
|
|
4
|
+
|
|
5
|
+
if TYPE_CHECKING:
|
|
6
|
+
from ..result import RunResult, RunResultBase, RunResultStreaming
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def _indent(text: str, indent_level: int) -> str:
|
|
10
|
+
indent_string = " " * indent_level
|
|
11
|
+
return "\n".join(f"{indent_string}{line}" for line in text.splitlines())
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def _final_output_str(result: "RunResultBase") -> str:
|
|
15
|
+
if result.final_output is None:
|
|
16
|
+
return "None"
|
|
17
|
+
elif isinstance(result.final_output, str):
|
|
18
|
+
return result.final_output
|
|
19
|
+
elif isinstance(result.final_output, BaseModel):
|
|
20
|
+
return result.final_output.model_dump_json(indent=2)
|
|
21
|
+
else:
|
|
22
|
+
return str(result.final_output)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def pretty_print_result(result: "RunResult") -> str:
|
|
26
|
+
output = "RunResult:"
|
|
27
|
+
output += f'\n- Last agent: Agent(name="{result.last_agent.name}", ...)'
|
|
28
|
+
output += (
|
|
29
|
+
f"\n- Final output ({type(result.final_output).__name__}):\n"
|
|
30
|
+
f"{_indent(_final_output_str(result), 2)}"
|
|
31
|
+
)
|
|
32
|
+
output += f"\n- {len(result.new_items)} new item(s)"
|
|
33
|
+
output += f"\n- {len(result.raw_responses)} raw response(s)"
|
|
34
|
+
output += f"\n- {len(result.input_guardrail_results)} input guardrail result(s)"
|
|
35
|
+
output += f"\n- {len(result.output_guardrail_results)} output guardrail result(s)"
|
|
36
|
+
output += "\n(See `RunResult` for more details)"
|
|
37
|
+
|
|
38
|
+
return output
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def pretty_print_run_result_streaming(result: "RunResultStreaming") -> str:
|
|
42
|
+
output = "RunResultStreaming:"
|
|
43
|
+
output += f'\n- Current agent: Agent(name="{result.current_agent.name}", ...)'
|
|
44
|
+
output += f"\n- Current turn: {result.current_turn}"
|
|
45
|
+
output += f"\n- Max turns: {result.max_turns}"
|
|
46
|
+
output += f"\n- Is complete: {result.is_complete}"
|
|
47
|
+
output += (
|
|
48
|
+
f"\n- Final output ({type(result.final_output).__name__}):\n"
|
|
49
|
+
f"{_indent(_final_output_str(result), 2)}"
|
|
50
|
+
)
|
|
51
|
+
output += f"\n- {len(result.new_items)} new item(s)"
|
|
52
|
+
output += f"\n- {len(result.raw_responses)} raw response(s)"
|
|
53
|
+
output += f"\n- {len(result.input_guardrail_results)} input guardrail result(s)"
|
|
54
|
+
output += f"\n- {len(result.output_guardrail_results)} output guardrail result(s)"
|
|
55
|
+
output += "\n(See `RunResultStreaming` for more details)"
|
|
56
|
+
return output
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import re
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
def transform_string_function_style(name: str) -> str:
|
|
5
|
+
# Replace spaces with underscores
|
|
6
|
+
name = name.replace(" ", "_")
|
|
7
|
+
|
|
8
|
+
# Replace non-alphanumeric characters with underscores
|
|
9
|
+
name = re.sub(r"[^a-zA-Z0-9]", "_", name)
|
|
10
|
+
|
|
11
|
+
return name.lower()
|
agents/util/_types.py
ADDED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: openai-agents
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.5
|
|
4
4
|
Summary: OpenAI Agents SDK
|
|
5
5
|
Project-URL: Homepage, https://github.com/openai/openai-agents-python
|
|
6
6
|
Project-URL: Repository, https://github.com/openai/openai-agents-python
|
|
@@ -19,7 +19,7 @@ Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
|
19
19
|
Classifier: Typing :: Typed
|
|
20
20
|
Requires-Python: >=3.9
|
|
21
21
|
Requires-Dist: griffe<2,>=1.5.6
|
|
22
|
-
Requires-Dist: openai>=1.66.
|
|
22
|
+
Requires-Dist: openai>=1.66.5
|
|
23
23
|
Requires-Dist: pydantic<3,>=2.10
|
|
24
24
|
Requires-Dist: requests<3,>=2.0
|
|
25
25
|
Requires-Dist: types-requests<3,>=2.0
|
|
@@ -35,7 +35,7 @@ The OpenAI Agents SDK is a lightweight yet powerful framework for building multi
|
|
|
35
35
|
### Core concepts:
|
|
36
36
|
|
|
37
37
|
1. [**Agents**](https://openai.github.io/openai-agents-python/agents): LLMs configured with instructions, tools, guardrails, and handoffs
|
|
38
|
-
2. [**Handoffs**](https://openai.github.io/openai-agents-python/handoffs/):
|
|
38
|
+
2. [**Handoffs**](https://openai.github.io/openai-agents-python/handoffs/): A specialized tool call used by the Agents SDK for transferring control between agents
|
|
39
39
|
3. [**Guardrails**](https://openai.github.io/openai-agents-python/guardrails/): Configurable safety checks for input and output validation
|
|
40
40
|
4. [**Tracing**](https://openai.github.io/openai-agents-python/tracing/): Built-in tracking of agent runs, allowing you to view, debug and optimize your workflows
|
|
41
41
|
|
|
@@ -170,7 +170,7 @@ The Agents SDK is designed to be highly flexible, allowing you to model a wide r
|
|
|
170
170
|
|
|
171
171
|
## Tracing
|
|
172
172
|
|
|
173
|
-
The Agents SDK automatically traces your agent runs, making it easy to track and debug the behavior of your agents. Tracing is extensible by design, supporting custom spans and a wide variety of external destinations, including [Logfire](https://logfire.pydantic.dev/docs/integrations/llms/openai/#openai-agents), [AgentOps](https://docs.agentops.ai/v1/integrations/agentssdk), [Braintrust](https://braintrust.dev/docs/guides/traces/integrations#openai-agents-sdk), [Scorecard](https://docs.scorecard.io/docs/documentation/features/tracing#openai-agents-sdk-integration), and [Keywords AI](https://docs.keywordsai.co/integration/development-frameworks/openai-agent). For more details about how to customize or disable tracing, see [Tracing](http://openai.github.io/openai-agents-python/tracing).
|
|
173
|
+
The Agents SDK automatically traces your agent runs, making it easy to track and debug the behavior of your agents. Tracing is extensible by design, supporting custom spans and a wide variety of external destinations, including [Logfire](https://logfire.pydantic.dev/docs/integrations/llms/openai/#openai-agents), [AgentOps](https://docs.agentops.ai/v1/integrations/agentssdk), [Braintrust](https://braintrust.dev/docs/guides/traces/integrations#openai-agents-sdk), [Scorecard](https://docs.scorecard.io/docs/documentation/features/tracing#openai-agents-sdk-integration), and [Keywords AI](https://docs.keywordsai.co/integration/development-frameworks/openai-agent). For more details about how to customize or disable tracing, see [Tracing](http://openai.github.io/openai-agents-python/tracing), which also includes a larger list of [external tracing processors](http://openai.github.io/openai-agents-python/tracing/#external-tracing-processors-list).
|
|
174
174
|
|
|
175
175
|
## Development (only needed if you need to edit the SDK/examples)
|
|
176
176
|
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
agents/__init__.py,sha256=vdpHPLytdNImdTlOJUnZi_Wx6Egot3q_InhcFixd6zU,6422
|
|
2
|
+
agents/_config.py,sha256=ANrM7GP2VSQehDkMc9qocxkUlPwqU-i5sieMJyEwxpM,796
|
|
3
|
+
agents/_debug.py,sha256=7OKys2lDjeCtGggTkM53m_8vw0WIr3yt-_JPBDAnsw0,608
|
|
4
|
+
agents/_run_impl.py,sha256=B-YeWxms2vi3SHMSsHPEjif0ZbcpxDetRugo-_mkUVw,31991
|
|
5
|
+
agents/agent.py,sha256=ODhpQ74vZfYpk_8vxExJEXBl1dJVsgudXabY9t069qQ,8324
|
|
6
|
+
agents/agent_output.py,sha256=sUlsur0_C2pPokyvspo5gxIkM0PtcNxdbZmeu_6Z4TE,5379
|
|
7
|
+
agents/computer.py,sha256=XD44UgiUWSfniv-xKwwDP6wFKVwBiZkpaL1hO-0-7ZA,2516
|
|
8
|
+
agents/exceptions.py,sha256=F3AltRt27PGdhbFqKBhRJL9eHqoN4SQx7oxBn0GWmhs,1856
|
|
9
|
+
agents/function_schema.py,sha256=8f90espzzVE4i9cCiOYAzX5zHHhYm195gX9Ytvtr1P4,12908
|
|
10
|
+
agents/guardrail.py,sha256=vWWcApo9s_6aHapQ5AMko08MqC8Jrlk-J5iqIRctCDQ,9291
|
|
11
|
+
agents/handoffs.py,sha256=wRg-HBGKBZev88mOg_mfv6CR8T2kewZM8eX3tb71l1g,9043
|
|
12
|
+
agents/items.py,sha256=xCoX-ZcUUs3WHN90_o8PQSnX8jt8oQ2TJPz7k74ooQ4,8182
|
|
13
|
+
agents/lifecycle.py,sha256=wYFG6PLSKQ7bICKVbB8oGtdoJNINGq9obh2RSKlAkDE,2938
|
|
14
|
+
agents/logger.py,sha256=p_ef7vWKpBev5FFybPJjhrCCQizK08Yy1A2EDO1SNNg,60
|
|
15
|
+
agents/model_settings.py,sha256=4JOqsLswjdrEszNqNEJ_dYjxUMCyt68hOIdgxlXELw0,2169
|
|
16
|
+
agents/result.py,sha256=JOscHoh2EIUY4w-ESO500Z3DnNYq67vtkRrWr70fOr4,8421
|
|
17
|
+
agents/run.py,sha256=SI0u7XQ6e3lEP6v1k530rDDcJJbg8K_DcdK2o0leCqI,37129
|
|
18
|
+
agents/run_context.py,sha256=vuSUQM8O4CLensQY27-22fOqECnw7yvwL9U3WO8b_bk,851
|
|
19
|
+
agents/stream_events.py,sha256=ULgBEcL_H4vklZoxhpY2yomeoxVF0UiXvswsFsjFv4s,1547
|
|
20
|
+
agents/strict_schema.py,sha256=FEyEvF3ZjxIHRLmraBGZyjJjuFiPCZGaCFV22LlwaTQ,5783
|
|
21
|
+
agents/tool.py,sha256=XKeR1khfbaPbyO8DiGsn8WMO_Hkbrmm9NQzGeRsKcPs,11641
|
|
22
|
+
agents/usage.py,sha256=-MZOmSDVdWxA2V_yVVnmUcwVcLdvYFccv0HXZ7Ow3_A,733
|
|
23
|
+
agents/version.py,sha256=bkeg2DaYBS8OnV7R7J6OuF5pNA__0mJ4QZsJjC1DTI0,223
|
|
24
|
+
agents/extensions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
25
|
+
agents/extensions/handoff_filters.py,sha256=2cXxu1JROez96CpTiGuT9PIuaIrIE8ksP01fX83krKM,1977
|
|
26
|
+
agents/extensions/handoff_prompt.py,sha256=oGWN0uNh3Z1L7E-Ev2up8W084fFrDNOsLDy7P6bcmic,1006
|
|
27
|
+
agents/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
28
|
+
agents/models/_openai_shared.py,sha256=4Ngwo2Fv2RXY61Pqck1cYPkSln2tDnb8Ai-ao4QG-iE,836
|
|
29
|
+
agents/models/fake_id.py,sha256=lbXjUUSMeAQ8eFx4V5QLUnBClHE6adJlYYav55RlG5w,268
|
|
30
|
+
agents/models/interface.py,sha256=dgIlKyPaCbNRTHXxd6x7OQwJuAelG3F-C19P-aacHWQ,3129
|
|
31
|
+
agents/models/openai_chatcompletions.py,sha256=xs2JdEl0taqz3LIRWL8etr88tzpa_UWggAwAQPTyoxQ,39375
|
|
32
|
+
agents/models/openai_provider.py,sha256=3zKt8stSm0IcDJzX8GqXa3UcECKK79A290Zzem1nlUo,2784
|
|
33
|
+
agents/models/openai_responses.py,sha256=4CowZT0wAMflEzDgi6hEidcMq_0zchIm2uX_vV090TM,13386
|
|
34
|
+
agents/tracing/__init__.py,sha256=pp2_mBCQGL9oN6_czCWHQsV4ZTEOcy1AVxdjQ41PNr0,2424
|
|
35
|
+
agents/tracing/create.py,sha256=xn0n1Zr6Az4SMw0x_OeBNiBHJ1yYxL1FNhA_bLhBodY,12111
|
|
36
|
+
agents/tracing/logger.py,sha256=J4KUDRSGa7x5UVfUwWe-gbKwoaq8AeETRqkPt3QvtGg,68
|
|
37
|
+
agents/tracing/processor_interface.py,sha256=wNyZCwNJko5CrUIWD_lMou5ppQ67CFYwvWRsJRM3up8,1659
|
|
38
|
+
agents/tracing/processors.py,sha256=z3NAwo4ZG8KloEIq7ihIadxMfduL_cECY5XCgOaK1H8,9595
|
|
39
|
+
agents/tracing/scope.py,sha256=84gOESqFfR2E_XCZsT11DLyR-3UTyqxHrfBBjH1Ic44,1373
|
|
40
|
+
agents/tracing/setup.py,sha256=1wRMIVnsMOx5nWWnldqbTXg44a7-ABcC0jZK4q4I-S8,6729
|
|
41
|
+
agents/tracing/span_data.py,sha256=5VOoiHHakviJDeiLcPAQS_jy2hPS__GwKsREAUg8Bd4,4604
|
|
42
|
+
agents/tracing/spans.py,sha256=6vVzocGMsdgIma1ksqkBZmhar91xj4RpgcpUC3iibqg,6606
|
|
43
|
+
agents/tracing/traces.py,sha256=G5LlECSK-DBRFP-bjT8maZjBQulz6SaHILYauUVlfq8,4775
|
|
44
|
+
agents/tracing/util.py,sha256=BsDvn2rjE4SRQvfm55utljT8agdA0Z36KWXd1vdx4hs,392
|
|
45
|
+
agents/util/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
46
|
+
agents/util/_coro.py,sha256=S38XUYFC7bqTELSgMUBsAX1GoRlIrV7coupcUAWH__4,45
|
|
47
|
+
agents/util/_error_tracing.py,sha256=hdkYNx180b18lP0PSB1toE5atNHsMg_Bm9Osw812vLo,421
|
|
48
|
+
agents/util/_json.py,sha256=eKeQeMlQkBXRFeL3ilNZFmszGyfhtzZdW_GW_As6dcg,972
|
|
49
|
+
agents/util/_pretty_print.py,sha256=rRVp24UmTgzCm-W4ritWBOxxnPRinzFdrZlOhTi1KVQ,2227
|
|
50
|
+
agents/util/_transforms.py,sha256=CZe74NOHkHneyo4fHYfFWksCSTn-kXtEyejL9P0_xlA,270
|
|
51
|
+
agents/util/_types.py,sha256=8KxYfCw0gYSMWcQmacJoc3Q7Lc46LmT-AWvhF10KJ-E,160
|
|
52
|
+
openai_agents-0.0.5.dist-info/METADATA,sha256=fHalk7G3p4YxZCj85yRVbOpYX63vgxcR0mIFdEEpfgU,7757
|
|
53
|
+
openai_agents-0.0.5.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
54
|
+
openai_agents-0.0.5.dist-info/licenses/LICENSE,sha256=E994EspT7Krhy0qGiES7WYNzBHrh1YDk3r--8d1baRU,1063
|
|
55
|
+
openai_agents-0.0.5.dist-info/RECORD,,
|
agents/_utils.py
DELETED
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
|
|
3
|
-
import re
|
|
4
|
-
from collections.abc import Awaitable
|
|
5
|
-
from typing import Any, Literal, Union
|
|
6
|
-
|
|
7
|
-
from pydantic import TypeAdapter, ValidationError
|
|
8
|
-
from typing_extensions import TypeVar
|
|
9
|
-
|
|
10
|
-
from .exceptions import ModelBehaviorError
|
|
11
|
-
from .logger import logger
|
|
12
|
-
from .tracing import Span, SpanError, get_current_span
|
|
13
|
-
|
|
14
|
-
T = TypeVar("T")
|
|
15
|
-
|
|
16
|
-
MaybeAwaitable = Union[Awaitable[T], T]
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
def transform_string_function_style(name: str) -> str:
|
|
20
|
-
# Replace spaces with underscores
|
|
21
|
-
name = name.replace(" ", "_")
|
|
22
|
-
|
|
23
|
-
# Replace non-alphanumeric characters with underscores
|
|
24
|
-
name = re.sub(r"[^a-zA-Z0-9]", "_", name)
|
|
25
|
-
|
|
26
|
-
return name.lower()
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
def validate_json(json_str: str, type_adapter: TypeAdapter[T], partial: bool) -> T:
|
|
30
|
-
partial_setting: bool | Literal["off", "on", "trailing-strings"] = (
|
|
31
|
-
"trailing-strings" if partial else False
|
|
32
|
-
)
|
|
33
|
-
try:
|
|
34
|
-
validated = type_adapter.validate_json(json_str, experimental_allow_partial=partial_setting)
|
|
35
|
-
return validated
|
|
36
|
-
except ValidationError as e:
|
|
37
|
-
attach_error_to_current_span(
|
|
38
|
-
SpanError(
|
|
39
|
-
message="Invalid JSON provided",
|
|
40
|
-
data={},
|
|
41
|
-
)
|
|
42
|
-
)
|
|
43
|
-
raise ModelBehaviorError(
|
|
44
|
-
f"Invalid JSON when parsing {json_str} for {type_adapter}; {e}"
|
|
45
|
-
) from e
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
def attach_error_to_span(span: Span[Any], error: SpanError) -> None:
|
|
49
|
-
span.set_error(error)
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
def attach_error_to_current_span(error: SpanError) -> None:
|
|
53
|
-
span = get_current_span()
|
|
54
|
-
if span:
|
|
55
|
-
attach_error_to_span(span, error)
|
|
56
|
-
else:
|
|
57
|
-
logger.warning(f"No span to add error {error} to")
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
async def noop_coroutine() -> None:
|
|
61
|
-
pass
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
agents/__init__.py,sha256=NGc7r2Su7RM8c1Ym3gl_LWDFMiIiL_bY-YUgFDDugYo,6267
|
|
2
|
-
agents/_config.py,sha256=ANrM7GP2VSQehDkMc9qocxkUlPwqU-i5sieMJyEwxpM,796
|
|
3
|
-
agents/_debug.py,sha256=7OKys2lDjeCtGggTkM53m_8vw0WIr3yt-_JPBDAnsw0,608
|
|
4
|
-
agents/_run_impl.py,sha256=jMlWtHi7blDC8bJTpzQ1-Xi9wcPBiGUSyfItgw-L1io,28550
|
|
5
|
-
agents/_utils.py,sha256=L21Hdl20U66Asp-W61yTnahmo8b6X58jsgdUBWb9_Rk,1685
|
|
6
|
-
agents/agent.py,sha256=Y0lnIva9qL_WJVUVxDQtSrMa0KuM5IXLWK0q6CzIxas,6297
|
|
7
|
-
agents/agent_output.py,sha256=k271F9MgMaoS1nPtsSwsURP8mNxv8VrEOWrv7PJSQT4,5345
|
|
8
|
-
agents/computer.py,sha256=XD44UgiUWSfniv-xKwwDP6wFKVwBiZkpaL1hO-0-7ZA,2516
|
|
9
|
-
agents/exceptions.py,sha256=F3AltRt27PGdhbFqKBhRJL9eHqoN4SQx7oxBn0GWmhs,1856
|
|
10
|
-
agents/function_schema.py,sha256=OgeuiDhLowhYt6T9CU-7Fk05uKIxPaDPgL2hdnMFjpQ,12666
|
|
11
|
-
agents/guardrail.py,sha256=3y4oGa-dPp75nsS15zZdJ-GBT34jDu5c8gMeFHC4SME,9286
|
|
12
|
-
agents/handoffs.py,sha256=onlvwSCTNJKof2Ftk-qZ5-zxTNT9AimjvyOcxj4Rp38,8999
|
|
13
|
-
agents/items.py,sha256=DQPAJQkAVRR9Js-RVDtp4eizxiVaL30bbB0W-8U7GuQ,8069
|
|
14
|
-
agents/lifecycle.py,sha256=wYFG6PLSKQ7bICKVbB8oGtdoJNINGq9obh2RSKlAkDE,2938
|
|
15
|
-
agents/logger.py,sha256=p_ef7vWKpBev5FFybPJjhrCCQizK08Yy1A2EDO1SNNg,60
|
|
16
|
-
agents/model_settings.py,sha256=4JOqsLswjdrEszNqNEJ_dYjxUMCyt68hOIdgxlXELw0,2169
|
|
17
|
-
agents/result.py,sha256=k8B5Q9Vf-H6IzGaEHqJyMNoairUcF4yCfnePS8Qanzo,8176
|
|
18
|
-
agents/run.py,sha256=GLPPfHH7MswO_5oW27y7RsZVY5rbkvyCBxG4kbN5y-Q,37064
|
|
19
|
-
agents/run_context.py,sha256=vuSUQM8O4CLensQY27-22fOqECnw7yvwL9U3WO8b_bk,851
|
|
20
|
-
agents/stream_events.py,sha256=ULgBEcL_H4vklZoxhpY2yomeoxVF0UiXvswsFsjFv4s,1547
|
|
21
|
-
agents/strict_schema.py,sha256=FEyEvF3ZjxIHRLmraBGZyjJjuFiPCZGaCFV22LlwaTQ,5783
|
|
22
|
-
agents/tool.py,sha256=I6MD3H3wB9ka9FUOg6hlx9Swe9fceSnbH2BPMmNYXl0,10629
|
|
23
|
-
agents/usage.py,sha256=-MZOmSDVdWxA2V_yVVnmUcwVcLdvYFccv0HXZ7Ow3_A,733
|
|
24
|
-
agents/version.py,sha256=bkeg2DaYBS8OnV7R7J6OuF5pNA__0mJ4QZsJjC1DTI0,223
|
|
25
|
-
agents/extensions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
26
|
-
agents/extensions/handoff_filters.py,sha256=2cXxu1JROez96CpTiGuT9PIuaIrIE8ksP01fX83krKM,1977
|
|
27
|
-
agents/extensions/handoff_prompt.py,sha256=oGWN0uNh3Z1L7E-Ev2up8W084fFrDNOsLDy7P6bcmic,1006
|
|
28
|
-
agents/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
29
|
-
agents/models/_openai_shared.py,sha256=4Ngwo2Fv2RXY61Pqck1cYPkSln2tDnb8Ai-ao4QG-iE,836
|
|
30
|
-
agents/models/fake_id.py,sha256=lbXjUUSMeAQ8eFx4V5QLUnBClHE6adJlYYav55RlG5w,268
|
|
31
|
-
agents/models/interface.py,sha256=dgIlKyPaCbNRTHXxd6x7OQwJuAelG3F-C19P-aacHWQ,3129
|
|
32
|
-
agents/models/openai_chatcompletions.py,sha256=e7iA9mxflbVKNCbt11gxCXKHRjMS1JXd0vpzjlOQOI8,39059
|
|
33
|
-
agents/models/openai_provider.py,sha256=3zKt8stSm0IcDJzX8GqXa3UcECKK79A290Zzem1nlUo,2784
|
|
34
|
-
agents/models/openai_responses.py,sha256=4CowZT0wAMflEzDgi6hEidcMq_0zchIm2uX_vV090TM,13386
|
|
35
|
-
agents/tracing/__init__.py,sha256=pp2_mBCQGL9oN6_czCWHQsV4ZTEOcy1AVxdjQ41PNr0,2424
|
|
36
|
-
agents/tracing/create.py,sha256=PAhfJKAeJ8jbZvxylTiikU_LqAhezYHphR4jG5EdaAE,12110
|
|
37
|
-
agents/tracing/logger.py,sha256=J4KUDRSGa7x5UVfUwWe-gbKwoaq8AeETRqkPt3QvtGg,68
|
|
38
|
-
agents/tracing/processor_interface.py,sha256=wNyZCwNJko5CrUIWD_lMou5ppQ67CFYwvWRsJRM3up8,1659
|
|
39
|
-
agents/tracing/processors.py,sha256=74BB0w3XQjerlYN6kgRiqtV4VPAvZSMTPByutcX464c,9600
|
|
40
|
-
agents/tracing/scope.py,sha256=x1m-aYilS1DeeV4L7Ckv55LVWod7c_nnTKoCGhJCumk,1372
|
|
41
|
-
agents/tracing/setup.py,sha256=P5JaIcHej6m62rb27bSutN2Bqv0XSD9Z_Ki7ynCVdbs,6728
|
|
42
|
-
agents/tracing/span_data.py,sha256=UQUPpMQ7Z1XOqKFJNHUxAJUVPwa6JMfGa7dm_NovuhQ,4574
|
|
43
|
-
agents/tracing/spans.py,sha256=KWCqcRwUlt85NCZPQp98UIF5vAQAVWuVWQh3tgPK0WE,6605
|
|
44
|
-
agents/tracing/traces.py,sha256=GL9EoEQKVk7eo0BcfRfQ6C7tdzlmPhkneQn4fdsCdqA,4774
|
|
45
|
-
agents/tracing/util.py,sha256=BsDvn2rjE4SRQvfm55utljT8agdA0Z36KWXd1vdx4hs,392
|
|
46
|
-
openai_agents-0.0.4.dist-info/METADATA,sha256=8a-UqdtxRJCgwuT6jsfJ1MwDwwYWS-NnbcJB52QpZP4,7582
|
|
47
|
-
openai_agents-0.0.4.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
48
|
-
openai_agents-0.0.4.dist-info/licenses/LICENSE,sha256=E994EspT7Krhy0qGiES7WYNzBHrh1YDk3r--8d1baRU,1063
|
|
49
|
-
openai_agents-0.0.4.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|