Add support for ACP extension methods #11
+372
−5
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.
Add first-class support for ACP extension methods (JSON-RPC methods starting with
_).Key changes:
ExtensionMethodHandlerfor agent/client implementations to receive extension requests/notifications._...methods through the handler (fallback to MethodNotFound per spec).CallExtension/NotifyExtensionhelpers on both AgentSideConnection and ClientSideConnection.Fixes #4
Tests:
go test ./...📋 Implementation Plan
Plan: Support ACP extension methods (method names starting with
_)Context
_and are negotiated via_metain capabilities. Unknown extension requests should return JSON-RPC “Method not found” (-32601); unknown extension notifications should be ignored.Goals
AgentSideConnection/ClientSideConnection.acp.Agent/acp.Clientinterfaces).Non-goals
_meta, but not enforce a schema).Proposed public API
1) Optional handler interface (non-breaking)
Add a new optional interface in a non-generated file (e.g.
extensions.go):Why a single interface:
AgentExtensionHandler,ClientExtensionHandler) with identical signatures.2) Outbound helpers on connections
Add additive helper methods:
Implementation notes:
strings.HasPrefix(method, "_"); return a Go error if not.SendRequest[T]/Connection.SendNotification.Alternative: expose the raw *Connection
Instead of adding helper methods, we could add
Conn() *Connectionto both wrapper types so callers can directly useSendRequest/SendNotificationwith arbitrary methods.Pros: maximum flexibility (also helps with “future core methods” before regeneration).
Cons: leaks a lower-level type and makes the public surface bigger.
The helper-method approach keeps the abstraction and still covers the common use case.
Implementation steps
A) Dispatch inbound extension methods (agent + client)
ExtensionMethodHandlerinterface (new file, non-generated).NewAgentSideConnectionandNewClientSideConnectionto pass a new wrapper handler toNewConnection:agent.go, replaceNewConnection(asc.handle, …)withNewConnection(asc.handleWithExtensions, …).client.go, replaceNewConnection(csc.handle, …)withNewConnection(csc.handleWithExtensions, …).handleWithExtensionsmethods (non-generated) that:strings.HasPrefix(method, "_"):a.agent/c.clientimplementsExtensionMethodHandler, call it.errorviatoReqErr.NewMethodNotFound(method).handlemethod for core ACP methods.This approach avoids modifying codegen and keeps the extension routing logic stable across regenerations.
B) Make notification behavior spec-friendly (reduce noise)
Currently, if a notification is unrecognized and the handler returns
NewMethodNotFound,connection.gologs an error.Adjust
Connection.handleInboundnotification path:req.ID == nil(notification) and the handler error is*RequestErrorwithCode == -32601, do not log.strings.HasPrefix(req.Method, "_")) so we keep visibility into unexpected core-method notifications.C) Add outbound helpers for extension calls
Add
CallExtension/NotifyExtensionmethods to both connection wrapper types._.SendRequest[T](c.conn, ctx, method, params)c.conn.SendNotification(ctx, method, params)D) Tests
Extend
acp_test.gowith focused, table-driven tests:agentFuncs-like struct that also implementsExtensionMethodHandler.CallExtensionwith_vendor.test/echo.methodand rawparams, and the response was decoded.*RequestError{Code: -32601}.ExtensionMethodHandler.E) Documentation / examples
README.mdwith a new “Extension methods” section covering:_vendor.id/feature/actionconvention).ExtensionMethodHandler._meta(and calling side checking it).example/) showing:_metacapabilities._vendor.id/…extension method and handles response.Notes on capability negotiation via _meta
The ACP spec uses
_metawithin capabilities as an extension point.The SDK already models this as
Meta anyonAgentCapabilities/ClientCapabilities.In docs, recommend:
map[string]anyor a small struct for_meta._meta(traceparent,tracestate,baggage).Rollout
Generated with
mux