fix: model discovery, fallback IDs, and conversation context persistence#19
Merged
ephraimduncan merged 1 commit intomainfrom Mar 22, 2026
Merged
Conversation
Three compounding bugs prevented non-composer models from working and caused context loss when switching models or restarting the proxy. Model discovery (h2-bridge.mjs): - callCursorUnaryRpc used streaming mode (application/connect+proto with Connect framing) for the GetUsableModels unary RPC. Cursor expects application/proto with a raw protobuf body. Add unary config flag that switches content-type and writes a single body instead of streaming. Fallback model IDs (models.ts): - Nearly every non-composer ID was wrong: claude-4.6-opus (real: claude-4.6-opus-high), gpt-5.4 (real: gpt-5.4-medium), grok-4.20 (doesn't exist). Corrected against Oh My Pi's maintained registry. Conversation context (proxy.ts): - Split single bridgeKey into two: bridgeKey (model-specific, for active tool-call bridges) and convKey (model-independent, for conversation state). Context now survives model switches within a session. - Make conversationId deterministic from convKey hash instead of crypto.randomUUID(). Same first user message produces the same UUID, so Cursor's server-side conversation persists across proxy restarts.
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.
Three compounding bugs prevented non-composer models from working and caused context loss when switching models or restarting the proxy.
Model discovery (h2-bridge.mjs)
callCursorUnaryRpcused streaming mode (application/connect+protowith Connect framing) for theGetUsableModelsunary RPC. Cursor expectsapplication/protowith a raw protobuf body for unary calls. Discovery silently failed, falling back to hardcoded models.Fix: Add
unaryconfig flag to the H2 bridge that switches content-type and writes a single body instead of streaming.Fallback model IDs (models.ts)
Nearly every non-composer fallback ID was wrong:
claude-4.6-opus(real:claude-4.6-opus-high),gpt-5.4(real:gpt-5.4-medium),grok-4.20(doesn't exist). Onlycomposer-2/composer-2-fasthappened to be valid.Fix: Corrected all IDs against Oh My Pi's maintained model registry.
Conversation context (proxy.ts)
Two issues:
Context lost on model switch: A single
bridgeKey(model-specific) was used for both active tool-call bridges and conversation state. Switching models changed the key, creating a newconversationIdwith no history.Context lost on proxy restart:
conversationIdwascrypto.randomUUID()— ephemeral. After restart, the in-memory map was empty and a new random ID was generated. Cursor's server couldn't match it to the existing conversation.Fix:
bridgeKey(model-specific, foractiveBridges) andconvKey(model-independent, forconversationStates)conversationIddeterministically fromconvKeyhash so Cursor's server-side conversation persists across restartsFixes #17