Add offset parameter to get_items() for pagination#2811
Add offset parameter to get_items() for pagination#2811ecanlar wants to merge 1 commit intoopenai:mainfrom
Conversation
The existing limit parameter only supports truncation (latest N items). This adds an offset parameter across all session backends to enable proper pagination over conversation history. All backends updated: SQLiteSession, AsyncSQLiteSession, SQLAlchemySession, RedisSession, DaprSession, AdvancedSQLiteSession, EncryptedSession, OpenAIResponsesCompactionSession, and OpenAIConversationsSession. Backward compatible — offset defaults to 0. Closes openai#2810 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 4b76578b40
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| self, limit: int | None = None, offset: int = 0 | ||
| ) -> list[TResponseInputItem]: |
There was a problem hiding this comment.
Honor offset in OpenAIConversationsSession.get_items
get_items now advertises an offset argument, but this method never applies it in either query path, so get_items(offset=...) returns the same page as offset=0. This breaks pagination specifically for the OpenAI-backed session and can cause duplicate pages when callers iterate through history using offsets.
Useful? React with 👍 / 👎.
| end_idx = -(offset + 1) | ||
| raw_messages = await self._redis.lrange(self._messages_key, 0, end_idx) # type: ignore[misc] |
There was a problem hiding this comment.
Clamp Redis LRANGE indices for large offsets
The Redis pagination math passes raw negative indices to LRANGE; when offset exceeds the list length, Redis normalizes out-of-range indices instead of erroring, so ranges like 0, -(offset+1) can still return the oldest element(s) instead of an empty list. That makes get_items(offset>=len(history)) return stale data and breaks page boundaries.
Useful? React with 👍 / 👎.
|
Thanks for your response! In my case, I’m developing an assistant (chatbot) that manages a growing history of user sessions in production. As the number of sessions increases, retrieving all of them at once is not scalable and negatively impacts both performance and user experience. Pagination becomes necessary to:
Using an offset (or cursor-based pagination) is a standard approach in these scenarios and would make the Sessions API much more practical for real-world applications. I believe this is not an edge case but a common requirement for any production system that stores conversational history over time. Thanks for considering it! |
|
I mean, just having the offset parameter on the session store side is not enough, because the agent runner does not pass that parameter to your session store. Also, it is not obvious what offset value would be optimal. So, if your app needs to limit the size or number of items, I recommend implementing that logic within the get_items method, such as setting an upper limit on the number of items to return or compacting items at the right time. |
Summary
offsetparameter toget_items()across all session backends, enabling real pagination over conversation historylimitonly truncates (returns the latest N items) — withoffset, users can now paginate through the full historyoffsetdefaults to0Usage
Backends updated
src/agents/memory/session.pysrc/agents/memory/session.pysrc/agents/memory/sqlite_session.pysrc/agents/extensions/memory/async_sqlite_session.pysrc/agents/extensions/memory/sqlalchemy_session.pysrc/agents/extensions/memory/redis_session.pysrc/agents/extensions/memory/dapr_session.pysrc/agents/extensions/memory/advanced_sqlite_session.pysrc/agents/extensions/memory/encrypt_session.pysrc/agents/memory/openai_responses_compaction_session.pysrc/agents/memory/openai_conversations_session.pyTest plan
test_sqlite_session_get_items_with_offset— verifies limit+offset pagination, offset-only, and edge casesCloses #2810