Please read this first
- Have you read the docs? Yes.
- Have you searched for related issues? Yes.
Describe the bug
EncryptedSession.get_items(limit=N) applies limit to the underlying encrypted envelopes before it decrypts them. Invalid, expired, or otherwise undecryptable envelopes are then dropped, so a latest invalid envelope can hide earlier valid context even when enough valid items exist in the session history.
I searched existing issues and PRs for EncryptedSession get_items limit, EncryptedSession invalid token limit, and encrypted session expired limit, and did not find a direct match.
This is specific to EncryptedSession because it wraps another session backend and filters encrypted envelopes after reading them. The adjacent negative limit behavior is a separate session-limit consistency issue and is not part of this report.
Debug information
- Agents SDK version:
v0.16.0 / current main at eed9100
- Python version: Python 3.12.1
- Backend:
EncryptedSession wrapping SQLiteSession
Repro steps
Run this script against an affected version:
import asyncio
from cryptography.fernet import Fernet
from agents import SQLiteSession
from agents.extensions.memory.encrypt_session import EncryptedSession
async def main() -> None:
session_id = "encrypted-limit-repro"
underlying_session = SQLiteSession(session_id)
encrypted_session = EncryptedSession(
session_id=session_id,
underlying_session=underlying_session,
encryption_key=Fernet.generate_key().decode("utf-8"),
)
try:
await encrypted_session.add_items([{"role": "user", "content": "older valid"}])
await underlying_session.add_items(
[{"__enc__": 1, "v": 1, "kid": "hkdf-v1", "payload": "not-a-valid-token"}]
)
all_items = await encrypted_session.get_items()
limited_items = await encrypted_session.get_items(limit=1)
print("all:", [item.get("content") for item in all_items])
print("limit=1:", [item.get("content") for item in limited_items])
assert [item.get("content") for item in all_items] == ["older valid"]
assert [item.get("content") for item in limited_items] == ["older valid"]
finally:
underlying_session.close()
asyncio.run(main())
On affected versions, the output is:
all: ['older valid']
limit=1: []
The first assertion passes, but the second assertion fails because limited_items is empty.
Expected behavior
For positive explicit limits, EncryptedSession.get_items(limit=N) should return the latest N valid decrypted items when that many valid items exist in the underlying history. Invalid, expired, or otherwise undecryptable envelopes should not count against the requested limit.
Please read this first
Describe the bug
EncryptedSession.get_items(limit=N)applieslimitto the underlying encrypted envelopes before it decrypts them. Invalid, expired, or otherwise undecryptable envelopes are then dropped, so a latest invalid envelope can hide earlier valid context even when enough valid items exist in the session history.I searched existing issues and PRs for
EncryptedSession get_items limit,EncryptedSession invalid token limit, andencrypted session expired limit, and did not find a direct match.This is specific to
EncryptedSessionbecause it wraps another session backend and filters encrypted envelopes after reading them. The adjacent negativelimitbehavior is a separate session-limit consistency issue and is not part of this report.Debug information
v0.16.0/ currentmainateed9100EncryptedSessionwrappingSQLiteSessionRepro steps
Run this script against an affected version:
On affected versions, the output is:
The first assertion passes, but the second assertion fails because
limited_itemsis empty.Expected behavior
For positive explicit limits,
EncryptedSession.get_items(limit=N)should return the latestNvalid decrypted items when that many valid items exist in the underlying history. Invalid, expired, or otherwise undecryptable envelopes should not count against the requested limit.