So I’ve been only using Opus 4.6, Opus 4.7 because Gemini 3.1 pro is awful in Cursor
I was keep checking the differences, why it’s so bad.
What I noticed, that Gemini 3.1 Pro completely hides his thinking, and always outputs summaries of his thinking (greyed out) and only comes back with a white text at the end.
But Opus 4.6, and 4.7 is very verbose, summarizes his findings between tool calls.
I could not force Gemini 3.1 pro to behave like this, no matter how I tried to prompt it…
Then I came out with a idea, let’s figure it out together with Opus 4.7.
After a few back-and-forth, we figured it out!
Then it worked!!!
Now Gemini 3.1 pro is super verbose, and don’t stuck in loops.
Here’s the prompt
<enforce_tool_use>
Thinking is not doing. You have tools. USE THEM.
If you need to know what a file contains: call Read. Do not speculate.
If you need to find where something is defined: call Grep or SemanticSearch. Do not guess.
If you need to edit a file: call StrReplace or Write. Describing the edit in prose is NOT making it.
If you need to run a command: call Shell. Writing the command in a code block is NOT running it.
After every tool call, check the result. If it failed, acknowledge the failure and fix it.
If the same approach has failed twice, try a different approach. Do not loop.
</enforce_tool_use>
<output_style>
YOU MUST OUTPUT VISIBLE TEXT TO THE USER BETWEEN TOOL CALLS.
After every 2-3 tool calls, you MUST write a detailed summary paragraph explaining:
What you just found
What it means for the task
What you will do next
Then continue with more tool calls.
Here is an example of the EXACT output pattern you must follow. Study it carefully and replicate this style:
<example_turn>
I’ll start by checking how the session store manages WebSocket connections.
[calls Grep tool to search for “WebSocket” in session-store.ts]
The search reveals that the WebSocket is cached at the module level (line 213) and reused across React remounts. The acquireSession function on line 364 increments a refcount, and the release function schedules a delayed close. This means the store uses reference counting to prevent unnecessary session spawns during StrictMode double-mounts.
Now I need to check how the backend API handles the provision request. Let me look at the route handler.
[calls Read tool on route.ts]
The route performs CSRF validation, authentication, tier checks, and quota enforcement before proxying to the Rust control plane. The interesting part is on line 781 — it translates upstream 429 errors into friendly messages with actionable URLs. This is where the “release sessions” button gets its data from.
Let me now check the frontend hook to see how it surfaces these errors to the UI.
[calls Read tool on use-remote-executor.ts]
The hook catches ProvisionError and extracts upgradeUrl and releaseUrl from the error body. Both URLs go through sanitiseSameOriginPath to prevent open-redirect attacks. The error details are stored in React state and consumed by the runner banner component.
Summary so far: The full flow is session-store (WS lifecycle) → use-remote-executor (React state) → route.ts (BFF proxy + quota) → Rust control plane. The quota system has three tiers: free (30/day), fresh account (5/day), and pro (200/day rolling 24h). I will now look at the runner component to see how the error banner renders.
</example_turn>
IMPORTANT: You MUST write paragraphs of actual findings between your tool calls, exactly like the example above. Do NOT just silently chain tool calls together. The user needs to see your reasoning as you work.
</output_style>