ai-switch-cli 0.3.2__tar.gz → 0.5.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ai-switch-cli
3
- Version: 0.3.2
3
+ Version: 0.5.0
4
4
  Summary: One-command provider and model switching for Claude Code and Codex, with session-history checks
5
5
  Author: ZidongS
6
6
  License: MIT
@@ -84,12 +84,26 @@ default for new sessions is the one you last used, or the profile default. Add `
84
84
  asked, or `-m/--model` to set the default directly.
85
85
 
86
86
  ```text
87
- Active profile: glm
88
- Default model: glm-5.3 (new sessions)
89
- Published models: 3 - switch any time with /model inside codex (Claude Code uses its
90
- Opus/Sonnet/Haiku mappings), or change the default with -m/--model.
87
+ ⠸ ▰▰▰▰▰▰▱▱▱▱▱▱▱▱▱▱ 38% 2/5 writing ~/.codex/models.json
88
+ ✓ ▰▰▰▰▰▰▰▰▰▰▰▰▱▱▱▱ 75% 4/5 write ~/.codex/models.json 3 model(s)
89
+ ✓ ▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰ 100% 5/5 save profile state glm is now the active profile
90
+ ╭──────────────────────────────────────────────────────────╮
91
+ │ ✦ glm is active (0.73s) │
92
+ ├──────────────────────────────────────────────────────────┤
93
+ │ profile glm │
94
+ │ default glm-5.3 │
95
+ │ models 3 published · switch inside codex with /model │
96
+ │ backup ~/.config/ai-switch/backups/20260915-203657 │
97
+ │ next restart claude/codex to reload │
98
+ ╰──────────────────────────────────────────────────────────╯
91
99
  ```
92
100
 
101
+ The bar is a colour ramp (cyan → green) with a bright leading edge and it always finishes completely
102
+ filled at 100%, followed by a short sweep as the closing flourish.
103
+
104
+ The progress animation needs a terminal — piped output, `TERM=dumb`, `--plain` and `--no-color` keep the
105
+ plain one-line-per-action form (handy for scripts). `NO_COLOR=1` mutes the colours but keeps the spinner.
106
+
93
107
  With `--choose` you get the picker instead:
94
108
 
95
109
  ```text
@@ -132,7 +146,25 @@ Update an existing profile description:
132
146
  ai-switch describe default "Default daily configuration"
133
147
  ```
134
148
 
135
- `list` shows the active marker, profile name, configured clients, description, detected models, and endpoint hostnames. API keys are never printed.
149
+ `list` shows the active marker, profile name, configured clients, description, detected models, and endpoint hostnames. `current` prints a panel of **every** profile with its models, the default one (★), the endpoint and — for the active profile — whether the live agent configuration still matches:
150
+
151
+ ```text
152
+ ai-switch · 4 profile(s) · ~/.config/ai-switch
153
+ ────────────────────────────────────────────────────────────────────
154
+ ○ glm glm-coding-plan
155
+ Codex glm-5.3 · 3 models
156
+ Claude glm-5.3 · 2 Claude category mappings
157
+ host open.bigmodel.cn
158
+ models glm-5.3 ★, glm-5.3-flash, glm-5-turbo
159
+
160
+ ● paratera custom paratera active
161
+ Codex DeepSeek-V4.1-Flash · 31 models
162
+ Claude DeepSeek-V4.1-Flash · opus/sonnet/haiku → DeepSeek-V4.1-Flash
163
+ host llmapi.paratera.com
164
+ models DeepSeek-V4.1-Flash ★, DeepSeek-V4-Pro, …, MiniMax-Text-01
165
+ ```
166
+
167
+ Use `current --plain` to print just the active profile name. API keys are never printed.
136
168
 
137
169
  ## Choosing a model
138
170
 
@@ -170,6 +202,32 @@ ai-switch use deepseek -m deepseek-flash
170
202
 
171
203
  Model suffixes are proxy-specific: DeepSeek's Claude endpoint accepts and strips a `[1m]` marker (`deepseek-v4-pro[1m]`), while ZAI rejects it as an unknown model — `glm-5.3` is already 1M context and must be used without a suffix. Worth a one-token request before trusting a name in a profile.
172
204
 
205
+ ## Gateways that break Codex's tool calls
206
+
207
+ Codex 0.154 records an assistant `message` item **between** a turn's tool calls and their results — the text it said before calling the tools, or an empty string when it said nothing. That is valid in the Responses API, but a gateway that translates Responses into Chat completions emits it as its own chat message, which leaves the `tool_calls` message without the `tool` messages that must follow it directly. The next request is then rejected and the session dies:
208
+
209
+ ```text
210
+ OpenAIException - The request is invalid: An assistant message with 'tool_calls' must be
211
+ followed by tool messages responding to each 'tool_call_id'. (insufficient tool messages
212
+ following tool_calls message)
213
+ ```
214
+
215
+ Paratera (`llmapi.paratera.com`) does this. Claude Code is unaffected, because it speaks the Anthropic API rather than the Responses API — only Codex hits the translation.
216
+
217
+ For such a profile, `ai-switch use` starts a small local proxy that moves that message back in front of the calls, points Codex at it, and stops it again when you activate a profile that does not need it:
218
+
219
+ ```text
220
+ Note: Codex will use the llmapi.paratera.com patch proxy on 127.0.0.1:8791
221
+ (Paratera translates Responses into Chat completions and splits a turn's tool calls from their results).
222
+ ```
223
+
224
+ * The profile keeps the provider's real endpoint. Only the live `~/.codex/config.toml` is repointed, and only Codex's own configuration — Claude Code still talks to the provider directly.
225
+ * The proxy listens on `127.0.0.1` only, forwards your key and your request body untouched apart from the item order, and logs counts and status codes (never keys, prompts or answers) to `~/.config/ai-switch/patch.log`.
226
+ * If the process dies (a reboot, a kill), Codex cannot reach its endpoint. `ai-switch doctor` reports it and `ai-switch use NAME` starts it again. `ai-switch current` shows whether it is up.
227
+ * Nothing here is needed once the gateway's translation is fixed: `ai-switch use NAME --no-patch` activates the profile without the proxy and stops it if it is running.
228
+
229
+ This is a workaround for the gateway, not a fix — the rewriting is deliberately narrow (only a completed `calls + message + results` turn, only on `/responses`), and anything else is forwarded byte for byte.
230
+
173
231
  ## Session history
174
232
 
175
233
  Conversation history belongs to the agents, not to a provider, so ai-switch never manages it. These files are deliberately excluded from profiles and switches:
@@ -204,7 +262,7 @@ ai-switch doctor --fix # quarantine damaged Codex runtime databases
204
262
 
205
263
  ## Safety and storage
206
264
 
207
- Before activation, the current Codex and Claude files are backed up under `~/.config/ai-switch/backups/<timestamp>/` (files that a switch removes are kept under `removed/`). Profiles are stored under `~/.config/ai-switch/profiles/`; directories use mode 700 and files use mode 600. The active profile and the last used model are recorded in `~/.config/ai-switch/state.json`. Restart `claude` or `codex` after switching so the process reloads its configuration.
265
+ Before activation, the current Codex and Claude files are backed up under `~/.config/ai-switch/backups/<timestamp>/` (files that a switch removes are kept under `removed/`). Profiles are stored under `~/.config/ai-switch/profiles/`; directories use mode 700 and files use mode 600. The active profile, the last used model and the running gateway patch proxy (pid, port, endpoint) are recorded in `~/.config/ai-switch/state.json`; that proxy's log is `~/.config/ai-switch/patch.log`. Restart `claude` or `codex` after switching so the process reloads its configuration.
208
266
 
209
267
  Set `AI_SWITCH_HOME` to use a different profile directory, `CODEX_HOME`/`CLAUDE_CONFIG_DIR` for relocated agent configurations, and `AI_SWITCH_API_KEY` to fill the API key prompt non-interactively.
210
268
 
@@ -213,9 +271,10 @@ Set `AI_SWITCH_HOME` to use a different profile directory, `CODEX_HOME`/`CLAUDE_
213
271
  ```text
214
272
  ai-switch init NAME [-d DESCRIPTION] Save current files as a new profile
215
273
  ai-switch list List profiles and configuration summaries
216
- ai-switch use NAME [-m MODEL] [-y] [-n] Back up and activate a profile (and a model)
274
+ ai-switch use NAME [-m MODEL] [--choose] [--pin] [--plain] [--no-patch]
275
+ Back up and activate a profile (animated, -m sets the default)
217
276
  ai-switch models [NAME] [--json] Show the models a profile offers
218
- ai-switch current Print the active profile
277
+ ai-switch current [-p] Show every profile, its models and the live state (-p: name only)
219
278
  ai-switch describe NAME TEXT Set a profile description
220
279
  ai-switch upgrade NAME Derive models.json for a profile from an older release
221
280
  ai-switch add Create a profile interactively (GLM, DeepSeek, or custom)
@@ -70,12 +70,26 @@ default for new sessions is the one you last used, or the profile default. Add `
70
70
  asked, or `-m/--model` to set the default directly.
71
71
 
72
72
  ```text
73
- Active profile: glm
74
- Default model: glm-5.3 (new sessions)
75
- Published models: 3 - switch any time with /model inside codex (Claude Code uses its
76
- Opus/Sonnet/Haiku mappings), or change the default with -m/--model.
73
+ ⠸ ▰▰▰▰▰▰▱▱▱▱▱▱▱▱▱▱ 38% 2/5 writing ~/.codex/models.json
74
+ ✓ ▰▰▰▰▰▰▰▰▰▰▰▰▱▱▱▱ 75% 4/5 write ~/.codex/models.json 3 model(s)
75
+ ✓ ▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰▰ 100% 5/5 save profile state glm is now the active profile
76
+ ╭──────────────────────────────────────────────────────────╮
77
+ │ ✦ glm is active (0.73s) │
78
+ ├──────────────────────────────────────────────────────────┤
79
+ │ profile glm │
80
+ │ default glm-5.3 │
81
+ │ models 3 published · switch inside codex with /model │
82
+ │ backup ~/.config/ai-switch/backups/20260915-203657 │
83
+ │ next restart claude/codex to reload │
84
+ ╰──────────────────────────────────────────────────────────╯
77
85
  ```
78
86
 
87
+ The bar is a colour ramp (cyan → green) with a bright leading edge and it always finishes completely
88
+ filled at 100%, followed by a short sweep as the closing flourish.
89
+
90
+ The progress animation needs a terminal — piped output, `TERM=dumb`, `--plain` and `--no-color` keep the
91
+ plain one-line-per-action form (handy for scripts). `NO_COLOR=1` mutes the colours but keeps the spinner.
92
+
79
93
  With `--choose` you get the picker instead:
80
94
 
81
95
  ```text
@@ -118,7 +132,25 @@ Update an existing profile description:
118
132
  ai-switch describe default "Default daily configuration"
119
133
  ```
120
134
 
121
- `list` shows the active marker, profile name, configured clients, description, detected models, and endpoint hostnames. API keys are never printed.
135
+ `list` shows the active marker, profile name, configured clients, description, detected models, and endpoint hostnames. `current` prints a panel of **every** profile with its models, the default one (★), the endpoint and — for the active profile — whether the live agent configuration still matches:
136
+
137
+ ```text
138
+ ai-switch · 4 profile(s) · ~/.config/ai-switch
139
+ ────────────────────────────────────────────────────────────────────
140
+ ○ glm glm-coding-plan
141
+ Codex glm-5.3 · 3 models
142
+ Claude glm-5.3 · 2 Claude category mappings
143
+ host open.bigmodel.cn
144
+ models glm-5.3 ★, glm-5.3-flash, glm-5-turbo
145
+
146
+ ● paratera custom paratera active
147
+ Codex DeepSeek-V4.1-Flash · 31 models
148
+ Claude DeepSeek-V4.1-Flash · opus/sonnet/haiku → DeepSeek-V4.1-Flash
149
+ host llmapi.paratera.com
150
+ models DeepSeek-V4.1-Flash ★, DeepSeek-V4-Pro, …, MiniMax-Text-01
151
+ ```
152
+
153
+ Use `current --plain` to print just the active profile name. API keys are never printed.
122
154
 
123
155
  ## Choosing a model
124
156
 
@@ -156,6 +188,32 @@ ai-switch use deepseek -m deepseek-flash
156
188
 
157
189
  Model suffixes are proxy-specific: DeepSeek's Claude endpoint accepts and strips a `[1m]` marker (`deepseek-v4-pro[1m]`), while ZAI rejects it as an unknown model — `glm-5.3` is already 1M context and must be used without a suffix. Worth a one-token request before trusting a name in a profile.
158
190
 
191
+ ## Gateways that break Codex's tool calls
192
+
193
+ Codex 0.154 records an assistant `message` item **between** a turn's tool calls and their results — the text it said before calling the tools, or an empty string when it said nothing. That is valid in the Responses API, but a gateway that translates Responses into Chat completions emits it as its own chat message, which leaves the `tool_calls` message without the `tool` messages that must follow it directly. The next request is then rejected and the session dies:
194
+
195
+ ```text
196
+ OpenAIException - The request is invalid: An assistant message with 'tool_calls' must be
197
+ followed by tool messages responding to each 'tool_call_id'. (insufficient tool messages
198
+ following tool_calls message)
199
+ ```
200
+
201
+ Paratera (`llmapi.paratera.com`) does this. Claude Code is unaffected, because it speaks the Anthropic API rather than the Responses API — only Codex hits the translation.
202
+
203
+ For such a profile, `ai-switch use` starts a small local proxy that moves that message back in front of the calls, points Codex at it, and stops it again when you activate a profile that does not need it:
204
+
205
+ ```text
206
+ Note: Codex will use the llmapi.paratera.com patch proxy on 127.0.0.1:8791
207
+ (Paratera translates Responses into Chat completions and splits a turn's tool calls from their results).
208
+ ```
209
+
210
+ * The profile keeps the provider's real endpoint. Only the live `~/.codex/config.toml` is repointed, and only Codex's own configuration — Claude Code still talks to the provider directly.
211
+ * The proxy listens on `127.0.0.1` only, forwards your key and your request body untouched apart from the item order, and logs counts and status codes (never keys, prompts or answers) to `~/.config/ai-switch/patch.log`.
212
+ * If the process dies (a reboot, a kill), Codex cannot reach its endpoint. `ai-switch doctor` reports it and `ai-switch use NAME` starts it again. `ai-switch current` shows whether it is up.
213
+ * Nothing here is needed once the gateway's translation is fixed: `ai-switch use NAME --no-patch` activates the profile without the proxy and stops it if it is running.
214
+
215
+ This is a workaround for the gateway, not a fix — the rewriting is deliberately narrow (only a completed `calls + message + results` turn, only on `/responses`), and anything else is forwarded byte for byte.
216
+
159
217
  ## Session history
160
218
 
161
219
  Conversation history belongs to the agents, not to a provider, so ai-switch never manages it. These files are deliberately excluded from profiles and switches:
@@ -190,7 +248,7 @@ ai-switch doctor --fix # quarantine damaged Codex runtime databases
190
248
 
191
249
  ## Safety and storage
192
250
 
193
- Before activation, the current Codex and Claude files are backed up under `~/.config/ai-switch/backups/<timestamp>/` (files that a switch removes are kept under `removed/`). Profiles are stored under `~/.config/ai-switch/profiles/`; directories use mode 700 and files use mode 600. The active profile and the last used model are recorded in `~/.config/ai-switch/state.json`. Restart `claude` or `codex` after switching so the process reloads its configuration.
251
+ Before activation, the current Codex and Claude files are backed up under `~/.config/ai-switch/backups/<timestamp>/` (files that a switch removes are kept under `removed/`). Profiles are stored under `~/.config/ai-switch/profiles/`; directories use mode 700 and files use mode 600. The active profile, the last used model and the running gateway patch proxy (pid, port, endpoint) are recorded in `~/.config/ai-switch/state.json`; that proxy's log is `~/.config/ai-switch/patch.log`. Restart `claude` or `codex` after switching so the process reloads its configuration.
194
252
 
195
253
  Set `AI_SWITCH_HOME` to use a different profile directory, `CODEX_HOME`/`CLAUDE_CONFIG_DIR` for relocated agent configurations, and `AI_SWITCH_API_KEY` to fill the API key prompt non-interactively.
196
254
 
@@ -199,9 +257,10 @@ Set `AI_SWITCH_HOME` to use a different profile directory, `CODEX_HOME`/`CLAUDE_
199
257
  ```text
200
258
  ai-switch init NAME [-d DESCRIPTION] Save current files as a new profile
201
259
  ai-switch list List profiles and configuration summaries
202
- ai-switch use NAME [-m MODEL] [-y] [-n] Back up and activate a profile (and a model)
260
+ ai-switch use NAME [-m MODEL] [--choose] [--pin] [--plain] [--no-patch]
261
+ Back up and activate a profile (animated, -m sets the default)
203
262
  ai-switch models [NAME] [--json] Show the models a profile offers
204
- ai-switch current Print the active profile
263
+ ai-switch current [-p] Show every profile, its models and the live state (-p: name only)
205
264
  ai-switch describe NAME TEXT Set a profile description
206
265
  ai-switch upgrade NAME Derive models.json for a profile from an older release
207
266
  ai-switch add Create a profile interactively (GLM, DeepSeek, or custom)