writing
ChatGPT and Codex Merge, Protocol Changes Again
After ChatGPT and Codex merged, the protocol changed again: tool definitions moved into additional_tools, and third-party models that don't receive tools may fake calls. The author's local gateway AgentGate has adapted, restoring tools and forwarding upstream; the merged desktop client can still point to localhost to call DeepSeek and other models.
Project address: https://github.com/dengmengmian/agentgate-ai
After ChatGPT and Codex merged into one desktop client, many people's first reaction is: the interface changed, the entry point changed.
What I care about is another layer:
The protocol changed again.
Tool definitions are sometimes not in the top-level tools, but stuffed into additional_tools in the input.
If not handled, third-party models won't receive the tool list and can only write fake <tool_call> in the text.
It looks like the model got dumber.
Actually, something in the middle got eaten.
My local gateway AgentGate has kept up: it lifts these tools back and forwards them upstream. The merged desktop client can still point to localhost and continue calling models you've configured, like DeepSeek, MiMo, etc.
This is not another product line. Still the same statement: Model interfaces are configured in AgentGate, and local clients call from the gateway—no matter how the client changes, I try to make this layer hold up.
⸻
Why This Is Worth Mentioning First
I've written before: I like using Codex, want to use DeepSeek, but the protocol doesn't connect, so I made a local gateway. That was the first hurdle: connecting.
When the client merges and changes the protocol, those who already connected are most likely to stumble again. Lost tools, fake calls, spending ages debugging thinking the model is bad—these pitfalls will pop up in clusters.
So this article first explains the merged version clearly. Later, I'll talk about: after connecting, how I gather multiple models into one entry point to reduce manual switching.
⸻
What I Really Want Has Never Changed
The more I do this, the clearer it becomes: the original intention is not to "make an abstract AI gateway concept."
It's:
All model interfaces are configured in AgentGate. Local tasks—Codex, the merged ChatGPT desktop client, Claude Code, or others—can all call from this one entry point.
The starting point was Codex + DeepSeek. When DeepSeek doesn't support images, requests with images automatically go to KimiCoding. The merged version changed the protocol, and the gateway kept up. Manual model switching is too annoying, so multiple models stand by in the router.
One line, not scattered efforts.
⸻
The Gateway Is Connected, but Hands Are Still Busy
After connecting, the second annoyance quickly appears.
When writing code with DeepSeek, when the quota gets tight, I want to switch. Automatic switching for images is smooth. But there are also background tasks, backup sites, and occasionally wanting to try other models...
Every additional model adds one more decision of "who to enable now." Either click to switch. Or change configuration. Or stop mid-task and think: which one should I use this time?
The problem sounds small. For someone like me who has agents running all day writing code, it's very real. I don't want to be pulled away from code just to switch models.
So what AgentGate later focused on is the routing side: The client only connects to one local address. Multiple models stand by in the gateway and take tasks according to rules.
⸻
Multiple at Once, Not Greed
Let me clarify: it's not about talking to ten models simultaneously in one chat window. It's about multiple model capabilities standing by in the router at the same time.
This shot uses A. The next might use B. Try C if needed. No need to click "enable" again.
The common approach is "enable one set at a time": Enable DeepSeek → write for a while → hit quota, click backup → need images, switch to vision...
AgentGate is:
The client applies once, pointing to 127.0.0.1:9090.
Then attach primary, backup, image conditions, small task conditions.
With images, model names like haiku, 429 / 5xx, follow the rules.
In the logs, you can see who was used for this shot.
You can also attach multiple keys from the same provider: use them in rotation, and if one key hits 429, automatically switch to the next.
Multiple models mean multiple providers standing by; multiple keys mean multiple lives within the same provider—spreading quota and reducing stops during rate limits.
I remember it this way:
- Configuration switching answers "who to enable now."
- The gateway answers "who should be used for this shot, and who to switch to if it fails."
Some people use tools like CC Switch to switch providers with one click, which is also great and solves how to switch configuration quickly. What I want to solve more is the next step: after the client points to localhost, how multiple models stand by in the router to reduce manual switching.
The two don't conflict; if needed, you can stack them—just point the switching tool to 127.0.0.1:9090.
Image Image
This is the same line as the original intention: All interfaces are collected in the local gateway. Text can prioritize DeepSeek. Images can go to KimiCoding. Failures can go through the provider chain. Small tasks can be distributed. The merged desktop client still points to this one place.
It wasn't a "multi-model platform" planned from the start. It grew out of usage—first connecting, then keeping up with the merged version, then reducing manual switching.
⸻
Smart Switching Isn't for Showing Off
What really affects efficiency in AI coding is often not a few seconds faster on a response. It's: can it stably support you working continuously.
Suddenly rate-limited. Suddenly 5xx. Suddenly this model doesn't accept images. Suddenly you have to stop and switch configuration. Suddenly the merged version loses all tools.
These interruptions hurt more than being a few seconds slower.
So routing, failover, and merged version adaptation are not checkbox items on a feature list for me. They're to reduce interruptions.
- If transparent proxying works, don't force conversion.
- Only convert when necessary.
- If a provider doesn't support vision, automatically let it step aside, so users don't have to judge manually.
The principle remains:
Tools should stand in front to shield complexity, not create new complexity.
⸻
Full Input/Output Logs for My Development
When connecting third-party models, the most annoying thing isn't the words "can't connect." It's when you can't connect, you don't know where it's stuck.
What did the client send out?
What did the gateway convert and send upstream?
What did upstream return?
Were tool fields lost? Was the model name mapping correct?
Did the merged version's additional_tools get lifted up?
Without full logs, you can only guess. Guess, change config, guess again—development rhythm gets shattered.
So AgentGate leaves request-level logs locally: Input, output, and before/after conversion, with sensitive data masked. When problems arise, I check logs first, look at raw / converted, which is much faster than going back and forth between client and upstream.
This is a must-have for me to write code, connect new providers, and debug merged version protocol pitfalls. It's not for a pretty dashboard; it's to reduce blind guessing.
⸻
Also Made a Desktop Pet
Gateway, logs, routing—these all seem "console-like." After using it for a while, there's a very real problem: The gateway is running, requests are flowing, how much spent today—I might not always want to stare at a panel.
So later I added a desktop pet.
It's not the main course. Nor is it meant to be a second product. It's just a lightweight presence next to the local gateway: When Claude Code is working, it reacts. It jumps more when busy, and calms down when idle. If today's spending is high, it looks a bit "stuffed."
It can also chat; when the gateway is connected, it uses real models to reply, otherwise it falls back to local text. It can remember some chat preferences, and you can edit memory in the page.
These capabilities still go through the same local gateway—not another cloud service.
The pet doesn't replace logs or routing configuration. It just makes "this machine is always running" less dry. I continue writing code, and I can glance at its status from the corner of my eye.
⸻
Boundaries Must Be Kept
The boundary isn't "I'm not Codex." Codex, the merged ChatGPT desktop client, Claude Code, OpenCode—they should do what they do.
What I want to keep is the other side: Model interfaces are configured in only one place—AgentGate. Local tasks call from this one place arbitrarily. Keys, routing, mapping, logs are all in the local gateway. When clients upgrade, merge, or change protocols, I try to let the gateway catch it, rather than laying out another set of providers in each tool.
- No new IDE.
- No cloud relay station.
- The pet doesn't connect to another cloud; it still goes through the same entry.
If boundaries aren't clear, things get heavier and heavier.
So the positioning remains restrained:
Local entry. Interface consolidation. Multiple models standing by. Full logs visible. Client updates, gateway tries to keep up.
⸻
How I Use It Myself
After installation, roughly:
- Paste keys for each provider in the provider section (configure all that can be called; multiple keys for the same provider are fine)
- Start the gateway
- Set primary, backup, and conditions in the router
- Local clients (including the merged desktop client) apply to localhost
- Send a few different scenarios, check logs to see who was used—especially whether tools are still there
If Windows SmartScreen blocks it: More info → Run anyway. This is common for open-source unsigned installers, not a virus popup.
Who it's not for, I'll say directly:
- If you only ever use one official model and never switch—you don't need to install.
- If you need team billing or multi-tenancy—look at LiteLLM / new-api or similar.
- If you just want to switch relay configurations with one click—dedicated switching tools are lighter; only come to AgentGate if you really want to consolidate multiple providers into one local entry.
⸻
Final Thoughts
For me, AgentGate still didn't start from a grand concept.
At first it was just: I like using Codex, but I want to use DeepSeek.
Later it became clearer that what I really want is:
All model interfaces configured in AgentGate, local tasks called arbitrarily.
So it grew along the way:
- DeepSeek doesn't support images, so image requests automatically go to KimiCoding.
- Manual model switching is too annoying, so multiple models stand by in the router.
- Multiple keys for the same provider, switch on 429.
- ChatGPT and Codex merged, protocol changed again, gateway kept up.
- Problems hard to debug, so made full input/output logs (including before/after conversion).
- The machine runs all the time, so made a desktop pet to glance at status.
It may not be complex. But it solves problems I really encounter every day.
For those who just switched to the merged version, if third-party models "suddenly can't use tools"—don't rush to blame the model. It might be that the protocol got eaten. Try passing the request through the local gateway first.
If you want to try: https://github.com/dengmengmian/agentgate-ai