Replies: 1 comment
|
This is helpful |
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
This is a resubmission of #5234, closed as not-planned on 2026-08-26 with "no plans to make changes or improvements to this part of the codebase." I am reopening it because the original report did not convey the operational cost, and because the change is smaller than it probably looked. If the answer is still no, I would appreciate knowing why — from the outside it looks like it costs nothing to anyone who does not opt in.
Problem
An AI Studio websocket provider's identity is
aistudio-<16 random chars>, generated server-side byrandomProviderName()ininternal/wsrelay/manager.go.wsOnConnecteduses that string as the auth ID and puts it inMetadata["email"];wsOnDisconnecteddeletes the auth on disconnect. So the identity dies with the TCP connection.I run one headless browser per Google account. What that costs me:
Usage statistics cannot survive a restart. They are aggregated by
Metadata["email"], which is the random channel ID. After any reconnect an account's counters start over at zero under a name unrelated to the previous one. I cannot answer "how much quota did this account use this week" at all — the data is not lost, it is just spread across N identities I cannot join together.A restart is indistinguishable from a new account. I get reconnects daily from deploys, browser crashes, and network blips. The provider list accumulates entries I cannot tell apart. When one account starts throwing errors or gets throttled, I have no way to know which Google account it was — the name says nothing, and the logs from before the restart are attached to an identity that no longer exists. That is the part that actually hurts: the one moment I need to trace an account is the moment the identity has been renamed.
Every reconnect pays a full add/delete cycle for nothing. Each connect/disconnect pair runs
handleAuthUpdateson both ends:prepareCoreAuthForModelRegistration, model registration,needsPluginSync,RefreshAPIKeyModelAlias(), plus a persist and a scheduler upsert. A browser reconnecting every few minutes pays that forever, and the identity it just paid to register is discarded on the next disconnect.Proposal
Wire
wsrelay.Options.ProviderFactory. It already exists ininternal/wsrelay/manager.goand is already honored inhandleWebsocket— but nothing in the tree sets it, so it is dead code today. Let a client claim a name on the upgrade request:The
aistudio-prefix is added in the factory when missing, becausewsOnConnectedonly registers channels carrying that prefix. The manager lowercases, as it already does.No new machinery downstream — this reconnects existing behavior:
handleWebsocketalready does last-one-wins replacement per provider key and already cleans up the replaced session with"replaced by new connection".wsOnDisconnectedalready returns early on that reason, so it skips the delete on reconnect. That is the whole mechanism: the auth entry and its counters survive the restart.Compatibility
Strictly additive. No migration, no config, nothing to opt into.
provider_namegets the factory returning"", andhandleWebsocketfalls back torandomProviderName()exactly as today. Same code path, same result. Every existing deployment stays on it.internal/wsrelay/issdk/cliproxy/service_auth.go, and only insideensureWebsocketGateway().internal/wsrelay/is untouched.Trust boundary, stated plainly
Anyone holding a valid
auth_tokencan pick a name, and picking one already in use replaces that session. That is not a new privilege: any valid token can already register a provider and can already replace sessions — it just happens under a random name today. The change makes the display/aggregation identity caller-chosen instead of server-chosen, and nothing else.Verification
Running in production for a week on top of
dev: each browser injects its own account id asprovider_name, the provider list stays stable across restarts, and per-account usage stays on one identity.gofmtclean,go build ./cmd/serverpasses.Not part of this request
Two reconnect races I hit while running this are filed separately. They are ordering bugs in the connect/disconnect path and exist on current
devregardless of whether this lands.All reactions