A 502 After One Tool Call
On September 28, testing the phone app against production, a mission on Gemini 3.8 Flash read a file and then stopped: the model connection had ended the turn. The first call to Gemini had worked. The second, the one that carried the result of the tool, came back from Google as 400, with the least helpful message an API can send: the request contains an invalid argument. The same failure had happened once two days earlier.
Gemini 3 has a strict rule for tool calls. Every call it makes carries a signature over its own reasoning, and the next request has to hand that signature back unchanged. That was the obvious suspect, and it was wrong. Skyflo already stored and returned the signatures. The request that failed contained the signed call exactly as Gemini had issued it. It also contained the same call a second time.
One Message, Two Names
A mission on an included model keeps its own record of the conversation, because the provider keeps nothing between calls. After each call, the Mac stores what the model returned. When it builds the next request, it walks its transcript and adds whatever is not stored yet, and it recognises a message as stored by its name.
The Mac chose that name once when it reserved the model for a step, and once more when the step began. In between, the step moved to waiting for the model, which is itself an event in the mission's history, and the name comes from the latest event. So the stored reply and the transcript's copy of it never matched. Every tool call went out twice: once as the model issued it, and once rebuilt from the transcript, without Gemini's signature and under Skyflo's internal tool name, file.search where the model had said file_search. Every earlier answer went out twice as well.
Three Providers, Three Answers
OpenAI refused the request, because a tool name with a dot in it is not a name it accepts. On the included OpenAI models, every mission stopped the first time the agent needed another step after using a tool. Gemini refused it too, because a call it made once cannot be answered as two. Z.ai accepted it and counted it: on the shipped 1.4.4 build, the same Z.ai step uses 11,041 input tokens where 1.4.3 used 11,790.
Gemini also taught us something about duplicates that do not fail. With its previous answer present twice in the conversation, it wrote its next answer twice, in 12 of 12 trials of the same request. With the copy removed, it did so in none. A model reads the whole conversation as a pattern to continue, including the parts nobody meant to write.
The quiet provider was the expensive one. A refusal is a bug report; an accepted duplicate is a bill and a subtly worse answer.
State Belongs to Whoever Issued It
Fixing the copy exposed a second fault of the same kind. Auto chooses a model for each step, so a mission can move between providers, and each provider leaves opaque state in the conversation for itself: Gemini its signatures, OpenAI its encrypted reasoning. Skyflo replayed all of it to whichever provider came next. OpenAI refused Gemini's signatures as unknown, and Gemini refused OpenAI's reasoning as a corrupted signature, so a mission that switched providers could not continue.
Each provider now receives only the state it issued, and the rest stays in the conversation for when that provider is chosen again. We checked both directions against the providers themselves: a Gemini conversation with tool calls continued on an OpenAI model, and then back on Gemini.
What Changes for You
Skyflo updates itself to 1.4.4. Conversations started before it are repaired as they continue: the earlier copies stay stored on your Mac and are no longer sent. The server side of the fix, including moving between providers, applies to every version already.
The 1.2 essay said the models came with a paid plan, with no key of your own to bring. That promise is only as good as the conversation Skyflo hands them. Every earlier test of this lane passed, because each built both names the same way. It took real missions, on every provider, to see that the model had been reading everything twice. The 1.4.4 release notes list the changes.