feat(app): let an extension supply the A2A handler - #2544
Merged
Conversation
grpcserver registers the A2A service only when A2AHandler is set, and core/pkg/app never sets it. A controller built on app.Start can therefore create AgentInstances but cannot talk to them: Unimplemented: unknown service lf.a2a.v1.A2AService core/cmd/controller-v2 sets it, but that is package main, so the capability is unreachable to anything embedding app.Start. ExtensionConfig gains an A2AHandler field, passed through to grpcserver. Nothing else changes: the field defaults to nil and grpcserver skips registration exactly as it does today. The extension can build a handler with a2agateway.New using the DbClient it already receives in BootstrapConfig, which is resolved well before the gRPC server is constructed, so no ordering change is needed either. Signed-off-by: Jonathan Jamroga <jjamroga@gmail.com>
jjamroga
force-pushed
the
extension-a2a-handler
branch
from
August 25, 2026 13:25
e588244 to
33b5ea1
Compare
EItanya
approved these changes
Aug 25, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
grpcserverregisters the A2A service only whenA2AHandleris non-nil, andcore/pkg/appnever sets it. A controller built onapp.Startcan create AgentInstances but cannot talk to them:core/cmd/controller-v2does set it, but that ispackage main, so the capability is unreachable to anything embeddingapp.Start.Change
ExtensionConfiggains anA2AHandlerfield, passed through togrpcserver. That's it — one file, two lines of code.Nothing else changes. The field defaults to nil and
grpcserverskips registration exactly as it does today, so this is inert unless an extension opts in.It also needs no reordering:
getExtensionConfigis called with theDbClientinBootstrapConfigwell before the gRPC server is constructed, so an extension can build a handler witha2agateway.Newand return it.Alternative considered
I first went at this by exporting
core/internal/grpcserverand adding a public constructor for the store, so the v2 stack could be assembled outsidepackage main(#2543). This is much smaller, keeps the internals internal, and covers the actual need — so I've closed that one in favour of this.The larger export still has an independent argument: it would let an external module stand up the gRPC surface with a real Postgres and fakes for
a2agateway's dialer andagentinstance's actor client, and test AgentInstance lifecycle, ownership checks, A2A routing andDefaultMethodPolicieswithout a cluster or Substrate. Happy to revive it if that's wanted, but it shouldn't be bundled with this.Testing
go build ./...,go vet, andgo test ./core/pkg/app/ ./core/internal/grpcserver/all pass.