Migrating from 0.9.x to 0.10
The 0.10 release is additive. Every change is opt-in. Three things to be aware of when you upgrade.
1. Postgres memory_blocks schema migrated
The empty-string anonymous bucket is replaced with a reserved sentinel
(__jeeves_anon_user__). The framework’s init_schema() runs the
rewriting UPDATE automatically; if you bypass it and manage
migrations yourself, run:
UPDATE memory_blocks SET user_id = '__jeeves_anon_user__'
WHERE user_id = '';
ALTER TABLE memory_blocks ALTER COLUMN user_id
SET DEFAULT '__jeeves_anon_user__';Attempting to use the sentinel as a real user_id now raises
ValueError. Defense against impersonating the anonymous bucket.
2. LoomDeprecationWarning for legacy protocol shapes
Custom Memory / Permissions / HookHost / AuditLog impls
without a user_id= kwarg emit LoomDeprecationWarning. The shim
layer still calls the legacy shape, so nothing breaks today. The
deprecation will turn into a hard removal in 1.0. To silence:
class MyMemory:
async def remember(
self, episode: Episode, *, user_id: str | None = None,
) -> str:
...3. Bounded in-process state by default
StandardBudget._by_user and InMemoryMemory._blocks are now bounded
by default. A workflow that legitimately pins >100k active users in
process needs to opt out or raise the cap:
StandardBudget(BudgetConfig(), max_users=None, user_idle_ttl_seconds=None)
InMemoryMemory(max_users=None, user_idle_ttl_seconds=None)That’s the whole upgrade. No public API got renamed; no constructor arg got removed.