Skip to content

Commit 1f546e2

Browse files
committed
fix: restore event_queue property and 3.9‑compatible typing in ToolContext
1 parent 0a7bb1b commit 1f546e2

File tree

2 files changed

+44
-12
lines changed

2 files changed

+44
-12
lines changed

src/agents/agent.py

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
if TYPE_CHECKING:
3333
from .lifecycle import AgentHooks
3434
from .mcp import MCPServer
35-
from .result import RunResult
35+
from .result import RunResult, RunResultStreaming
3636

3737

3838
@dataclass
@@ -381,9 +381,11 @@ def as_tool(
381381
self,
382382
tool_name: str | None,
383383
tool_description: str | None,
384+
*,
384385
custom_output_extractor: Callable[[RunResult], Awaitable[str]] | None = None,
385386
is_enabled: bool
386387
| Callable[[RunContextWrapper[Any], AgentBase[Any]], MaybeAwaitable[bool]] = True,
388+
stream_inner_events: bool = False,
387389
) -> Tool:
388390
"""Transform this agent into a tool, callable by other agents.
389391
@@ -412,17 +414,36 @@ def as_tool(
412414
async def run_agent(context: RunContextWrapper, input: str) -> str:
413415
from .run import Runner
414416

415-
output = await Runner.run(
416-
starting_agent=self,
417-
input=input,
418-
context=context.context,
419-
)
417+
output_run: RunResult | RunResultStreaming
418+
if stream_inner_events:
419+
from .stream_events import RunItemStreamEvent
420+
421+
sub_run = Runner.run_streamed(
422+
self,
423+
input=input,
424+
context=context.context,
425+
)
426+
parent_queue = getattr(context, "_event_queue", None)
427+
async for ev in sub_run.stream_events():
428+
if parent_queue is not None and isinstance(ev, RunItemStreamEvent):
429+
if ev.name in ("tool_called", "tool_output"):
430+
parent_queue.put_nowait(ev)
431+
output_run = sub_run
432+
else:
433+
output_run = await Runner.run(
434+
starting_agent=self,
435+
input=input,
436+
context=context.context,
437+
)
438+
420439
if custom_output_extractor:
421-
return await custom_output_extractor(output)
440+
return await custom_output_extractor(cast(Any, output_run))
422441

423-
return ItemHelpers.text_message_outputs(output.new_items)
442+
return ItemHelpers.text_message_outputs(output_run.new_items)
424443

425-
return run_agent
444+
tool = run_agent
445+
tool.stream_inner_events = stream_inner_events
446+
return tool
426447

427448
async def get_system_prompt(self, run_context: RunContextWrapper[TContext]) -> str | None:
428449
if isinstance(self.instructions, str):

src/agents/tool_context.py

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from dataclasses import dataclass, field, fields
2-
from typing import Any, Optional
2+
from typing import Any, Optional, Union
3+
import asyncio
34

45
from openai.types.responses import ResponseFunctionToolCall
56

@@ -21,14 +22,24 @@ class ToolContext(RunContextWrapper[TContext]):
2122
tool_name: str = field(default_factory=_assert_must_pass_tool_name)
2223
"""The name of the tool being invoked."""
2324

24-
tool_call_id: str = field(default_factory=_assert_must_pass_tool_call_id)
25+
tool_call_id: Union[str, int] = field(default_factory=_assert_must_pass_tool_call_id)
2526
"""The ID of the tool call."""
2627

28+
_event_queue: Optional[asyncio.Queue[Any]] = field(default=None, init=False, repr=False)
29+
30+
@property
31+
def event_queue(self) -> Optional[asyncio.Queue[Any]]:
32+
return self._event_queue
33+
34+
@event_queue.setter
35+
def event_queue(self, queue: Optional[asyncio.Queue[Any]]) -> None:
36+
self._event_queue = queue
37+
2738
@classmethod
2839
def from_agent_context(
2940
cls,
3041
context: RunContextWrapper[TContext],
31-
tool_call_id: str,
42+
tool_call_id: Union[str, int],
3243
tool_call: Optional[ResponseFunctionToolCall] = None,
3344
) -> "ToolContext":
3445
"""

0 commit comments

Comments
 (0)