Add unstable ACP schema support + $/cancel_request#17
Add unstable ACP schema support + $/cancel_request#17
Conversation
Change-Id: Id1d0dff677c5a0ec7506a423f278c8a2ded27966 Signed-off-by: Thomas Kosiewski <tk@coder.com>
Change-Id: I91e09574e4a46d5d6645f0844e3e4f2b3040cf2b Signed-off-by: Thomas Kosiewski <tk@coder.com>
Add optional loading for meta/schema.unstable.json and merge unstable-only methods into the IR without changing stable defs. Also adjust union UnmarshalJSON generation to tolerate primitive JSON by only peeking at object maps when that unmarshal succeeds. Change-Id: I81dbcd9f72e9106c95c6aafb07f895b7758e7f5e Signed-off-by: Thomas Kosiewski <tk@coder.com>
Regenerate types_gen.go so union UnmarshalJSON methods no longer error on primitive JSON variants. Change-Id: Ie20a7e301e4808e8a66a339456029d1f08ecad7d Signed-off-by: Thomas Kosiewski <tk@coder.com>
Change-Id: Iee25c62931dea5b76748fe8ece4700d73e32211c Signed-off-by: Thomas Kosiewski <tk@coder.com>
Change-Id: If59c040a3faa7a21ca59dce5f86d4bd26252c020 Signed-off-by: Thomas Kosiewski <tk@coder.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ac0b690036
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
Hey @ThomasK33, can this be merged? Also https://agentclientprotocol.com/protocol/session-config-options is now stable. |
Change-Id: I1110d20acf558e42a8b2b95d30e285f446e3a7e7 Signed-off-by: Thomas Kosiewski <tk@coder.com>
|
@codex review |
Change-Id: I9c10393f4d6ce1ccac4df0eb83e11795c4ad2867 Signed-off-by: Thomas Kosiewski <tk@coder.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: bb34ca2793
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Change-Id: I30839ab01619439e1a3178f319abe3312d63a7b3 Signed-off-by: Thomas Kosiewski <tk@coder.com>
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: acb634959a
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Change-Id: I24665f26981bcaf92e98cd2e616071fc84d04c93 Signed-off-by: Thomas Kosiewski <tk@coder.com>
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: b7ec4e89e7
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Change-Id: I98d174fac0f30681f36c6735a0c71a71d1fc55fe Signed-off-by: Thomas Kosiewski <tk@coder.com>
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
acp-go-sdk/cmd/generate/internal/emit/types.go
Lines 1127 to 1130 in b6947c3
The fallback branch accepts the first variant whose json.Unmarshal succeeds, which is unsafe for unions where multiple array variants can decode the same payload. With the new unstable schema this causes valid grouped select-options payloads (objects with group/options) to be parsed as the ungrouped variant first because unknown fields are ignored and missing required fields become zero values, so grouping information is silently lost in UnstableSessionConfigSelectOptions.
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Change-Id: I381d40fbf2040fe4c2bcc511e0c3bf3b91816796 Signed-off-by: Thomas Kosiewski <tk@coder.com>
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: c7c2c7c34b
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Change-Id: I0a5cc811d92a23987bf47a57ad16c77f2b41bf4e Signed-off-by: Thomas Kosiewski <tk@coder.com>
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: c67a44c49a
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Change-Id: I37676ffb056b5867b5bbb2e2cff121145c9b5c65 Signed-off-by: Thomas Kosiewski <tk@coder.com>
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 853d58e391
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Change-Id: I690ec1462659be0d1f068dbf786f0a96a10ed611 Signed-off-by: Thomas Kosiewski <tk@coder.com>
|
@codex review |
|
Codex Review: Didn't find any major issues. Breezy! ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 476669d162
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Change-Id: I0bab8ffb5e201d1c82d5fd9aba087fa45f995787 Signed-off-by: Thomas Kosiewski <tk@coder.com>
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: aba87cd94b
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Change-Id: I163e43ba12da91083562f08aec8646eab81d96e6 Signed-off-by: Thomas Kosiewski <tk@coder.com>
|
@codex review |
|
Codex Review: Didn't find any major issues. Hooray! ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 14f70fb539
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Change-Id: Ib8b24f1cd85b13ca47fc59fa2b3e3f4af1a7ad3e Signed-off-by: Thomas Kosiewski <tk@coder.com>
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 2d3ab6aa6d
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Change-Id: I3b3a79ee49f2c069abd5dd24db0e8a22e8627ae3 Signed-off-by: Thomas Kosiewski <tk@coder.com>
|
@codex review |
|
Codex Review: Didn't find any major issues. Bravo. ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: b54e8a331d
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Change-Id: I1e6195bae6969b5e07b532c5f042244530eb9a9e Signed-off-by: Thomas Kosiewski <tk@coder.com>
|
@codex review |
|
Codex Review: Didn't find any major issues. Breezy! ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
|
@codex review |
|
Codex Review: Didn't find any major issues. Swish! ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
|
@codex review |
|
Codex Review: Didn't find any major issues. Another round soon, please! ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
Add support for ACP unstable schemas alongside stable API generation, and implement full
$/cancel_requestcancellation semantics.What changed
schema/meta.unstable.json+schema/schema.unstable.json(with safe fallback for older ACP releases).Unstable*prefix.$/cancel_requestinbound/outbound handling, per-request cancellation contexts, and map cancellations to JSON-RPC error code-32800.UnmarshalJSONfor unions that can be primitives (e.g.RequestId).Verification
go test ./...(cd cmd/generate && go test ./...)📋 Implementation Plan
ACP unstable schema support +
Unstable*Go APIContext / Why
Upstream ACP now ships additional schema artifacts:
schema/meta.unstable.jsonschema/schema.unstable.jsonGoal:
meta.json/schema.json) unchanged.Unstableprefix (user choice: prefix existing schema type names, e.g.ForkSessionRequest→UnstableForkSessionRequest).$\/cancel_requestprotocol cancellation support (user choice).Evidence (what we verified)
schema/(schema/meta.json,schema/schema.json,schema/versioncurrently0.10.7).meta.jsonvsmeta.unstable.json:session/fork,session/list,session/resume,session/set_config_option,session/set_model.$/cancel_request(underprotocolMethods).schema.unstable.jsonis a superset ofschema.json(main branch sample: 29 new$defs, 7 changed$defs).meta.json+schema.json(cmd/generate/main.go,cmd/generate/internal/load/load.go).*Requesttype name (so renaming request types is sufficient to rename method names).protocolMethodshandling today.Connectiondoes not support$\/cancel_requestand does not have per-request cancellation (single shared context for inbound handlers).Plan
1) Fetch & store unstable schema files in-repo
Makefileto download (from the pinned release tag) in addition to stable files:schema/meta.unstable.jsonschema/schema.unstable.jsonmake versionbrings these files in (and generator remains compatible if they’re absent for older pins).2) Loader changes: parse unstable meta + schema (optionally)
cmd/generate/internal/load.Meta:ProtocolMethods map[string]string \json:"protocolMethods,omitempty"``.ReadMetaUnstable(schemaDir) (*Meta, bool, error)ReadSchemaUnstable(schemaDir) (*Schema, bool, error)(nil, false, nil)when the*.unstable.jsonfile isn’t present.3) Core: merge stable + unstable into a single codegen view without changing stable API
Create a merge step (new file in
cmd/generate/internal/load/orcmd/generate/internal/ir/) that outputs:combinedMeta: stable methods + unstable-only methods (for codegen), and protocolMethods.combinedSchema: stable$defsplus additional$defswithUnstable-prefixed names.3.1 Determine which wire methods are “unstable-only”
Compute unstable-only wire method sets by diffing by wire method string:
unstableAgentWires = metaUnstable.AgentMethods − metaStable.AgentMethodsunstableClientWires = metaUnstable.ClientMethods − metaStable.ClientMethodsunstableProtocolWires = metaUnstable.ProtocolMethods(stable has none)Merge these into
combinedMeta(keep stable maps unchanged; only add new entries).3.2 Build the set of
$defsto duplicate asUnstable*Roots: in
schema.unstable.json, find all$defswhere:x-method∈ unstable-only wire set, andx-sidematches (agent,client,protocol), andRequest,Response, orNotification.Reachability: traverse
$refedges from roots withinschema.unstable.jsonto computereachable.Fixpoint selection (minimal duplication): compute
neededwhere we must create an unstable-prefixed copy:neededwith all roots.reflect.DeepEqual(stableDef, unstableDef) == false).needed, then it must also be inneeded(so we can rewrite refs and keep the unstable graph self-consistent).This matches the user requirement: generate unstable variants for stable-RPC types only when needed transitively.
3.3 Emit
Unstable*defs (deep-copy + rewrite refs)For each def name
Tinneeded:schemaUnstable.$defs[T].#/$defs/X→#/$defs/UnstableXonly whenXis also inneeded.combinedSchema.$defsunder the new keyUnstable<T>.Avoid method-group collisions: if the copied def has
x-methodpointing to a stable wire method (present inmeta.json), clearx-method/x-sideon the copy so it won’t be treated as the canonical request/response type for stable dispatch.Naming rule (chosen):
ForkSessionRequest→UnstableForkSessionRequest(simple prefix; no re-ordering).4) Wire up generator entrypoint to use merged inputs
Update
cmd/generate/main.go:combinedMeta+combinedSchema.emit.WriteConstantsJenemit.WriteTypesJenemit.WriteDispatchJenemit.WriteHelpersJenExpected result:
Agent,Client, etc.) remain unchanged.Unstable*and land inAgentExperimental/ClientExperimentalvia the existing “unstable” doc marker detection.5) Full
$\/cancel_requestsupport (protocol cancellation)Implement cancellation primarily in runtime, not by exposing protocol hooks on Agent/Client.
5.1 Inbound cancellation (server-side)
Update
connection.go:inflightmap keyed by JSON-RPC id string (raw JSON form, consistent with existingpendingmap keys).idandmethod):reqCtx, cancel := context.WithCancelCause(c.ctx)cancelininflight[idKey]reqCtxto the handler$\/cancel_requestnotifications inreceive()before invokingc.handler:paramsas an object, extractrequestIdas raw JSONcancelexists, call it (cause can becontext.Canceled)5.2 Outbound cancellation (client-side)
When
SendRequestwaits for a response andctx.Done()fires first:$\/cancel_requestnotification to the peer with params{ "requestId": <raw id> }.5.3 Error mapping for canceled requests
NewRequestCancelled(...)returning JSON-RPC error code-32800.toReqErrto mapcontext.Canceled(and/or cancel causes) to-32800instead of treating it as internal error.6) Fix union unmarshal for non-object variants (needed for
RequestId)RequestIdis ananyOfunion ofnull | number | string. Today the generatedUnmarshalJSONalways triesmap[string]json.RawMessage, which fails for primitives.Update
emitUnioncodegen so:map[string]json.RawMessageunmarshalThis makes
RequestId(and thusCancelRequestNotification) usable.7) Tests + validation
Unstable*; refs rewritten; stable method grouping unaffected.$\/cancel_requestcancels a long-running handler and produces-32800$\/cancel_requeston the wire (capture writes)make versionmake fmtmake testNotes / non-goals (keep scope tight)
AgentExperimental/ClientExperimental) to avoid breaking implementers.Generated with
mux• Model:openai:gpt-5.2• Thinking:xhigh