Skip to content

feat(cli): add --app_name to decouple session/artifact storage from folder#6467

Open
amitjborate wants to merge 4 commits into
google:mainfrom
amitjborate:feat/app-name-override
Open

feat(cli): add --app_name to decouple session/artifact storage from folder#6467
amitjborate wants to merge 4 commits into
google:mainfrom
amitjborate:feat/app-name-override

Conversation

@amitjborate

Copy link
Copy Markdown

Summary

When agents are served via adk web / adk api_server by passing a directory, the app_name used to key sessions and artifacts is derived from the agent's folder name. Two servers that load an identically-named agent folder against a shared session/artifact backend therefore write under the same app_name and unintentionally share each other's sessions. There is currently no supported way to override the app_name on the directory-launch path (ADK_DEFAULT_APP_NAME only injects a default when a client omits it; it does not decouple storage from the folder name).

This PR adds an optional app_name override, exposed three ways:

  • get_fast_api_app(app_name=...)
  • --app_name CLI flag on adk web and adk api_server
  • ADK_APP_NAME environment variable (fallback)

When set, the session and artifact services are wrapped so their app_name is pinned to the override, while the agent loader, REST routes, and web UI keep using the folder name. Servers loading the same folder can thus be given distinct app_names to isolate their persisted data — or the same one to share it, on purpose — without renaming the folder.

Motivation / use case

Running multiple instances of the same agent (e.g. one server per tenant/channel) against a shared session backend (Postgres, MySQL, …), launched by pointing at a directory whose folder name is identical across instances. Today their sessions collide. With this change each instance sets a distinct --app_name and stays isolated.

# instance A
adk api_server --session_service_uri postgresql+asyncpg://…(shared) --app_name channel_a  path/to/agent
# instance B  (same folder name, same DB)
adk api_server --session_service_uri postgresql+asyncpg://…(shared) --app_name channel_b  path/to/agent

Design

A thin decorator (google/adk/cli/utils/app_name_override.py) wraps BaseSessionService / BaseArtifactService and rewrites only the app_name keyword argument before delegating; every other argument and any implementation-specific attribute passes through unchanged. Because this operates at the abstraction layer, it is storage-agnostic — it never touches SQL, drivers, connection strings, or schema.

The session/artifact routes and the Runner both flow through the same wrapped service instance, so a single wrap covers the REST session CRUD, the web UI, and agent runs consistently. session.app_name already carries the override on the append_event path (the session was created/fetched through the wrapper), so no rewrite is needed there.

Backward compatibility

Fully opt-in. When no override is supplied, maybe_override_app_name returns the services unchanged, so the new code path is never entered for existing deployments — behavior is byte-for-byte identical on every backend. The new function argument is keyword-only with a None default, and the new CLI flag / env var default to unset.

Scope / follow-ups

Covers the two app-scoped stores with a clean app_name= interface: sessions and artifacts. The memory service is intentionally left for a follow-up — its add_session_to_memory(session) carries app_name inside the Session object rather than as a kwarg, and ADK ships no SQL-backed memory service (memory is per-process memory:// or Vertex rag:// / agentengine://), so it is unaffected by shared-SQL-database setups.

Tests

tests/unittests/cli/utils/test_app_name_override.py (10 tests):

  • Session override stores under the override, not the folder name (get/list/delete round-trip).
  • Two distinct overrides on one backend stay isolated; two equal overrides share (opt-in).
  • Artifact override stores under the override.
  • maybe_override_app_name is a no-op without an override and wraps when given one.
  • Unknown attributes delegate through.
  • Backend matrix test_override_is_backend_agnostic: InMemorySessionService, DatabaseSessionService (sqlite+aiosqlite — the same class Postgres/MySQL use), and SqliteSessionService. DB backends are importorskip-guarded so the suite still runs where optional drivers are absent.

All 10 pass locally.

@google-cla

google-cla Bot commented Jul 24, 2026

Copy link
Copy Markdown

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

@adk-bot adk-bot added the services [Component] This issue is related to runtime services, e.g. sessions, memory, artifacts, etc label Jul 24, 2026
@amitjborate
amitjborate force-pushed the feat/app-name-override branch from b37dd2a to e8025fa Compare July 24, 2026 21:22
…older name

When agents are served via `adk web` / `adk api_server` by passing a
directory, the app_name used to key sessions and artifacts is derived from
the agent's folder name. Two servers that load an identically-named agent
folder against a shared session/artifact backend therefore write to the same
app_name and unintentionally share each other's sessions. There was no
supported way to override the app_name on the directory-launch path.

This adds an optional app_name override:
  - `get_fast_api_app(app_name=...)`
  - `--app_name` CLI flag on `adk web` and `adk api_server`
  - `ADK_APP_NAME` environment variable (fallback)

When set, the session and artifact services are wrapped so their `app_name`
is pinned to the override, while the agent loader, REST routes and web UI keep
using the folder name. Servers loading the same folder can thus be given
distinct app_names to isolate their persisted data (or the same app_name to
share it, on purpose) without renaming the folder.

The change is opt-in: when no override is supplied the services are returned
unchanged, so existing deployments on any backend are unaffected. The wrapper
operates at the BaseSessionService/BaseArtifactService abstraction (it only
rewrites the app_name string), so it is storage-agnostic. Tests cover the
wrapper logic, the get_fast_api_app wiring, and a backend matrix
(in-memory, DatabaseSessionService via sqlite+aiosqlite -- the same class
Postgres/MySQL use -- and SqliteSessionService).
@amitjborate
amitjborate force-pushed the feat/app-name-override branch from 723bae8 to b61e6e8 Compare July 24, 2026 21:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

services [Component] This issue is related to runtime services, e.g. sessions, memory, artifacts, etc

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants