Skip to content

feat(server): expose request_handler= on create_a2a_server() #1007

Description

@numarasSigmaSoftware

create_a2a_server() constructs DefaultRequestHandler internally and offers no way to supply a different one, so an adopter with an existing a2a.server.request_handlers.RequestHandler implementation cannot use the factory at all — it is all-or-nothing.

The value is already a local variable that gets threaded into the JSON-RPC routes, so exposing it is additive:

# adcp/server/a2a_server.py (6.6.0 and v7.0.0-rc, identical)
1182:        request_handler = DefaultRequestHandler(
1188:        jsonrpc_kwargs["request_handler"] = request_handler
1227:        request_handler = DefaultRequestHandler(   # v0.3 compat branch
1233:        jsonrpc_kwargs["request_handler"] = request_handler

Proposed change — add a keyword-only parameter, default None, preserving today's behavior:

def create_a2a_server(
    handler: ADCPHandler[Any],
    *,
    ...,
    request_handler: RequestHandler | None = None,
) -> Any:

When supplied, use it for both the 1.0 and v0.3 compat branches instead of constructing DefaultRequestHandler. When None, behavior is unchanged.

Why it matters. task_store= and push_config_store= already let adopters own persistence, but some request-level semantics live in the handler rather than the store — most visibly tasks/cancel, which DefaultRequestHandler resolves against its in-process active-task registry and therefore cannot cancel a task issued by a previous process or a sibling worker. Multi-worker deployments cannot express durable cancel through any currently-exposed seam.

Concretely, this blocks incremental adoption. We maintain a seller agent with a mature RequestHandler implementation and would like to adopt the SDK's executor, middleware chain, error translation, and validation while keeping our request-handler layer during migration. Today the only options are "adopt everything" or "adopt nothing"; this kwarg makes a staged migration possible.

Compatibility: additive, keyword-only, default preserves current behavior.

We are happy to open the PR if the direction is acceptable.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions