ai-switch-cli 0.1.2__tar.gz → 0.2.2__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.
- ai_switch_cli-0.2.2/PKG-INFO +220 -0
- ai_switch_cli-0.2.2/README.md +206 -0
- ai_switch_cli-0.2.2/ai_switch.py +1341 -0
- ai_switch_cli-0.2.2/ai_switch_cli.egg-info/PKG-INFO +220 -0
- {ai_switch_cli-0.1.2 → ai_switch_cli-0.2.2}/pyproject.toml +3 -3
- ai_switch_cli-0.1.2/PKG-INFO +0 -124
- ai_switch_cli-0.1.2/README.md +0 -110
- ai_switch_cli-0.1.2/ai_switch.py +0 -182
- ai_switch_cli-0.1.2/ai_switch_cli.egg-info/PKG-INFO +0 -124
- {ai_switch_cli-0.1.2 → ai_switch_cli-0.2.2}/ai_switch_cli.egg-info/SOURCES.txt +0 -0
- {ai_switch_cli-0.1.2 → ai_switch_cli-0.2.2}/ai_switch_cli.egg-info/dependency_links.txt +0 -0
- {ai_switch_cli-0.1.2 → ai_switch_cli-0.2.2}/ai_switch_cli.egg-info/entry_points.txt +0 -0
- {ai_switch_cli-0.1.2 → ai_switch_cli-0.2.2}/ai_switch_cli.egg-info/top_level.txt +0 -0
- {ai_switch_cli-0.1.2 → ai_switch_cli-0.2.2}/setup.cfg +0 -0
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: ai-switch-cli
|
|
3
|
+
Version: 0.2.2
|
|
4
|
+
Summary: One-command provider and model switching for Claude Code and Codex, with session-history checks
|
|
5
|
+
Author: ZidongS
|
|
6
|
+
License: MIT
|
|
7
|
+
Keywords: codex,claude-code,api,profile,cli,model-switching
|
|
8
|
+
Classifier: Environment :: Console
|
|
9
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
10
|
+
Classifier: Operating System :: POSIX
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Requires-Python: >=3.9
|
|
13
|
+
Description-Content-Type: text/markdown
|
|
14
|
+
|
|
15
|
+
# ai-switch
|
|
16
|
+
|
|
17
|
+
## The problem it solves
|
|
18
|
+
|
|
19
|
+
When you use multiple coding agents and multiple model providers, changing providers separately in Claude Code and Codex is repetitive and error-prone. **ai-switch updates both agents in one command.**
|
|
20
|
+
|
|
21
|
+
Choose a provider profile once, then activate it with `ai-switch use NAME`. The built-in GLM and DeepSeek presets already contain the provider-specific files, endpoints, protocols, model catalogs, and Claude Code mappings recommended by their official documentation. You only need to enter your API key. Custom OpenAI-compatible providers are supported too.
|
|
22
|
+
|
|
23
|
+
A profile can offer several models (for example GLM 5.3 and GLM 5.3 Flash, or DeepSeek Flash and DeepSeek V4 Pro). `ai-switch use` asks which one to activate and writes the answer to both agents, so the model pickers *inside* Claude Code and Codex keep working instead of being pinned to a single model.
|
|
24
|
+
|
|
25
|
+
Switching also leaves conversation history alone: sessions, rollouts, `history.jsonl` and the agents' runtime databases are never copied into a profile or overwritten by a switch, and `ai-switch doctor` reports the things that really do make old sessions disappear.
|
|
26
|
+
|
|
27
|
+
This is a secure, headless-friendly command-line tool for servers without a desktop environment or administrator privileges.
|
|
28
|
+
|
|
29
|
+
## Install
|
|
30
|
+
|
|
31
|
+
Install from PyPI (recommended):
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
python3 -m pip install --user ai-switch-cli
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
For a system or virtual-environment install:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
pip install ai-switch-cli
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Install the latest development version directly from GitHub:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
python3 -m pip install --user "git+https://github.com/ZidongS/ai-switch.git"
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Or install a local checkout:
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
python3 -m pip install --user .
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
If `ai-switch` is not found afterwards, add the user script directory to `PATH`:
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
export PATH="$HOME/.local/bin:$PATH"
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Quick start
|
|
62
|
+
|
|
63
|
+
Save the configuration currently in use as a fallback profile:
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
ai-switch init default --description "Default daily configuration"
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Create a ready-to-use mainstream provider profile interactively:
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
ai-switch add
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Select `glm` or `deepseek`, enter the API key, and activate the generated configuration:
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
ai-switch use glm
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
`use` lists the models the profile offers and remembers your choice:
|
|
82
|
+
|
|
83
|
+
```text
|
|
84
|
+
This profile provides 2 models:
|
|
85
|
+
1) glm-5.3 GLM-5.3 flagship (1M context) [default]
|
|
86
|
+
2) glm-5.3-flash GLM-5.3 flash (fast, 1M context)
|
|
87
|
+
Select model [1-2, Enter=glm-5.3, q=cancel]:
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
For scripts and servers, choose without prompting (name, unique prefix, or index):
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
ai-switch use glm --model glm-5.3-flash
|
|
94
|
+
ai-switch use glm -m 2 -y
|
|
95
|
+
ai-switch use glm --dry-run # show what would change
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
Edit `~/.codex/config.toml` and `~/.claude/settings.json` for another provider, then save that configuration as a second profile:
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
ai-switch init glm --description "GLM Coding Plan"
|
|
102
|
+
ai-switch list
|
|
103
|
+
ai-switch use glm
|
|
104
|
+
ai-switch current
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Create a profile through an interactive prompt (no editor required; API keys are hidden while typing). Choose the built-in `glm` preset to generate the complete ZAI Codex Responses configuration, Codex model catalog and Claude Code model/environment mappings for the three models the endpoint publishes (`glm-5.3`, `glm-5.3-flash`, `glm-5-turbo`) automatically. The `deepseek` preset creates the two model entries the DeepSeek endpoint currently accepts (`deepseek-flash` and `deepseek-v4-pro`, both with image input metadata) plus the recommended Claude Code mappings:
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
ai-switch add
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
Update an existing profile description:
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
ai-switch describe default "Default daily configuration"
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
`list` shows the active marker, profile name, configured clients, description, detected models, and endpoint hostnames. API keys are never printed.
|
|
120
|
+
|
|
121
|
+
## Choosing a model
|
|
122
|
+
|
|
123
|
+
Each profile keeps its model list in `models.json` next to the client files:
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
ai-switch models # list the models of the active profile
|
|
127
|
+
ai-switch models glm --json # machine readable
|
|
128
|
+
ai-switch upgrade glm # derive models.json for a profile from an older release
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
For every model a profile records the Codex catalogue entry and the Claude Code mapping, so activating one model updates all of these consistently:
|
|
132
|
+
|
|
133
|
+
* Codex: the top-level `model` (and `model_reasoning_effort`), plus a `~/.codex/models.json` catalogue that lists **every** model of the profile, which is what makes Codex's own `/model` picker show them.
|
|
134
|
+
* Claude Code: the default model in `settings.json` plus the Opus/Sonnet/Haiku mappings. The presets map the three categories to *different* provider models where they exist, and they never set `ANTHROPIC_MODEL`, because a pinned environment model overrides your selection and makes `/model` do nothing.
|
|
135
|
+
|
|
136
|
+
The `glm` and `deepseek` presets ship multi-model lists. A custom (OpenAI-compatible) profile is open-ended: it does not publish a catalogue, and `ai-switch use NAME --model anything` accepts any model name the endpoint serves.
|
|
137
|
+
|
|
138
|
+
### When a provider adds or renames a model
|
|
139
|
+
|
|
140
|
+
Model names change, and an endpoint refuses a name it does not know. Ask the provider what your key may use:
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
curl -s https://api.deepseek.com/models -H "Authorization: Bearer $KEY" # OpenAI-style list
|
|
144
|
+
curl -s https://open.bigmodel.cn/api/v1/models -H "Authorization: Bearer $KEY" # Codex-format catalogue
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
A rejected name is also reported in the API error itself (*"The supported API model names are ..."*, or `模型不存在,请检查模型代码。`). Some providers publish their Codex catalogue directly (`/api/v1/models` on ZAI returns exactly the entries a profile's `codex-models.json` wants), so it can be copied verbatim. Historically DeepSeek answered to `deepseek-v4-flash` and `deepseek-v4-flash-vision-exp`; today those are aliases that the endpoint resolves to `deepseek-flash`.
|
|
148
|
+
|
|
149
|
+
To add a model, append it to the profile's `models.json` — the `claude` mapping decides what Opus/Sonnet/Haiku resolve to, the `codex` entry controls whether Codex's own picker offers it. Keep the entries of names that older sessions were recorded with in the Codex catalogue so those sessions stay resumable, then activate:
|
|
150
|
+
|
|
151
|
+
```bash
|
|
152
|
+
ai-switch use deepseek -m deepseek-flash
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
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.
|
|
156
|
+
|
|
157
|
+
## Session history
|
|
158
|
+
|
|
159
|
+
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:
|
|
160
|
+
|
|
161
|
+
```text
|
|
162
|
+
~/.codex/history.jsonl, ~/.codex/session_index.jsonl, ~/.codex/sessions/,
|
|
163
|
+
~/.codex/*_N.sqlite (runtime state, logs, goals, memories)
|
|
164
|
+
~/.claude.json, ~/.claude/history.jsonl, ~/.claude/projects/, ~/.claude/sessions/
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
If sessions do seem to disappear after a switch, run:
|
|
168
|
+
|
|
169
|
+
```bash
|
|
170
|
+
ai-switch doctor # full report; --json for tooling
|
|
171
|
+
ai-switch doctor --fix # quarantine damaged Codex runtime databases
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
`doctor` checks, among other things:
|
|
175
|
+
|
|
176
|
+
* **Damaged SQLite runtime databases.** Codex keeps thread metadata in `~/.codex/state_*.sqlite` and `thread_history_1.sqlite`. When one is damaged (typical messages: `database disk image is malformed`, `file is not a database`) Codex silently stops listing recent sessions in `codex resume`. `doctor` detects this — reading a snapshot copy when the live file cannot be opened — and `--fix` moves the damaged files into `~/.config/ai-switch/quarantine/<timestamp>/`. Codex rebuilds the database from the rollout files on the next start, which brings resumable sessions back. Rollouts and history are not touched.
|
|
177
|
+
* **Network filesystems.** If `CODEX_HOME` lives on NFS/CIFS/SMB, SQLite databases are corrupted sooner or later, which is the usual root cause of "history lost after switching". Keep the runtime databases on a local disk instead:
|
|
178
|
+
|
|
179
|
+
```bash
|
|
180
|
+
export CODEX_SQLITE_HOME=/var/tmp/codex-sqlite-$USER # a local, persistent directory
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
`ai-switch add` offers to write `sqlite_home` into the generated Codex configuration when it detects a network filesystem.
|
|
184
|
+
* **A stale model catalogue.** A catalogue left behind by the previous provider hides the new provider's models from Codex and makes sessions that used them unresumable. ai-switch removes that leftover file (only if it wrote it itself, and it backs it up first), and `doctor` verifies the configured model exists in the catalogue.
|
|
185
|
+
* **Disabled history persistence** (`[history] persistence = "none"`), a Claude Code model pinned by `ANTHROPIC_MODEL`, and `claude`/`codex` processes that are running while you switch and will rewrite their configuration on exit.
|
|
186
|
+
|
|
187
|
+
`codex resume` only lists sessions of the current directory by default; `codex resume --all` shows every directory. That cwd filter, not a lost session, is a common false alarm.
|
|
188
|
+
|
|
189
|
+
## Safety and storage
|
|
190
|
+
|
|
191
|
+
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.
|
|
192
|
+
|
|
193
|
+
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.
|
|
194
|
+
|
|
195
|
+
## Commands
|
|
196
|
+
|
|
197
|
+
```text
|
|
198
|
+
ai-switch init NAME [-d DESCRIPTION] Save current files as a new profile
|
|
199
|
+
ai-switch list List profiles and configuration summaries
|
|
200
|
+
ai-switch use NAME [-m MODEL] [-y] [-n] Back up and activate a profile (and a model)
|
|
201
|
+
ai-switch models [NAME] [--json] Show the models a profile offers
|
|
202
|
+
ai-switch current Print the active profile
|
|
203
|
+
ai-switch describe NAME TEXT Set a profile description
|
|
204
|
+
ai-switch upgrade NAME Derive models.json for a profile from an older release
|
|
205
|
+
ai-switch add Create a profile interactively (GLM, DeepSeek, or custom)
|
|
206
|
+
ai-switch doctor [--fix] [--json] Check configuration and session-history health
|
|
207
|
+
ai-switch --help Show full usage and examples
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
## Upgrading from 0.1
|
|
211
|
+
|
|
212
|
+
Existing profiles keep working. Profiles that only have `codex-models.json` are read as before and get a model picker automatically; run `ai-switch upgrade NAME` (or re-create the profile with `ai-switch add`) to materialise an editable `models.json` with explicit per-model Claude Code mappings.
|
|
213
|
+
|
|
214
|
+
## Development
|
|
215
|
+
|
|
216
|
+
```bash
|
|
217
|
+
python3 -m unittest -v
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
The project uses only the Python standard library.
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
# ai-switch
|
|
2
|
+
|
|
3
|
+
## The problem it solves
|
|
4
|
+
|
|
5
|
+
When you use multiple coding agents and multiple model providers, changing providers separately in Claude Code and Codex is repetitive and error-prone. **ai-switch updates both agents in one command.**
|
|
6
|
+
|
|
7
|
+
Choose a provider profile once, then activate it with `ai-switch use NAME`. The built-in GLM and DeepSeek presets already contain the provider-specific files, endpoints, protocols, model catalogs, and Claude Code mappings recommended by their official documentation. You only need to enter your API key. Custom OpenAI-compatible providers are supported too.
|
|
8
|
+
|
|
9
|
+
A profile can offer several models (for example GLM 5.3 and GLM 5.3 Flash, or DeepSeek Flash and DeepSeek V4 Pro). `ai-switch use` asks which one to activate and writes the answer to both agents, so the model pickers *inside* Claude Code and Codex keep working instead of being pinned to a single model.
|
|
10
|
+
|
|
11
|
+
Switching also leaves conversation history alone: sessions, rollouts, `history.jsonl` and the agents' runtime databases are never copied into a profile or overwritten by a switch, and `ai-switch doctor` reports the things that really do make old sessions disappear.
|
|
12
|
+
|
|
13
|
+
This is a secure, headless-friendly command-line tool for servers without a desktop environment or administrator privileges.
|
|
14
|
+
|
|
15
|
+
## Install
|
|
16
|
+
|
|
17
|
+
Install from PyPI (recommended):
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
python3 -m pip install --user ai-switch-cli
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
For a system or virtual-environment install:
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
pip install ai-switch-cli
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Install the latest development version directly from GitHub:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
python3 -m pip install --user "git+https://github.com/ZidongS/ai-switch.git"
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Or install a local checkout:
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
python3 -m pip install --user .
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
If `ai-switch` is not found afterwards, add the user script directory to `PATH`:
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
export PATH="$HOME/.local/bin:$PATH"
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Quick start
|
|
48
|
+
|
|
49
|
+
Save the configuration currently in use as a fallback profile:
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
ai-switch init default --description "Default daily configuration"
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Create a ready-to-use mainstream provider profile interactively:
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
ai-switch add
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Select `glm` or `deepseek`, enter the API key, and activate the generated configuration:
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
ai-switch use glm
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
`use` lists the models the profile offers and remembers your choice:
|
|
68
|
+
|
|
69
|
+
```text
|
|
70
|
+
This profile provides 2 models:
|
|
71
|
+
1) glm-5.3 GLM-5.3 flagship (1M context) [default]
|
|
72
|
+
2) glm-5.3-flash GLM-5.3 flash (fast, 1M context)
|
|
73
|
+
Select model [1-2, Enter=glm-5.3, q=cancel]:
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
For scripts and servers, choose without prompting (name, unique prefix, or index):
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
ai-switch use glm --model glm-5.3-flash
|
|
80
|
+
ai-switch use glm -m 2 -y
|
|
81
|
+
ai-switch use glm --dry-run # show what would change
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Edit `~/.codex/config.toml` and `~/.claude/settings.json` for another provider, then save that configuration as a second profile:
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
ai-switch init glm --description "GLM Coding Plan"
|
|
88
|
+
ai-switch list
|
|
89
|
+
ai-switch use glm
|
|
90
|
+
ai-switch current
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
Create a profile through an interactive prompt (no editor required; API keys are hidden while typing). Choose the built-in `glm` preset to generate the complete ZAI Codex Responses configuration, Codex model catalog and Claude Code model/environment mappings for the three models the endpoint publishes (`glm-5.3`, `glm-5.3-flash`, `glm-5-turbo`) automatically. The `deepseek` preset creates the two model entries the DeepSeek endpoint currently accepts (`deepseek-flash` and `deepseek-v4-pro`, both with image input metadata) plus the recommended Claude Code mappings:
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
ai-switch add
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
Update an existing profile description:
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
ai-switch describe default "Default daily configuration"
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
`list` shows the active marker, profile name, configured clients, description, detected models, and endpoint hostnames. API keys are never printed.
|
|
106
|
+
|
|
107
|
+
## Choosing a model
|
|
108
|
+
|
|
109
|
+
Each profile keeps its model list in `models.json` next to the client files:
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
ai-switch models # list the models of the active profile
|
|
113
|
+
ai-switch models glm --json # machine readable
|
|
114
|
+
ai-switch upgrade glm # derive models.json for a profile from an older release
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
For every model a profile records the Codex catalogue entry and the Claude Code mapping, so activating one model updates all of these consistently:
|
|
118
|
+
|
|
119
|
+
* Codex: the top-level `model` (and `model_reasoning_effort`), plus a `~/.codex/models.json` catalogue that lists **every** model of the profile, which is what makes Codex's own `/model` picker show them.
|
|
120
|
+
* Claude Code: the default model in `settings.json` plus the Opus/Sonnet/Haiku mappings. The presets map the three categories to *different* provider models where they exist, and they never set `ANTHROPIC_MODEL`, because a pinned environment model overrides your selection and makes `/model` do nothing.
|
|
121
|
+
|
|
122
|
+
The `glm` and `deepseek` presets ship multi-model lists. A custom (OpenAI-compatible) profile is open-ended: it does not publish a catalogue, and `ai-switch use NAME --model anything` accepts any model name the endpoint serves.
|
|
123
|
+
|
|
124
|
+
### When a provider adds or renames a model
|
|
125
|
+
|
|
126
|
+
Model names change, and an endpoint refuses a name it does not know. Ask the provider what your key may use:
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
curl -s https://api.deepseek.com/models -H "Authorization: Bearer $KEY" # OpenAI-style list
|
|
130
|
+
curl -s https://open.bigmodel.cn/api/v1/models -H "Authorization: Bearer $KEY" # Codex-format catalogue
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
A rejected name is also reported in the API error itself (*"The supported API model names are ..."*, or `模型不存在,请检查模型代码。`). Some providers publish their Codex catalogue directly (`/api/v1/models` on ZAI returns exactly the entries a profile's `codex-models.json` wants), so it can be copied verbatim. Historically DeepSeek answered to `deepseek-v4-flash` and `deepseek-v4-flash-vision-exp`; today those are aliases that the endpoint resolves to `deepseek-flash`.
|
|
134
|
+
|
|
135
|
+
To add a model, append it to the profile's `models.json` — the `claude` mapping decides what Opus/Sonnet/Haiku resolve to, the `codex` entry controls whether Codex's own picker offers it. Keep the entries of names that older sessions were recorded with in the Codex catalogue so those sessions stay resumable, then activate:
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
ai-switch use deepseek -m deepseek-flash
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
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.
|
|
142
|
+
|
|
143
|
+
## Session history
|
|
144
|
+
|
|
145
|
+
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:
|
|
146
|
+
|
|
147
|
+
```text
|
|
148
|
+
~/.codex/history.jsonl, ~/.codex/session_index.jsonl, ~/.codex/sessions/,
|
|
149
|
+
~/.codex/*_N.sqlite (runtime state, logs, goals, memories)
|
|
150
|
+
~/.claude.json, ~/.claude/history.jsonl, ~/.claude/projects/, ~/.claude/sessions/
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
If sessions do seem to disappear after a switch, run:
|
|
154
|
+
|
|
155
|
+
```bash
|
|
156
|
+
ai-switch doctor # full report; --json for tooling
|
|
157
|
+
ai-switch doctor --fix # quarantine damaged Codex runtime databases
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
`doctor` checks, among other things:
|
|
161
|
+
|
|
162
|
+
* **Damaged SQLite runtime databases.** Codex keeps thread metadata in `~/.codex/state_*.sqlite` and `thread_history_1.sqlite`. When one is damaged (typical messages: `database disk image is malformed`, `file is not a database`) Codex silently stops listing recent sessions in `codex resume`. `doctor` detects this — reading a snapshot copy when the live file cannot be opened — and `--fix` moves the damaged files into `~/.config/ai-switch/quarantine/<timestamp>/`. Codex rebuilds the database from the rollout files on the next start, which brings resumable sessions back. Rollouts and history are not touched.
|
|
163
|
+
* **Network filesystems.** If `CODEX_HOME` lives on NFS/CIFS/SMB, SQLite databases are corrupted sooner or later, which is the usual root cause of "history lost after switching". Keep the runtime databases on a local disk instead:
|
|
164
|
+
|
|
165
|
+
```bash
|
|
166
|
+
export CODEX_SQLITE_HOME=/var/tmp/codex-sqlite-$USER # a local, persistent directory
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
`ai-switch add` offers to write `sqlite_home` into the generated Codex configuration when it detects a network filesystem.
|
|
170
|
+
* **A stale model catalogue.** A catalogue left behind by the previous provider hides the new provider's models from Codex and makes sessions that used them unresumable. ai-switch removes that leftover file (only if it wrote it itself, and it backs it up first), and `doctor` verifies the configured model exists in the catalogue.
|
|
171
|
+
* **Disabled history persistence** (`[history] persistence = "none"`), a Claude Code model pinned by `ANTHROPIC_MODEL`, and `claude`/`codex` processes that are running while you switch and will rewrite their configuration on exit.
|
|
172
|
+
|
|
173
|
+
`codex resume` only lists sessions of the current directory by default; `codex resume --all` shows every directory. That cwd filter, not a lost session, is a common false alarm.
|
|
174
|
+
|
|
175
|
+
## Safety and storage
|
|
176
|
+
|
|
177
|
+
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.
|
|
178
|
+
|
|
179
|
+
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.
|
|
180
|
+
|
|
181
|
+
## Commands
|
|
182
|
+
|
|
183
|
+
```text
|
|
184
|
+
ai-switch init NAME [-d DESCRIPTION] Save current files as a new profile
|
|
185
|
+
ai-switch list List profiles and configuration summaries
|
|
186
|
+
ai-switch use NAME [-m MODEL] [-y] [-n] Back up and activate a profile (and a model)
|
|
187
|
+
ai-switch models [NAME] [--json] Show the models a profile offers
|
|
188
|
+
ai-switch current Print the active profile
|
|
189
|
+
ai-switch describe NAME TEXT Set a profile description
|
|
190
|
+
ai-switch upgrade NAME Derive models.json for a profile from an older release
|
|
191
|
+
ai-switch add Create a profile interactively (GLM, DeepSeek, or custom)
|
|
192
|
+
ai-switch doctor [--fix] [--json] Check configuration and session-history health
|
|
193
|
+
ai-switch --help Show full usage and examples
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
## Upgrading from 0.1
|
|
197
|
+
|
|
198
|
+
Existing profiles keep working. Profiles that only have `codex-models.json` are read as before and get a model picker automatically; run `ai-switch upgrade NAME` (or re-create the profile with `ai-switch add`) to materialise an editable `models.json` with explicit per-model Claude Code mappings.
|
|
199
|
+
|
|
200
|
+
## Development
|
|
201
|
+
|
|
202
|
+
```bash
|
|
203
|
+
python3 -m unittest -v
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
The project uses only the Python standard library.
|