Skip to content

Commit dfa0f37

Browse files
authored
Fix type safety in OpenAIConversationsSession.get_items()
**What This PR Fixes** - Resolves type mismatch where `get_items()` returned `list[dict]` but was annotated as `list[TResponseInputItem]` - Removes unnecessary `# type: ignore` comments that masked real type safety issues - Adds explicit non-None assertion for client initialization in `start_openai_conversations_session` **Changes Made** - Added `from typing import cast` import to support explicit type casting - Typed the `all_items` accumulator as `list[TResponseInputItem]` to match method signature - Cast `item.model_dump(exclude_unset=True)` results to `TResponseInputItem` in both iteration branches - Removed `# type: ignore` on `get_items()` return statement since type now matches annotation - Removed `# type: ignore [typeddict-item]` in `pop_item()` since items are now correctly typed - Added explicit `assert _maybe_openai_client is not None` in `start_openai_conversations_session` to document invariant **Why This Matters** - Enables proper static type checking with mypy and other type checkers - Prevents potential runtime errors when downstream code expects proper `TResponseInputItem` objects - Makes type contracts explicit and verifiable - Improves code maintainability without changing runtime behavior **Backward Compatibility** - No changes to public APIs or method signatures - No changes to pagination, ordering, or session management behavior - All existing functionality preserved **Testing** - Existing test suite validates unchanged behavior - Type checking now passes without suppressions
1 parent cfddc7c commit dfa0f37

File tree

1 file changed

+10
-7
lines changed

1 file changed

+10
-7
lines changed

src/agents/memory/openai_conversations_session.py

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
from __future__ import annotations
22

3+
from typing import cast
4+
35
from openai import AsyncOpenAI
46

57
from agents.models._openai_shared import get_default_openai_client
@@ -12,8 +14,9 @@ async def start_openai_conversations_session(openai_client: AsyncOpenAI | None =
1214
_maybe_openai_client = openai_client
1315
if openai_client is None:
1416
_maybe_openai_client = get_default_openai_client() or AsyncOpenAI()
15-
# this never be None here
16-
_openai_client: AsyncOpenAI = _maybe_openai_client # type: ignore [assignment]
17+
# ensure non-None for type checkers and readers
18+
assert _maybe_openai_client is not None
19+
_openai_client: AsyncOpenAI = _maybe_openai_client
1720

1821
response = await _openai_client.conversations.create(items=[])
1922
return response.id
@@ -43,27 +46,27 @@ async def _clear_session_id(self) -> None:
4346

4447
async def get_items(self, limit: int | None = None) -> list[TResponseInputItem]:
4548
session_id = await self._get_session_id()
46-
all_items = []
49+
all_items: list[TResponseInputItem] = []
4750
if limit is None:
4851
async for item in self._openai_client.conversations.items.list(
4952
conversation_id=session_id,
5053
order="asc",
5154
):
5255
# calling model_dump() to make this serializable
53-
all_items.append(item.model_dump(exclude_unset=True))
56+
all_items.append(cast(TResponseInputItem, item.model_dump(exclude_unset=True)))
5457
else:
5558
async for item in self._openai_client.conversations.items.list(
5659
conversation_id=session_id,
5760
limit=limit,
5861
order="desc",
5962
):
6063
# calling model_dump() to make this serializable
61-
all_items.append(item.model_dump(exclude_unset=True))
64+
all_items.append(cast(TResponseInputItem, item.model_dump(exclude_unset=True)))
6265
if limit is not None and len(all_items) >= limit:
6366
break
6467
all_items.reverse()
6568

66-
return all_items # type: ignore
69+
return all_items
6770

6871
async def add_items(self, items: list[TResponseInputItem]) -> None:
6972
session_id = await self._get_session_id()
@@ -77,7 +80,7 @@ async def pop_item(self) -> TResponseInputItem | None:
7780
items = await self.get_items(limit=1)
7881
if not items:
7982
return None
80-
item_id: str = str(items[0]["id"]) # type: ignore [typeddict-item]
83+
item_id: str = str(items[0]["id"])
8184
await self._openai_client.conversations.items.delete(
8285
conversation_id=session_id, item_id=item_id
8386
)

0 commit comments

Comments
 (0)