google-adk-extras 0.1.1__tar.gz → 0.2.5__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (102) hide show
  1. {google_adk_extras-0.1.1 → google_adk_extras-0.2.5}/MANIFEST.in +3 -1
  2. google_adk_extras-0.2.5/PKG-INFO +302 -0
  3. google_adk_extras-0.2.5/README.md +259 -0
  4. google_adk_extras-0.2.5/docs/agent-loading.md +28 -0
  5. google_adk_extras-0.2.5/docs/credentials.md +31 -0
  6. google_adk_extras-0.2.5/docs/examples.md +11 -0
  7. google_adk_extras-0.2.5/docs/fastapi.md +24 -0
  8. google_adk_extras-0.2.5/docs/getting-started.md +49 -0
  9. google_adk_extras-0.2.5/docs/index.md +19 -0
  10. google_adk_extras-0.2.5/docs/quickstarts.md +61 -0
  11. google_adk_extras-0.2.5/docs/services.md +37 -0
  12. google_adk_extras-0.2.5/docs/troubleshooting.md +29 -0
  13. google_adk_extras-0.2.5/docs/uris.md +31 -0
  14. google_adk_extras-0.2.5/examples/README.md +15 -0
  15. google_adk_extras-0.2.5/examples/consume_remote_a2a.py +40 -0
  16. google_adk_extras-0.2.5/examples/credentials/google_oauth2.py +27 -0
  17. google_adk_extras-0.2.5/examples/custom_loader.py +29 -0
  18. google_adk_extras-0.2.5/examples/fastapi_app.py +28 -0
  19. google_adk_extras-0.2.5/examples/programmatic_a2a_expose.py +37 -0
  20. google_adk_extras-0.2.5/examples/runner_basic.py +27 -0
  21. google_adk_extras-0.2.5/examples/services/artifacts_local.py +15 -0
  22. google_adk_extras-0.2.5/examples/services/memory_yaml.py +14 -0
  23. google_adk_extras-0.2.5/examples/services/sessions_sql.py +15 -0
  24. google_adk_extras-0.2.5/mkdocs.yml +61 -0
  25. google_adk_extras-0.2.5/pyproject.toml +43 -0
  26. {google_adk_extras-0.1.1 → google_adk_extras-0.2.5}/setup.py +40 -30
  27. google_adk_extras-0.2.5/src/google_adk_extras/__init__.py +31 -0
  28. google_adk_extras-0.2.5/src/google_adk_extras/adk_builder.py +1030 -0
  29. google_adk_extras-0.2.5/src/google_adk_extras/artifacts/__init__.py +28 -0
  30. {google_adk_extras-0.1.1 → google_adk_extras-0.2.5}/src/google_adk_extras/artifacts/base_custom_artifact_service.py +148 -11
  31. {google_adk_extras-0.1.1 → google_adk_extras-0.2.5}/src/google_adk_extras/artifacts/local_folder_artifact_service.py +133 -13
  32. {google_adk_extras-0.1.1 → google_adk_extras-0.2.5}/src/google_adk_extras/artifacts/s3_artifact_service.py +135 -19
  33. {google_adk_extras-0.1.1 → google_adk_extras-0.2.5}/src/google_adk_extras/artifacts/sql_artifact_service.py +109 -10
  34. google_adk_extras-0.2.5/src/google_adk_extras/credentials/__init__.py +34 -0
  35. google_adk_extras-0.2.5/src/google_adk_extras/credentials/base_custom_credential_service.py +113 -0
  36. google_adk_extras-0.2.5/src/google_adk_extras/credentials/github_oauth2_credential_service.py +213 -0
  37. google_adk_extras-0.2.5/src/google_adk_extras/credentials/google_oauth2_credential_service.py +216 -0
  38. google_adk_extras-0.2.5/src/google_adk_extras/credentials/http_basic_auth_credential_service.py +388 -0
  39. google_adk_extras-0.2.5/src/google_adk_extras/credentials/jwt_credential_service.py +345 -0
  40. google_adk_extras-0.2.5/src/google_adk_extras/credentials/microsoft_oauth2_credential_service.py +250 -0
  41. google_adk_extras-0.2.5/src/google_adk_extras/credentials/x_oauth2_credential_service.py +240 -0
  42. google_adk_extras-0.2.5/src/google_adk_extras/custom_agent_loader.py +170 -0
  43. google_adk_extras-0.2.5/src/google_adk_extras/enhanced_adk_web_server.py +137 -0
  44. google_adk_extras-0.2.5/src/google_adk_extras/enhanced_fastapi.py +507 -0
  45. google_adk_extras-0.2.5/src/google_adk_extras/enhanced_runner.py +38 -0
  46. google_adk_extras-0.2.5/src/google_adk_extras/memory/__init__.py +32 -0
  47. {google_adk_extras-0.1.1 → google_adk_extras-0.2.5}/src/google_adk_extras/memory/base_custom_memory_service.py +37 -5
  48. {google_adk_extras-0.1.1 → google_adk_extras-0.2.5}/src/google_adk_extras/memory/sql_memory_service.py +105 -19
  49. {google_adk_extras-0.1.1 → google_adk_extras-0.2.5}/src/google_adk_extras/memory/yaml_file_memory_service.py +115 -22
  50. google_adk_extras-0.2.5/src/google_adk_extras/sessions/__init__.py +29 -0
  51. {google_adk_extras-0.1.1 → google_adk_extras-0.2.5}/src/google_adk_extras/sessions/base_custom_session_service.py +133 -11
  52. {google_adk_extras-0.1.1 → google_adk_extras-0.2.5}/src/google_adk_extras/sessions/sql_session_service.py +127 -16
  53. {google_adk_extras-0.1.1 → google_adk_extras-0.2.5}/src/google_adk_extras/sessions/yaml_file_session_service.py +122 -14
  54. google_adk_extras-0.2.5/src/google_adk_extras.egg-info/PKG-INFO +302 -0
  55. {google_adk_extras-0.1.1 → google_adk_extras-0.2.5}/src/google_adk_extras.egg-info/SOURCES.txt +34 -26
  56. google_adk_extras-0.2.5/src/google_adk_extras.egg-info/requires.txt +38 -0
  57. google_adk_extras-0.2.5/tests/test_a2a_helpers.py +199 -0
  58. google_adk_extras-0.1.1/PKG-INFO +0 -175
  59. google_adk_extras-0.1.1/README.md +0 -145
  60. google_adk_extras-0.1.1/examples/README.md +0 -69
  61. google_adk_extras-0.1.1/examples/artifact/README.md +0 -41
  62. google_adk_extras-0.1.1/examples/artifact/example.py +0 -198
  63. google_adk_extras-0.1.1/examples/artifact/local_folder_artifact_example.py +0 -97
  64. google_adk_extras-0.1.1/examples/artifact/mongodb_artifact_example.py +0 -80
  65. google_adk_extras-0.1.1/examples/artifact/s3_artifact_example.py +0 -46
  66. google_adk_extras-0.1.1/examples/artifact/sql_artifact_example.py +0 -112
  67. google_adk_extras-0.1.1/examples/artifact_service_example.py +0 -196
  68. google_adk_extras-0.1.1/examples/google_adk_integration.py +0 -91
  69. google_adk_extras-0.1.1/examples/memory/README.md +0 -41
  70. google_adk_extras-0.1.1/examples/memory/example.py +0 -243
  71. google_adk_extras-0.1.1/examples/memory/mongodb_memory_example.py +0 -96
  72. google_adk_extras-0.1.1/examples/memory/redis_memory_example.py +0 -96
  73. google_adk_extras-0.1.1/examples/memory/sql_memory_example.py +0 -105
  74. google_adk_extras-0.1.1/examples/memory/yaml_memory_example.py +0 -93
  75. google_adk_extras-0.1.1/examples/session/README.md +0 -40
  76. google_adk_extras-0.1.1/examples/session/example.py +0 -229
  77. google_adk_extras-0.1.1/examples/session/mongodb_session_example.py +0 -77
  78. google_adk_extras-0.1.1/examples/session/redis_session_example.py +0 -70
  79. google_adk_extras-0.1.1/examples/session/sql_session_example.py +0 -87
  80. google_adk_extras-0.1.1/examples/session/yaml_session_example.py +0 -76
  81. google_adk_extras-0.1.1/examples/session_service_example.py +0 -118
  82. google_adk_extras-0.1.1/examples/test_session_service.py +0 -75
  83. google_adk_extras-0.1.1/pyproject.toml +0 -29
  84. google_adk_extras-0.1.1/src/__init__.py +0 -0
  85. google_adk_extras-0.1.1/src/google_adk_extras/__init__.py +0 -1
  86. google_adk_extras-0.1.1/src/google_adk_extras/artifacts/__init__.py +0 -15
  87. google_adk_extras-0.1.1/src/google_adk_extras/memory/__init__.py +0 -15
  88. google_adk_extras-0.1.1/src/google_adk_extras/py.typed +0 -0
  89. google_adk_extras-0.1.1/src/google_adk_extras/sessions/__init__.py +0 -13
  90. google_adk_extras-0.1.1/src/google_adk_extras.egg-info/PKG-INFO +0 -175
  91. google_adk_extras-0.1.1/src/google_adk_extras.egg-info/requires.txt +0 -15
  92. google_adk_extras-0.1.1/src/main.py +0 -0
  93. google_adk_extras-0.1.1/tests/test_basic.py +0 -7
  94. {google_adk_extras-0.1.1 → google_adk_extras-0.2.5}/LICENSE +0 -0
  95. {google_adk_extras-0.1.1 → google_adk_extras-0.2.5}/setup.cfg +0 -0
  96. {google_adk_extras-0.1.1 → google_adk_extras-0.2.5}/src/google_adk_extras/artifacts/mongo_artifact_service.py +0 -0
  97. {google_adk_extras-0.1.1 → google_adk_extras-0.2.5}/src/google_adk_extras/memory/mongo_memory_service.py +0 -0
  98. {google_adk_extras-0.1.1 → google_adk_extras-0.2.5}/src/google_adk_extras/memory/redis_memory_service.py +0 -0
  99. {google_adk_extras-0.1.1 → google_adk_extras-0.2.5}/src/google_adk_extras/sessions/mongo_session_service.py +0 -0
  100. {google_adk_extras-0.1.1 → google_adk_extras-0.2.5}/src/google_adk_extras/sessions/redis_session_service.py +0 -0
  101. {google_adk_extras-0.1.1 → google_adk_extras-0.2.5}/src/google_adk_extras.egg-info/dependency_links.txt +0 -0
  102. {google_adk_extras-0.1.1 → google_adk_extras-0.2.5}/src/google_adk_extras.egg-info/top_level.txt +0 -0
@@ -4,7 +4,9 @@ include pyproject.toml
4
4
  include setup.py
5
5
  recursive-include src *.py
6
6
  recursive-include examples *.py *.md
7
+ recursive-include docs *.md
8
+ include mkdocs.yml
7
9
  global-exclude __pycache__
8
10
  global-exclude *.pyc
9
11
  global-exclude *.pyo
10
- global-exclude *~
12
+ global-exclude *~
@@ -0,0 +1,302 @@
1
+ Metadata-Version: 2.4
2
+ Name: google-adk-extras
3
+ Version: 0.2.5
4
+ Summary: Production-ready services, credentials, and FastAPI wiring for Google ADK
5
+ Home-page: https://github.com/DeadMeme5441/google-adk-extras
6
+ Author: DeadMeme5441
7
+ Author-email: DeadMeme5441 <deadunderscorememe@gmail.com>
8
+ Requires-Python: >=3.10,<3.13
9
+ Description-Content-Type: text/markdown
10
+ License-File: LICENSE
11
+ Requires-Dist: google-adk
12
+ Requires-Dist: google-genai
13
+ Provides-Extra: sql
14
+ Requires-Dist: sqlalchemy; extra == "sql"
15
+ Provides-Extra: mongodb
16
+ Requires-Dist: pymongo; extra == "mongodb"
17
+ Provides-Extra: redis
18
+ Requires-Dist: redis; extra == "redis"
19
+ Provides-Extra: yaml
20
+ Requires-Dist: pyyaml; extra == "yaml"
21
+ Provides-Extra: s3
22
+ Requires-Dist: boto3; extra == "s3"
23
+ Provides-Extra: jwt
24
+ Requires-Dist: PyJWT; extra == "jwt"
25
+ Provides-Extra: web
26
+ Requires-Dist: fastapi; extra == "web"
27
+ Requires-Dist: watchdog; extra == "web"
28
+ Provides-Extra: dev
29
+ Requires-Dist: pytest; extra == "dev"
30
+ Requires-Dist: pytest-asyncio; extra == "dev"
31
+ Requires-Dist: build; extra == "dev"
32
+ Requires-Dist: twine; extra == "dev"
33
+ Provides-Extra: docs
34
+ Requires-Dist: mkdocs; extra == "docs"
35
+ Requires-Dist: mkdocs-material; extra == "docs"
36
+ Requires-Dist: mkdocs-llmstxt; extra == "docs"
37
+ Provides-Extra: all
38
+ Requires-Dist: google-adk-extras[docs,jwt,mongodb,redis,s3,sql,web,yaml]; extra == "all"
39
+ Dynamic: author
40
+ Dynamic: home-page
41
+ Dynamic: license-file
42
+ Dynamic: requires-python
43
+
44
+ # google-adk-extras
45
+
46
+ [![PyPI](https://img.shields.io/pypi/v/google-adk-extras?label=PyPI)](https://pypi.org/project/google-adk-extras/)
47
+ ![Python](https://img.shields.io/badge/python-3.12%2B-blue)
48
+ ![License](https://img.shields.io/badge/license-Apache%202.0-green)
49
+ [![Docs](https://img.shields.io/badge/docs-site-brightgreen)](https://deadmeme5441.github.io/google-adk-extras/)
50
+ [![Docs Build](https://github.com/DeadMeme5441/google-adk-extras/actions/workflows/docs.yml/badge.svg)](https://github.com/DeadMeme5441/google-adk-extras/actions/workflows/docs.yml)
51
+
52
+ Production-ready extensions for Google ADK (Agent Development Kit). This library adds durable service backends (sessions, artifacts, memory), practical credential services (OAuth2/JWT/Basic), and clean FastAPI wiring so you can run ADK agents with real storage and auth.
53
+
54
+ What this is not: a fork of ADK. It builds on ADK’s core runtime, agents, tools and callbacks, and drops in where ADK expects services and a web server.
55
+
56
+
57
+ ## Why it exists
58
+
59
+ ADK provides the core primitives (Runner, Session/State, MemoryService, ArtifactService, CredentialService, Agents/Tools, callbacks, Dev UI, and deployment paths). See the official ADK docs for concepts and APIs.
60
+
61
+ This package focuses on three gaps common in real apps:
62
+ - Durable storage backends beyond in‑memory defaults
63
+ - Usable credential flows (Google/GitHub/Microsoft/X OAuth2, JWT, Basic)
64
+ - FastAPI integration that accepts your credential service without hacks
65
+
66
+
67
+ ## Features
68
+
69
+ - Session services: SQL (SQLite/Postgres/MySQL), MongoDB, Redis, YAML files
70
+ - Artifact services: Local folder (versioned), S3‑compatible, SQL, MongoDB
71
+ - Memory services: SQL, MongoDB, Redis, YAML files (term search over text parts)
72
+ - Credential services: Google/GitHub/Microsoft/X (OAuth2), JWT, HTTP Basic
73
+ - Enhanced FastAPI wiring that respects a provided credential service
74
+ - Fluent builder (`AdkBuilder`) to assemble a FastAPI app or a Runner
75
+ - A2A helpers for exposing/consuming agents (see below)
76
+
77
+ Note on Runner: `EnhancedRunner` is a thin subclass of ADK’s `Runner` for compatibility with the enhanced web server; it does not change behavior.
78
+
79
+
80
+ ## Install
81
+
82
+ Requirements: Python 3.12+, google-adk.
83
+
84
+ Using uv:
85
+
86
+ ```bash
87
+ # create a venv (optional)
88
+ uv venv && source .venv/bin/activate
89
+ # install the package
90
+ uv pip install google-adk-extras
91
+ ```
92
+
93
+ If you plan to use specific backends, also install their clients (examples):
94
+ - SQL: `uv pip install sqlalchemy`
95
+ - MongoDB: `uv pip install pymongo`
96
+ - Redis: `uv pip install redis`
97
+ - S3: `uv pip install boto3`
98
+ - JWT: `uv pip install PyJWT`
99
+
100
+
101
+ ## Quickstart (FastAPI)
102
+
103
+ Use the fluent builder to wire services and credentials. Then run with uvicorn.
104
+
105
+ ```python
106
+ # app.py
107
+ from google_adk_extras import AdkBuilder
108
+ from google_adk_extras.credentials import GoogleOAuth2CredentialService
109
+
110
+ app = (
111
+ AdkBuilder()
112
+ .with_agents_dir("./agents") # ADK agents on disk
113
+ .with_session_service("sqlite:///./sessions.db") # or: mongodb://, redis://, yaml://
114
+ .with_artifact_service("local://./artifacts") # or: s3://bucket, mongodb://, sql://
115
+ .with_memory_service("yaml://./memory") # or: redis://, mongodb://, sql://
116
+ .with_credential_service(GoogleOAuth2CredentialService(
117
+ client_id="…apps.googleusercontent.com",
118
+ client_secret="…",
119
+ scopes=["openid", "email", "profile"],
120
+ ))
121
+ .with_web_ui(True) # serve ADK’s dev UI if assets available
122
+ .with_agent_reload(True)
123
+ .build_fastapi_app()
124
+ )
125
+ ```
126
+
127
+ Run:
128
+
129
+ ```bash
130
+ uvicorn app:app --reload
131
+ ```
132
+
133
+ If you don’t keep agents on disk, register them programmatically and use a custom loader (see below).
134
+
135
+
136
+ ## Quickstart (Runner)
137
+
138
+ Create a Runner wired with your chosen backends. Use agent name (filesystem loader) or pass an agent instance.
139
+
140
+ ```python
141
+ from google_adk_extras import AdkBuilder
142
+
143
+ runner = (
144
+ AdkBuilder()
145
+ .with_agents_dir("./agents")
146
+ .with_session_service("sqlite:///./sessions.db")
147
+ .with_memory_service("redis://localhost:6379")
148
+ .with_artifact_service("local://./artifacts")
149
+ .build_runner("my_agent")
150
+ )
151
+
152
+ result = await runner.run("Hello there!")
153
+ ```
154
+
155
+
156
+ ## How this extends ADK (in practice)
157
+
158
+ ADK defines abstract service interfaces and a runner/web stack. This package provides drop‑in implementations and a small web‑server shim:
159
+
160
+ - Sessions
161
+ - `SQLSessionService` — SQLAlchemy; JSON‑serialized state/events
162
+ - `MongoSessionService` — PyMongo; per‑session doc, indexed by app/user/id
163
+ - `RedisSessionService` — hashes per session + user set; JSON state/events
164
+ - `YamlFileSessionService` — `base/app/user/{session_id}.yaml`
165
+
166
+ ### A2A helpers (new)
167
+
168
+ Two light-weight helpers wrap ADK’s A2A capabilities:
169
+
170
+ - `AdkBuilder.enable_a2a_for_registered_agents(enabled=True, mount_base="/a2a", card_factory=None)`
171
+ - Expose programmatically registered agents (added via `with_agent_instance()` / `with_agents()`) over A2A without an `agents_dir`.
172
+ - Optionally supply `card_factory(name, agent) -> dict` to build an Agent Card; otherwise a minimal card is used.
173
+
174
+ - `AdkBuilder.with_remote_a2a_agent(name, agent_card_url, description=None)`
175
+ - Register a `RemoteA2aAgent` by agent card URL so your root agent can delegate to a remote agent.
176
+ - Requires `google-adk[a2a]` installed.
177
+
178
+ Expose a programmatic agent via A2A:
179
+
180
+ ```python
181
+ from google_adk_extras import AdkBuilder
182
+ from google.adk.agents import Agent
183
+
184
+ hello = Agent(model="gemini-2.0-flash", name="hello", instruction="You are helpful.")
185
+
186
+ app = (
187
+ AdkBuilder()
188
+ .with_agent_instance("hello", hello)
189
+ .with_a2a_protocol(True)
190
+ .enable_a2a_for_registered_agents() # becomes available at /a2a/hello
191
+ .build_fastapi_app()
192
+ )
193
+ ```
194
+
195
+ Consume a remote A2A agent:
196
+
197
+ ```python
198
+ from a2a.utils.constants import AGENT_CARD_WELL_KNOWN_PATH
199
+ from google_adk_extras import AdkBuilder
200
+
201
+ card_url = f"http://remote-host:8001/a2a/prime{AGENT_CARD_WELL_KNOWN_PATH}"
202
+
203
+ app = (
204
+ AdkBuilder()
205
+ .with_remote_a2a_agent("prime_agent", card_url, description="Prime checker")
206
+ # add your root agent via with_agent_instance(...)
207
+ .build_fastapi_app()
208
+ )
209
+ ```
210
+
211
+ - Artifacts
212
+ - `LocalFolderArtifactService` — per‑artifact metadata JSON + versioned data files
213
+ - `S3ArtifactService` — metadata JSON + versioned data objects in S3‑compatible storage
214
+ - `SQLArtifactService` — blobs per version in SQL
215
+ - `MongoArtifactService` — blobs per version in MongoDB
216
+
217
+ - Memory
218
+ - `SQLMemoryService`, `MongoMemoryService`, `RedisMemoryService`, `YamlFileMemoryService`
219
+ - Extracts text from `google.genai.types.Content`, tokenizes simple terms, and searches terms
220
+
221
+ - Credentials
222
+ - OAuth2: Google, GitHub, Microsoft, X (Twitter)
223
+ - Tokens: JWT (generate/verify/refresh‑aware), HTTP Basic (+ multi‑user variant)
224
+ - Persist via ADK’s session/in‑memory credential stores
225
+
226
+ - FastAPI integration
227
+ - `get_enhanced_fast_api_app(...)` accepts a provided credential service
228
+ - `EnhancedAdkWebServer` returns `EnhancedRunner` and keeps ADK’s caching/cleanup
229
+ - Prefer the fluent `AdkBuilder()` path for multi‑backend wiring in one place
230
+
231
+
232
+ ## Agent loading options
233
+
234
+ - Directory loading (ADK default): `with_agents_dir("./agents")` and create `./agents/<app_name>/agent.json` (or your ADK agent files) per app.
235
+ - Programmatic agents: register instances and avoid a folder layout.
236
+
237
+ ```python
238
+ from google_adk_extras import AdkBuilder
239
+ from google_adk_extras.custom_agent_loader import CustomAgentLoader
240
+ from google.adk.agents.base_agent import BaseAgent
241
+
242
+ loader = CustomAgentLoader()
243
+ loader.register_agent("my_app", BaseAgent(name="my_app")) # replace with a real agent
244
+
245
+ app = (
246
+ AdkBuilder()
247
+ .with_agent_loader(loader)
248
+ .with_session_service("sqlite:///./sessions.db")
249
+ .build_fastapi_app()
250
+ )
251
+ ```
252
+
253
+
254
+ ## Credential URI cheatsheet (optional)
255
+
256
+ If you prefer URIs instead of constructing services:
257
+
258
+ - Google OAuth2: `oauth2-google://client_id:secret@scopes=openid,email,profile`
259
+ - GitHub OAuth2: `oauth2-github://client_id:secret@scopes=user,repo`
260
+ - Microsoft OAuth2: `oauth2-microsoft://<tenant>/<client_id>:<secret>@scopes=User.Read`
261
+ - X OAuth2: `oauth2-x://client_id:secret@scopes=tweet.read,users.read`
262
+ - JWT: `jwt://<secret>@algorithm=HS256&issuer=my-app&audience=api.example.com&expiration_minutes=60`
263
+ - Basic: `basic-auth://username:password@realm=My%20API`
264
+
265
+ ```python
266
+ cred = (
267
+ AdkBuilder()
268
+ .with_credential_service_uri("jwt://secret@issuer=my-app")
269
+ ._create_credential_service()
270
+ )
271
+ ```
272
+
273
+
274
+ ## Notes & limitations
275
+
276
+ - The runner in this package is intentionally thin. All agent logic, tools, callbacks, and evaluation remain ADK responsibilities.
277
+ - The repository currently ships only the pieces listed above; referenced registries or configuration subsystems are intentionally out of scope.
278
+ - Some direct FastAPI parameters (e.g., ADK’s special memory URIs) pass through for parity, but the fluent builder is the recommended path for the extended backends offered here.
279
+
280
+
281
+ ## Docs
282
+
283
+ This repo ships a full MkDocs site in `docs/`.
284
+
285
+ Build locally with uv:
286
+
287
+ ```bash
288
+ uv pip install .[docs]
289
+ uv run mkdocs serve
290
+ ```
291
+
292
+ ## Development
293
+
294
+ ```bash
295
+ uv sync # or: pip install -e .
296
+ pytest -q # run tests
297
+ ```
298
+
299
+
300
+ ## License
301
+
302
+ Apache 2.0 — see LICENSE.
@@ -0,0 +1,259 @@
1
+ # google-adk-extras
2
+
3
+ [![PyPI](https://img.shields.io/pypi/v/google-adk-extras?label=PyPI)](https://pypi.org/project/google-adk-extras/)
4
+ ![Python](https://img.shields.io/badge/python-3.12%2B-blue)
5
+ ![License](https://img.shields.io/badge/license-Apache%202.0-green)
6
+ [![Docs](https://img.shields.io/badge/docs-site-brightgreen)](https://deadmeme5441.github.io/google-adk-extras/)
7
+ [![Docs Build](https://github.com/DeadMeme5441/google-adk-extras/actions/workflows/docs.yml/badge.svg)](https://github.com/DeadMeme5441/google-adk-extras/actions/workflows/docs.yml)
8
+
9
+ Production-ready extensions for Google ADK (Agent Development Kit). This library adds durable service backends (sessions, artifacts, memory), practical credential services (OAuth2/JWT/Basic), and clean FastAPI wiring so you can run ADK agents with real storage and auth.
10
+
11
+ What this is not: a fork of ADK. It builds on ADK’s core runtime, agents, tools and callbacks, and drops in where ADK expects services and a web server.
12
+
13
+
14
+ ## Why it exists
15
+
16
+ ADK provides the core primitives (Runner, Session/State, MemoryService, ArtifactService, CredentialService, Agents/Tools, callbacks, Dev UI, and deployment paths). See the official ADK docs for concepts and APIs.
17
+
18
+ This package focuses on three gaps common in real apps:
19
+ - Durable storage backends beyond in‑memory defaults
20
+ - Usable credential flows (Google/GitHub/Microsoft/X OAuth2, JWT, Basic)
21
+ - FastAPI integration that accepts your credential service without hacks
22
+
23
+
24
+ ## Features
25
+
26
+ - Session services: SQL (SQLite/Postgres/MySQL), MongoDB, Redis, YAML files
27
+ - Artifact services: Local folder (versioned), S3‑compatible, SQL, MongoDB
28
+ - Memory services: SQL, MongoDB, Redis, YAML files (term search over text parts)
29
+ - Credential services: Google/GitHub/Microsoft/X (OAuth2), JWT, HTTP Basic
30
+ - Enhanced FastAPI wiring that respects a provided credential service
31
+ - Fluent builder (`AdkBuilder`) to assemble a FastAPI app or a Runner
32
+ - A2A helpers for exposing/consuming agents (see below)
33
+
34
+ Note on Runner: `EnhancedRunner` is a thin subclass of ADK’s `Runner` for compatibility with the enhanced web server; it does not change behavior.
35
+
36
+
37
+ ## Install
38
+
39
+ Requirements: Python 3.12+, google-adk.
40
+
41
+ Using uv:
42
+
43
+ ```bash
44
+ # create a venv (optional)
45
+ uv venv && source .venv/bin/activate
46
+ # install the package
47
+ uv pip install google-adk-extras
48
+ ```
49
+
50
+ If you plan to use specific backends, also install their clients (examples):
51
+ - SQL: `uv pip install sqlalchemy`
52
+ - MongoDB: `uv pip install pymongo`
53
+ - Redis: `uv pip install redis`
54
+ - S3: `uv pip install boto3`
55
+ - JWT: `uv pip install PyJWT`
56
+
57
+
58
+ ## Quickstart (FastAPI)
59
+
60
+ Use the fluent builder to wire services and credentials. Then run with uvicorn.
61
+
62
+ ```python
63
+ # app.py
64
+ from google_adk_extras import AdkBuilder
65
+ from google_adk_extras.credentials import GoogleOAuth2CredentialService
66
+
67
+ app = (
68
+ AdkBuilder()
69
+ .with_agents_dir("./agents") # ADK agents on disk
70
+ .with_session_service("sqlite:///./sessions.db") # or: mongodb://, redis://, yaml://
71
+ .with_artifact_service("local://./artifacts") # or: s3://bucket, mongodb://, sql://
72
+ .with_memory_service("yaml://./memory") # or: redis://, mongodb://, sql://
73
+ .with_credential_service(GoogleOAuth2CredentialService(
74
+ client_id="…apps.googleusercontent.com",
75
+ client_secret="…",
76
+ scopes=["openid", "email", "profile"],
77
+ ))
78
+ .with_web_ui(True) # serve ADK’s dev UI if assets available
79
+ .with_agent_reload(True)
80
+ .build_fastapi_app()
81
+ )
82
+ ```
83
+
84
+ Run:
85
+
86
+ ```bash
87
+ uvicorn app:app --reload
88
+ ```
89
+
90
+ If you don’t keep agents on disk, register them programmatically and use a custom loader (see below).
91
+
92
+
93
+ ## Quickstart (Runner)
94
+
95
+ Create a Runner wired with your chosen backends. Use agent name (filesystem loader) or pass an agent instance.
96
+
97
+ ```python
98
+ from google_adk_extras import AdkBuilder
99
+
100
+ runner = (
101
+ AdkBuilder()
102
+ .with_agents_dir("./agents")
103
+ .with_session_service("sqlite:///./sessions.db")
104
+ .with_memory_service("redis://localhost:6379")
105
+ .with_artifact_service("local://./artifacts")
106
+ .build_runner("my_agent")
107
+ )
108
+
109
+ result = await runner.run("Hello there!")
110
+ ```
111
+
112
+
113
+ ## How this extends ADK (in practice)
114
+
115
+ ADK defines abstract service interfaces and a runner/web stack. This package provides drop‑in implementations and a small web‑server shim:
116
+
117
+ - Sessions
118
+ - `SQLSessionService` — SQLAlchemy; JSON‑serialized state/events
119
+ - `MongoSessionService` — PyMongo; per‑session doc, indexed by app/user/id
120
+ - `RedisSessionService` — hashes per session + user set; JSON state/events
121
+ - `YamlFileSessionService` — `base/app/user/{session_id}.yaml`
122
+
123
+ ### A2A helpers (new)
124
+
125
+ Two light-weight helpers wrap ADK’s A2A capabilities:
126
+
127
+ - `AdkBuilder.enable_a2a_for_registered_agents(enabled=True, mount_base="/a2a", card_factory=None)`
128
+ - Expose programmatically registered agents (added via `with_agent_instance()` / `with_agents()`) over A2A without an `agents_dir`.
129
+ - Optionally supply `card_factory(name, agent) -> dict` to build an Agent Card; otherwise a minimal card is used.
130
+
131
+ - `AdkBuilder.with_remote_a2a_agent(name, agent_card_url, description=None)`
132
+ - Register a `RemoteA2aAgent` by agent card URL so your root agent can delegate to a remote agent.
133
+ - Requires `google-adk[a2a]` installed.
134
+
135
+ Expose a programmatic agent via A2A:
136
+
137
+ ```python
138
+ from google_adk_extras import AdkBuilder
139
+ from google.adk.agents import Agent
140
+
141
+ hello = Agent(model="gemini-2.0-flash", name="hello", instruction="You are helpful.")
142
+
143
+ app = (
144
+ AdkBuilder()
145
+ .with_agent_instance("hello", hello)
146
+ .with_a2a_protocol(True)
147
+ .enable_a2a_for_registered_agents() # becomes available at /a2a/hello
148
+ .build_fastapi_app()
149
+ )
150
+ ```
151
+
152
+ Consume a remote A2A agent:
153
+
154
+ ```python
155
+ from a2a.utils.constants import AGENT_CARD_WELL_KNOWN_PATH
156
+ from google_adk_extras import AdkBuilder
157
+
158
+ card_url = f"http://remote-host:8001/a2a/prime{AGENT_CARD_WELL_KNOWN_PATH}"
159
+
160
+ app = (
161
+ AdkBuilder()
162
+ .with_remote_a2a_agent("prime_agent", card_url, description="Prime checker")
163
+ # add your root agent via with_agent_instance(...)
164
+ .build_fastapi_app()
165
+ )
166
+ ```
167
+
168
+ - Artifacts
169
+ - `LocalFolderArtifactService` — per‑artifact metadata JSON + versioned data files
170
+ - `S3ArtifactService` — metadata JSON + versioned data objects in S3‑compatible storage
171
+ - `SQLArtifactService` — blobs per version in SQL
172
+ - `MongoArtifactService` — blobs per version in MongoDB
173
+
174
+ - Memory
175
+ - `SQLMemoryService`, `MongoMemoryService`, `RedisMemoryService`, `YamlFileMemoryService`
176
+ - Extracts text from `google.genai.types.Content`, tokenizes simple terms, and searches terms
177
+
178
+ - Credentials
179
+ - OAuth2: Google, GitHub, Microsoft, X (Twitter)
180
+ - Tokens: JWT (generate/verify/refresh‑aware), HTTP Basic (+ multi‑user variant)
181
+ - Persist via ADK’s session/in‑memory credential stores
182
+
183
+ - FastAPI integration
184
+ - `get_enhanced_fast_api_app(...)` accepts a provided credential service
185
+ - `EnhancedAdkWebServer` returns `EnhancedRunner` and keeps ADK’s caching/cleanup
186
+ - Prefer the fluent `AdkBuilder()` path for multi‑backend wiring in one place
187
+
188
+
189
+ ## Agent loading options
190
+
191
+ - Directory loading (ADK default): `with_agents_dir("./agents")` and create `./agents/<app_name>/agent.json` (or your ADK agent files) per app.
192
+ - Programmatic agents: register instances and avoid a folder layout.
193
+
194
+ ```python
195
+ from google_adk_extras import AdkBuilder
196
+ from google_adk_extras.custom_agent_loader import CustomAgentLoader
197
+ from google.adk.agents.base_agent import BaseAgent
198
+
199
+ loader = CustomAgentLoader()
200
+ loader.register_agent("my_app", BaseAgent(name="my_app")) # replace with a real agent
201
+
202
+ app = (
203
+ AdkBuilder()
204
+ .with_agent_loader(loader)
205
+ .with_session_service("sqlite:///./sessions.db")
206
+ .build_fastapi_app()
207
+ )
208
+ ```
209
+
210
+
211
+ ## Credential URI cheatsheet (optional)
212
+
213
+ If you prefer URIs instead of constructing services:
214
+
215
+ - Google OAuth2: `oauth2-google://client_id:secret@scopes=openid,email,profile`
216
+ - GitHub OAuth2: `oauth2-github://client_id:secret@scopes=user,repo`
217
+ - Microsoft OAuth2: `oauth2-microsoft://<tenant>/<client_id>:<secret>@scopes=User.Read`
218
+ - X OAuth2: `oauth2-x://client_id:secret@scopes=tweet.read,users.read`
219
+ - JWT: `jwt://<secret>@algorithm=HS256&issuer=my-app&audience=api.example.com&expiration_minutes=60`
220
+ - Basic: `basic-auth://username:password@realm=My%20API`
221
+
222
+ ```python
223
+ cred = (
224
+ AdkBuilder()
225
+ .with_credential_service_uri("jwt://secret@issuer=my-app")
226
+ ._create_credential_service()
227
+ )
228
+ ```
229
+
230
+
231
+ ## Notes & limitations
232
+
233
+ - The runner in this package is intentionally thin. All agent logic, tools, callbacks, and evaluation remain ADK responsibilities.
234
+ - The repository currently ships only the pieces listed above; referenced registries or configuration subsystems are intentionally out of scope.
235
+ - Some direct FastAPI parameters (e.g., ADK’s special memory URIs) pass through for parity, but the fluent builder is the recommended path for the extended backends offered here.
236
+
237
+
238
+ ## Docs
239
+
240
+ This repo ships a full MkDocs site in `docs/`.
241
+
242
+ Build locally with uv:
243
+
244
+ ```bash
245
+ uv pip install .[docs]
246
+ uv run mkdocs serve
247
+ ```
248
+
249
+ ## Development
250
+
251
+ ```bash
252
+ uv sync # or: pip install -e .
253
+ pytest -q # run tests
254
+ ```
255
+
256
+
257
+ ## License
258
+
259
+ Apache 2.0 — see LICENSE.
@@ -0,0 +1,28 @@
1
+ # Programmatic Agents
2
+
3
+ You don’t need on‑disk agent folders. Register agent instances directly.
4
+
5
+ ```python
6
+ from google_adk_extras import AdkBuilder, CustomAgentLoader
7
+ from google.adk.agents.base_agent import BaseAgent
8
+
9
+ class EchoAgent(BaseAgent):
10
+ name = "echo"
11
+ async def _run_async_impl(self, ctx):
12
+ text = ctx.user_content.text if ctx.user_content else ""
13
+ yield self.create_text_response(f"Echo: {text}")
14
+
15
+ loader = CustomAgentLoader()
16
+ loader.register_agent("echo_app", EchoAgent())
17
+
18
+ app = (
19
+ AdkBuilder()
20
+ .with_agent_loader(loader)
21
+ .with_session_service("sqlite:///./sessions.db")
22
+ .build_fastapi_app()
23
+ )
24
+ ```
25
+
26
+ Guidance
27
+ - Use programmatic loading for testing or dynamic agent assembly.
28
+ - Do not mix `with_agents_dir()` and registered instances in one builder.
@@ -0,0 +1,31 @@
1
+ # Credentials
2
+
3
+ Provide auth to tools and agents using credential services.
4
+
5
+ ## OAuth2
6
+ - `GoogleOAuth2CredentialService`
7
+ - `GitHubOAuth2CredentialService`
8
+ - `MicrosoftOAuth2CredentialService`
9
+ - `XOAuth2CredentialService`
10
+
11
+ ```python
12
+ from google_adk_extras.credentials import GoogleOAuth2CredentialService
13
+
14
+ cred = GoogleOAuth2CredentialService(
15
+ client_id="...",
16
+ client_secret="...",
17
+ scopes=["openid", "email", "profile"],
18
+ )
19
+
20
+ app = AdkBuilder().with_credential_service(cred).build_fastapi_app()
21
+ ```
22
+
23
+ ## JWT
24
+ - `JWTCredentialService` (requires `PyJWT` via extra `[jwt]`).
25
+
26
+ ## HTTP Basic
27
+ - `HTTPBasicAuthCredentialService` and multi‑user variant.
28
+
29
+ Notes
30
+ - You can also configure via URIs (see URIs page).
31
+ - Credential storage defaults to ADK’s session/in‑memory stores.
@@ -0,0 +1,11 @@
1
+ # Examples
2
+
3
+ These examples are kept small and runnable; see the `examples/` folder.
4
+
5
+ - `examples/fastapi_app.py` — full app with durable backends.
6
+ - `examples/runner_basic.py` — runner without FastAPI.
7
+ - `examples/custom_loader.py` — programmatic agents.
8
+ - `examples/services/` — focused snippets per backend.
9
+ - `examples/credentials/` — focused credential usage.
10
+
11
+ Install extras to match what you run, e.g. `uv pip install google-adk-extras[sql,yaml,web]`.
@@ -0,0 +1,24 @@
1
+ # FastAPI Integration
2
+
3
+ Use `get_enhanced_fast_api_app` indirectly via `AdkBuilder.build_fastapi_app()`.
4
+
5
+ Key points
6
+ - Accepts your provided `credential_service` (no forced in‑memory default).
7
+ - Honors ADK’s Dev UI when assets are present.
8
+ - Preserves ADK’s runner caching/cleanup semantics via `EnhancedAdkWebServer`.
9
+
10
+ Example
11
+ ```python
12
+ app = (
13
+ AdkBuilder()
14
+ .with_agents_dir("./agents")
15
+ .with_session_service("sqlite:///./sessions.db")
16
+ .with_artifact_service("local://./artifacts")
17
+ .with_memory_service("yaml://./memory")
18
+ .build_fastapi_app()
19
+ )
20
+ ```
21
+
22
+ Dev UI
23
+ - Set `with_web_ui(True)`; if ADK’s web assets are available, the UI is served.
24
+ - Use `with_agent_reload(True)` for filesystem agent hot‑reload.