Go SDK: add Client.CreateCloudSession#1396
Conversation
- CreateSession now rejects config.Cloud with an error pointing to CreateCloudSession - CreateCloudSession validates config (requires Cloud, rejects caller-supplied SessionID and Provider), omits sessionId from the session.create wire payload so the runtime assigns one - Pending-routing support: a refcounted beginPendingSessionRouting guard buffers session.event notifications (bounded drop-oldest, 128 per id) and parks inbound request handlers (userInput.request, exitPlanMode.request, autoModeSwitch.request, hooks.invoke, systemMessage.transform) until the runtime-assigned session id is registered; waiters are rejected with a clear error if pending mode ends without registration - TOCTOU race fixed: after acquiring pending.mu, both handleSessionEvent and waitForSession re-check c.sessions so a notification/request that races with flushPendingForSession is dispatched directly rather than buffered and abandoned - Waiter buffer is also bounded at 128; oldest waiter is rejected on overflow - README and inline godoc updated Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This comment has been minimized.
This comment has been minimized.
Carries the Rust SDK PR #1394 follow-up review fixes into the Go port: 1. Cap the per-session parked-waiter list at 128. When exceeded, reject the oldest waiter with errPendingSessionBufferOverflow ('pending session buffer overflow'). The handler returns a *jsonrpc2.Error with code -32603 via the new pendingRoutingRPCError helper, so the runtime receives a proper error response instead of hanging on the request id until its own timeout. Mirrors Rust commit 491b442 and TS commit c167bc3. 2. When the last pending-routing guard drops without RegisterSession (e.g. session.create failed mid-RPC), signal all parked waiters with errPendingSessionRoutingEnded ('pending session routing ended before session was registered'). Distinct phrasing from the overflow path so debugging can tell the two cases apart. Mirrors Rust commit e0ff254 and TS commit c167bc3. Adds pendingRoutingRPCError helper that routes sentinel errors to -32603 while unknown-session errors keep -32602. Adds two tests: - TestPendingRouting_OverflowEmitsError: 129 parked waiters, oldest gets -32603 overflow error, remaining 128 resolve normally after registration. - TestPendingRouting_GuardDropDistinctMessage: parks a request, drops the guard without registration, verifies exact routing-ended message and -32603 code. Updates TestPendingRouting_RejectsWaitersOnDispose to assert the new exact message and code instead of the old 'dropped' substring check. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Cross-SDK Consistency ReviewThe Go implementation in this PR looks great and correctly matches the Rust (#1394) and TypeScript (#1395) contracts. However, Python and .NET are not yet consistent with this new pattern. Missing in Python (
|
Ports
CreateCloudSessionto the Go SDK, matching the contract established by the Rust (#1394) and TypeScript (#1395) implementations.What changed
go/client.goCreateSessionnow returns a clear error whenconfig.Cloud != nil, pointing callers toCreateCloudSessionCreateCloudSession(ctx, config)method: validates config (requiresCloud, rejects caller-suppliedSessionIDorProvider), omitssessionIdfrom thesession.createwire payload (runtime assigns it), registers the session under the returned id, then callsflushPendingForSessionbefore releasing the routing guardpendingRoutingstruct +beginPendingSessionRouting/flushPendingForSession/waitForSessionhelpers: a refcounted guard bufferssession.eventnotifications (bounded drop-oldest, 128 per id) and parks inbound request handlers (userInput.request,exitPlanMode.request,autoModeSwitch.request,hooks.invoke,systemMessage.transform) while a cloudsession.createis in flighthandleSessionEventandwaitForSessionre-checkc.sessionsafter acquiringpending.mu, so an event/request that races withflushPendingForSessionis dispatched directly rather than buffered and abandonedgo/cloud_session_test.go(new)9 unit tests covering:
CreateSessioncloud rejection, wire payload (assertssessionIdis omitted), callerSessionIDrejection, callerProviderrejection, missingCloudrejection, early-notification buffering and replay, inbound-request parking and unblocking, drop-oldest overflow, waiter rejection on dispose.go/README.md— addsCreateCloudSessionto the API reference and a new Cloud Sessions section.Deviations from Rust/TS
sessionFs.*inbound requests (generated client-session API handlers) are not pending-buffered, matching the known limitation documented in the TS PR. In practice the runtime does not initiatesessionFs.*calls before thesession.createresponse.c.client.Requestcall is not supported (the jsonrpc2 client has no context-awareRequestAPI), same limitation as TS.