Summary
Add a advanced_alchemy.extensions.adk package providing a declarative, dual sync/async integration with Google ADK (≥ 2.0.0b1) — covering session, memory, and artifact services, with framework plugins for the existing AA extensions (Litestar, FastAPI, Flask, Sanic, Starlette).
Motivation
Google ADK ships only InMemorySessionService and DatabaseSessionService (raw SQL, single-backend) for sessions, and InMemoryArtifactService / GcsArtifactService for artifacts. Existing third-party SQL implementations (e.g. sqlspec) take a raw-SQL approach across many adapters, which sacrifices ORM ergonomics and type safety.
Advanced Alchemy already has every primitive needed:
JsonB ≈ ADK's DynamicJSON (PostgreSQL-native, Oracle-optimized fallback)
DateTimeUTC ≈ ADK's PreciseTimestamp (with a small fsp extension for MySQL parity)
StoredObject / FileObject + the existing session-tracker for transactional artifact storage across S3 / GCS / Azure / local / fsspec / obstore
- Repository + Service patterns for sync/async parity via unasyncd
- Mature framework integrations to plug services into apps
A first-party AA integration delivers idiomatic SQLAlchemy 2.0 models, transactional artifact storage that works across every supported file backend, and the same async/sync ergonomics AA already provides.
Scope
The integration ships in chapters so each piece can land and stabilize independently:
- Foundation —
extensions/adk/ package skeleton, [adk] optional dep with Python 3.10+ guard, schema-version routing module (mirrors ADK's _SchemaClasses pattern so future schema versions are drop-in), and DateTimeUTC(fsp=…) extension for MySQL DATETIME(6) parity.
- Models — the 5 v1 ADK tables (
sessions, events, app_states, user_states, adk_internal_metadata) declared as Mapped 2.0 models with composite primary keys, FK cascades, and indexes matching ADK exactly.
- Session Service — repositories +
ADKSessionService(BaseSessionService) with stale-session detection and temp-state filtering.
- Alembic template — pre-built migration scaffold (not autogenerate) so users can adopt the schema with one command.
- Litestar plugin — exemplar framework integration; provides DI for the session/artifact services.
- Artifact Service (headline feature) —
ADKArtifactService over StoredObject + FileObjectSessionTracker. Backend-agnostic, transactionally consistent. Path layout {app}/{user}/{session}/{filename}/v{N} matches GcsArtifactService for migration parity.
- Memory Service — SQL backend, with
pgvector opt-in via [adk-vector] extra.
- Framework breadth — FastAPI, Flask, Sanic, Starlette plugins following the Litestar plugin shape.
- Test matrix — integration tests across the supported DB backends + perf benchmarks vs upstream ADK services.
- Docs & release — Sphinx docs, ADK compatibility matrix, examples.
Key design decisions
- Target
google-adk>=2.0.0b1. v2.0.0b1 ships zero schema changes from v1.31, and v2.0 GA is imminent.
- Declarative ORM, not raw SQL. Lean into AA's existing strengths —
Mapped[...] models, SQLAlchemyAsyncRepository, services. Lower boilerplate, automatic dialect handling.
- Pluggable schema-version routing from MVP. Future schema versions are drop-in modules with no API breakage.
- Inherit
BaseSessionService, do not duplicate. Lazy-import google.adk inside the service module so any future abstract-method additions fail loudly at import time, not silently at user runtime.
- Composite PKs declared explicitly. AA's primary-key mixins assume single-column PKs; ADK's
sessions has 3 PK columns and events has 4.
String(128) for sessions.id, not GUID. Custom session IDs (ADK ≥ 1.28) are user-supplied strings up to 128 chars.
- Decoupled runtime/migration flags.
enable_sessions vs include_sessions_migration as independent booleans — users can mix AA runtime with external Alembic, AA migrations with AA runtime, or manual table management.
- Auth check raises
PermissionError. sqlspec returns None on app/user mismatch in get_session; AA raises a typed exception for better diagnostics and to match AA's exception philosophy.
- Async-first; sync via unasyncd. The ADK
BaseSessionService contract is async; the sync mirror is generated for AA's sync stack but isn't registered as a BaseSessionService.
- Python 3.10+ only for the
[adk] extra. ADK requires it. Core AA stays 3.9+. The extensions/adk/__init__.py runtime guard raises a clear error on 3.9.
- Owner-id factory is a typed
Mapped[...], not free-form DDL. Clean, type-safe, FK-aware multi-tenancy.
- First framework integration: Litestar. Mirrors existing AA extension maturity; FastAPI / Flask / Sanic / Starlette follow the same shape in chapter 8.
Out of scope
- Workflow / checkpoint persistence. ADK explicitly designs workflow state as in-memory; HITL resume reads from the existing
events table by invocation_id. A separate checkpoint table would be wasted work and could conflict with future ADK additions.
Differentiators vs. existing options
|
ADK upstream |
sqlspec |
AA (this proposal) |
| Session backend |
In-memory or one raw-SQL impl |
Raw SQL across many adapters |
Declarative ORM, all SQLAlchemy dialects |
| Artifact backend |
In-memory or GCS-only |
n/a |
Any StoredObject backend (S3/GCS/Azure/local/fsspec/obstore), transactional |
| Sync + async |
Async only |
Both |
Both, single source of truth via unasyncd |
| Framework plugins |
None |
None |
Litestar / FastAPI / Flask / Sanic / Starlette |
| Schema versioning |
None |
None |
Pluggable routing from MVP |
Tracking
I'll open follow-up issues for each chapter as it becomes ready to implement, blocking on this one.
Summary
Add a
advanced_alchemy.extensions.adkpackage providing a declarative, dual sync/async integration with Google ADK (≥ 2.0.0b1) — covering session, memory, and artifact services, with framework plugins for the existing AA extensions (Litestar, FastAPI, Flask, Sanic, Starlette).Motivation
Google ADK ships only
InMemorySessionServiceandDatabaseSessionService(raw SQL, single-backend) for sessions, andInMemoryArtifactService/GcsArtifactServicefor artifacts. Existing third-party SQL implementations (e.g. sqlspec) take a raw-SQL approach across many adapters, which sacrifices ORM ergonomics and type safety.Advanced Alchemy already has every primitive needed:
JsonB≈ ADK'sDynamicJSON(PostgreSQL-native, Oracle-optimized fallback)DateTimeUTC≈ ADK'sPreciseTimestamp(with a smallfspextension for MySQL parity)StoredObject/FileObject+ the existing session-tracker for transactional artifact storage across S3 / GCS / Azure / local / fsspec / obstoreA first-party AA integration delivers idiomatic SQLAlchemy 2.0 models, transactional artifact storage that works across every supported file backend, and the same async/sync ergonomics AA already provides.
Scope
The integration ships in chapters so each piece can land and stabilize independently:
extensions/adk/package skeleton,[adk]optional dep with Python 3.10+ guard, schema-version routing module (mirrors ADK's_SchemaClassespattern so future schema versions are drop-in), andDateTimeUTC(fsp=…)extension for MySQLDATETIME(6)parity.sessions,events,app_states,user_states,adk_internal_metadata) declared as Mapped 2.0 models with composite primary keys, FK cascades, and indexes matching ADK exactly.ADKSessionService(BaseSessionService)with stale-session detection and temp-state filtering.ADKArtifactServiceoverStoredObject+FileObjectSessionTracker. Backend-agnostic, transactionally consistent. Path layout{app}/{user}/{session}/{filename}/v{N}matchesGcsArtifactServicefor migration parity.pgvectoropt-in via[adk-vector]extra.Key design decisions
google-adk>=2.0.0b1. v2.0.0b1 ships zero schema changes from v1.31, and v2.0 GA is imminent.Mapped[...]models,SQLAlchemyAsyncRepository, services. Lower boilerplate, automatic dialect handling.BaseSessionService, do not duplicate. Lazy-importgoogle.adkinside the service module so any future abstract-method additions fail loudly at import time, not silently at user runtime.sessionshas 3 PK columns andeventshas 4.String(128)forsessions.id, notGUID. Custom session IDs (ADK ≥ 1.28) are user-supplied strings up to 128 chars.enable_sessionsvsinclude_sessions_migrationas independent booleans — users can mix AA runtime with external Alembic, AA migrations with AA runtime, or manual table management.PermissionError. sqlspec returnsNoneon app/user mismatch inget_session; AA raises a typed exception for better diagnostics and to match AA's exception philosophy.BaseSessionServicecontract is async; the sync mirror is generated for AA's sync stack but isn't registered as aBaseSessionService.[adk]extra. ADK requires it. Core AA stays 3.9+. Theextensions/adk/__init__.pyruntime guard raises a clear error on 3.9.Mapped[...], not free-form DDL. Clean, type-safe, FK-aware multi-tenancy.Out of scope
eventstable byinvocation_id. A separate checkpoint table would be wasted work and could conflict with future ADK additions.Differentiators vs. existing options
StoredObjectbackend (S3/GCS/Azure/local/fsspec/obstore), transactionalTracking
I'll open follow-up issues for each chapter as it becomes ready to implement, blocking on this one.