Skip to content

Phase 2: Pluggable TaskStore on create_a2a_server (PR-N) #224

@bokelley

Description

@bokelley

Summary

adcp.server.create_a2a_server() today instantiates InMemoryTaskStore() directly. Tasks don't survive restarts. Downstream (salesagent) has 2,288 LOC of custom A2A server code largely because this hook doesn't exist — they can't adopt the SDK's A2A path without losing DB-backed task persistence.

Proposed API

from a2a.server.tasks.task_store import TaskStore

def create_a2a_server(
    handler: ADCPHandler,
    *,
    ...,
    task_store: TaskStore | None = None,  # defaults to InMemoryTaskStore()
) -> Starlette: ...

Downstream subclasses a2a-sdk's TaskStore ABC (or implements the protocol) against their own Postgres/Redis/etc. and passes it in.

Reference impl

Ship examples/a2a_db_tasks.py with a SQLAlchemy + asyncpg reference. Not production-quality — just enough to prove the hook works and give the next adopter a starting point.

Acceptance

  • task_store kwarg threaded into DefaultRequestHandler(task_store=...).
  • Integration test that uses a file-backed TaskStore subclass and proves the cache survives server restart.
  • Example file referenced from docs/handler-authoring.md.

Context

Roadmap item PR-N (Phase 2) from .context/sdk-adoption-roadmap.md. Downstream feedback in /Users/brianokelley/Developer/salesagent/.conductor/lima-v16/.context/sdk-server-adoption.md — one of three blockers (with #225, #226) making A2A adoption net-negative today.

Revisit A2A adoption story: when N + O + P have shipped and been used by at least one downstream, the ~13-day salesagent A2A migration drops to ~5-day and net-positive.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions