from __future__ import annotations
import pytest
from typing import cast
from agents import Agent, RunConfig, Runner
from agents.tool import function_tool
from agents.run import (
get_current_run_config,
set_current_run_config,
reset_current_run_config,
)
from .fake_model import FakeModel
from .test_responses import get_function_tool_call, get_text_message
@pytest.mark.asyncio
async def test_run_config_inheritance_enabled():
"""Test that run_config is inherited when pass_run_config_to_sub_agents=True"""
inherited_configs = []
@function_tool
async def config_capture_tool() -> str:
"""Tool that captures the current run config"""
current_config = get_current_run_config()
inherited_configs.append(current_config)
return "config_captured"
sub_agent = Agent(
name="SubAgent",
instructions="You are a sub agent",
model=FakeModel(),
tools=[config_capture_tool],
)
sub_fake_model = cast(FakeModel, sub_agent.model)
sub_fake_model.add_multiple_turn_outputs(
[
[get_function_tool_call("config_capture_tool", "{}")],
[get_text_message("sub_agent_response")],
]
)
parent_agent = Agent(
name="ParentAgent",
instructions="You are a parent agent",
model=FakeModel(),
tools=[
sub_agent.as_tool(
tool_name="sub_agent_tool", tool_description="Call the sub agent"
)
],
)
parent_fake_model = cast(FakeModel, parent_agent.model)
parent_fake_model.add_multiple_turn_outputs(
[
[get_function_tool_call("sub_agent_tool", '{"input": "test"}')],
[get_text_message("parent_response")],
]
)
run_config = RunConfig(pass_run_config_to_sub_agents=True)
assert get_current_run_config() is None
await Runner.run(
starting_agent=parent_agent,
input="Use the sub agent tool",
run_config=run_config,
)
assert get_current_run_config() is None
assert len(inherited_configs) == 1
assert inherited_configs[0] is run_config
assert inherited_configs[0].pass_run_config_to_sub_agents is True
@pytest.mark.asyncio
async def test_run_config_inheritance_disabled():
"""Test that run_config is not inherited when pass_run_config_to_sub_agents=False"""
inherited_configs = []
@function_tool
async def config_capture_tool() -> str:
"""Tool that captures the current run config"""
current_config = get_current_run_config()
inherited_configs.append(current_config)
return "config_captured"
sub_agent = Agent(
name="SubAgent",
instructions="You are a sub agent",
model=FakeModel(),
tools=[config_capture_tool],
)
sub_fake_model = cast(FakeModel, sub_agent.model)
sub_fake_model.add_multiple_turn_outputs(
[
[get_function_tool_call("config_capture_tool", "{}")],
[get_text_message("sub_agent_response")],
]
)
parent_agent = Agent(
name="ParentAgent",
instructions="You are a parent agent",
model=FakeModel(),
tools=[
sub_agent.as_tool(
tool_name="sub_agent_tool", tool_description="Call the sub agent"
)
],
)
parent_fake_model = cast(FakeModel, parent_agent.model)
parent_fake_model.add_multiple_turn_outputs(
[
[get_function_tool_call("sub_agent_tool", '{"input": "test"}')],
[get_text_message("parent_response")],
]
)
run_config = RunConfig()
await Runner.run(
starting_agent=parent_agent,
input="Use the sub agent tool",
run_config=run_config,
)
assert get_current_run_config() is None
assert len(inherited_configs) == 1
assert inherited_configs[0] is None
@pytest.mark.asyncio
async def test_context_variable_cleanup_on_error():
"""Test that context variable is cleaned up even when errors occur"""
failing_model = FakeModel()
failing_model.set_next_output(RuntimeError("Intentional test failure"))
failing_agent = Agent(
name="FailingAgent",
instructions="Fail",
model=failing_model,
)
run_config = RunConfig(pass_run_config_to_sub_agents=True)
assert get_current_run_config() is None
with pytest.raises(RuntimeError, match="Intentional test failure"):
await Runner.run(
starting_agent=failing_agent,
input="This should fail",
run_config=run_config,
)
assert get_current_run_config() is None
@pytest.mark.asyncio
async def test_scope_methods_directly():
"""Test the Scope class methods directly for RunConfig management"""
run_config = RunConfig(pass_run_config_to_sub_agents=True)
assert get_current_run_config() is None
token = set_current_run_config(run_config)
assert get_current_run_config() is run_config
reset_current_run_config(token)
assert get_current_run_config() is None
token = set_current_run_config(None)
assert get_current_run_config() is None
reset_current_run_config(token)