Cross-cutting runtime for Springboard-generated ADK agents: identity, sessions, memory, plugin, tools.
Project description
szns-springboard-runtime
Python package that Springboard-generated ADK agents install at deployment time. Provides the canonical inbound message contract, identity types, the inbound adapters (Slack + HTTP), the principal resolver, the SpringboardPlugin that wires identity into the ADK runner, and helpers that tools use to read identity from session state.
See ARCHITECTURE.md for the data model and end-to-end flow.
Layout
szns_springboard_runtime/
├── __init__.py set/get/clear_canonical_context, requires_canonical_context
├── plugin.py SpringboardPlugin (ADK BasePlugin) — the seam
│ that writes session.state["szns"]
├── _internal/canonical_context.py set/get/clear contextvar, requires_canonical_context
├── identity/
│ ├── context.py CanonicalInboundMessage, IdentityContext,
│ ActiveActor, Conversation, Source,
│ MessageContent, Correlation, Attachment,
│ AuthConfidence, Platform, Visibility,
│ VisibilityViolationError
│ ├── state.py build_szns_state, actor_to_dict, actor_from_dict
│ └── resolver.py PrincipalResolver, ResolvedPrincipal,
│ InMemoryPrincipalResolver (deterministic),
│ FirestorePrincipalResolver,
│ PrincipalNotFoundError
└── adapters/inbound/
├── slack.py from_event(payload)
└── http.py from_request(body)
demo_generated_agent.py runnable end-to-end demonstration
tests/ pytest suite (adapters, resolver, state, plugin)
How a generated agent wires it in
The plugin mirrors the Almanac plugin pattern — attach it to the runner, and
have each entryway hand it a CanonicalInboundMessage:
from szns_springboard_runtime import set_canonical_context
from szns_springboard_runtime.adapters.inbound import http, slack
from szns_springboard_runtime.plugin import SpringboardPlugin
runner = Runner(..., plugins=[springboard_plugin]) # one instance, module-level
# In each inbound handler, before runner.run_async(...):
set_canonical_context(slack.from_event(payload)) # or http.from_request(body)
SpringboardPlugin.before_run resolves a stable, tenant-scoped principal_id
and writes session.state["szns"]. For surfaces with no handler we control
(the ADK web UI, A2A) it synthesizes a degraded identity from the ADK
invocation, so identity is always present. Tools then read it:
from szns_springboard_runtime.identity import IdentityContext
def my_tool(tool_context) -> str:
identity = IdentityContext.from_tool_context(tool_context)
return identity.actor.principal_id # canonical; same across entryways
The plugin imports google-adk (always present in a generated agent); install
it for local plugin/demo work via the adk or dev extra.
Installation
pip install -e ".[dev]"
Usage
python demo_generated_agent.py
Development
pytest -v
ruff check .
ruff format --check .
mypy szns_springboard_runtime
Implemented
- Canonical inbound contract + identity types (
CanonicalInboundMessage,IdentityContext, …) - Inbound adapters: Slack (Events API + slash commands) and HTTP (generic HTTPS trigger)
InMemoryPrincipalResolver— deterministic, tenant-scoped canonical ids (stable across stateless instances) with cross-channelregister()linkingSpringboardPlugin— resolves identity and writessession.state["szns"]on every run; synthesizes a degraded identity for surfaces with no inbound handler (ADK web, A2A)
Not yet implemented
SznsSessionService(extends ADKSessionService) /SznsMemoryService- Governance / OTel / model-armor plugins and tool wrappers (
with_confirmation,with_retry,with_scope) - Real visibility classifier (MVP stamps
private) andauth_confidenceenforcement - Channel adapters for email (Slack + HTTP done; ADK web / A2A via plugin fallback)
- Outbound adapters
FirestorePrincipalResolverimplementation (interface scaffolded; stub raisesNotImplementedError) — required for cross-provider identity continuity across stateless instances- Pydantic migration of identity types
Open configuration questions
auth_confidencedetermination policy. The Slack adapter currently assignsWORKSPACE_VERIFIEDto any signed Slack request; HTTP assignsOBSERVED_EMAIL/ANONYMOUS.conversation_idfallback whenthread_tsis absent. Current chain:thread_tsthentsthen channel-only.
References
- ARCHITECTURE.md
- Improved Architecture Tech Spec
- Runtime SDK Tech Spec
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distributions
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file szns_springboard_runtime-0.0.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl.
File metadata
- Download URL: szns_springboard_runtime-0.0.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl
- Upload date:
- Size: 1.9 MB
- Tags: CPython 3.12, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.17
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fdd879af181ccde88d247565915f5ee85132720c9b762fde395831f9cc53d021
|
|
| MD5 |
a06b77f0643296672008b7c528884d14
|
|
| BLAKE2b-256 |
e85f4766ccf9db6aa72a1b69f75f65c582ae531fe1ec868109528e07b41dfe74
|
File details
Details for the file szns_springboard_runtime-0.0.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl.
File metadata
- Download URL: szns_springboard_runtime-0.0.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl
- Upload date:
- Size: 1.8 MB
- Tags: CPython 3.11, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.17
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4862b5bdc0ee25772f4c3b7640eaf1deaeafeb2c904016a0c66d388cb05c4461
|
|
| MD5 |
703e3d3b8508abfd7d9221c0c35fe2f2
|
|
| BLAKE2b-256 |
e7981122f6fd9394cb4d415962acf4f4c6a57c8dab1f38250fc97befa63fbc67
|