Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions src/agents/memory/session_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,10 @@ def resolve(self, override: SessionSettings | dict[str, Any] | None) -> SessionS
override = _coerce_session_settings(override, settings_type=type(self))

changes = {
field.name: getattr(override, field.name)
field.name: getattr(override, field.name, None)
for field in fields(self)
if (override_fields is None or field.name in override_fields)
and getattr(override, field.name) is not None
and getattr(override, field.name, None) is not None
}

return replace(self, **changes)
Expand All @@ -76,6 +76,13 @@ def _coerce_session_settings(
*,
settings_type: type[SessionSettings],
) -> SessionSettings:
if isinstance(value, SessionSettings):
if type(value) is SessionSettings or isinstance(value, settings_type):
return value
raise TypeError(
f"Session settings override must be SessionSettings or an instance of "
f"{settings_type.__name__}; got {type(value).__name__}"
)
return coerce_dataclass_config(value, settings_type, parameter_name="session")


Expand Down
38 changes: 38 additions & 0 deletions tests/memory/test_session.py
Original file line number Diff line number Diff line change
Expand Up @@ -962,6 +962,44 @@ async def test_session_settings_resolve():
assert final_none.limit == 100


def test_session_settings_resolve_accepts_base_override_for_subclass() -> None:
"""A subclass can resolve settings produced by the base RunConfig type."""
from pydantic.dataclasses import dataclass

@dataclass
class TenantSessionSettings(SessionSettings):
tenant: str = "default"

base = TenantSessionSettings(limit=100, tenant="acme")
run_config = RunConfig(session_settings={"limit": 50})

final = base.resolve(run_config.session_settings)

assert isinstance(final, TenantSessionSettings)
assert final.limit == 50
assert final.tenant == "acme"
assert base.limit == 100


def test_session_settings_resolve_rejects_incompatible_subclass_override() -> None:
"""A subclass must not silently discard fields from a sibling subclass."""
from pydantic.dataclasses import dataclass

@dataclass
class TenantSessionSettings(SessionSettings):
tenant: str = "default"

@dataclass
class RegionSessionSettings(SessionSettings):
region: str = "default"

base = TenantSessionSettings(limit=100, tenant="acme")
override = RegionSessionSettings(limit=50, region="us-east-1")

with pytest.raises(TypeError, match="TenantSessionSettings"):
base.resolve(override)


@pytest.mark.asyncio
async def test_runner_with_session_settings_override():
"""Test that RunConfig can override session's default settings."""
Expand Down