@galaxy-yearn/codex-deepseek-gateway 0.1.6 → 0.2.0
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.
- package/README.md +58 -26
- package/bin/codex-deepseek-gateway.js +7 -0
- package/config/codex-model-catalog.json +24 -28
- package/config/codex-model-catalog.zh.json +126 -0
- package/config/frontend-design-guidance/en.md +33 -0
- package/config/frontend-design-guidance/zh.md +33 -0
- package/config/gateway.example.json +1 -0
- package/package.json +4 -1
- package/src/codex-launch.js +12 -3
- package/src/common.js +18 -3
- package/src/config.js +15 -2
- package/src/firecrawl.js +7 -16
- package/src/local-config.js +6 -2
- package/src/model-map.js +6 -20
- package/src/prompt-language.js +13 -0
- package/src/protocol.js +1319 -450
- package/src/server.js +510 -350
- package/src/session-store.js +228 -13
- package/src/tavily.js +2 -11
- package/src/upstream.js +14 -12
- package/src/web-search-emulator.js +12 -11
- package/state/sessions.example.json +72 -0
package/README.md
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
# Codex DeepSeek Gateway
|
|
2
2
|
|
|
3
|
-
A lightweight local gateway for using DeepSeek models in Codex.
|
|
3
|
+
A lightweight local gateway for using DeepSeek models in Codex. It performs nearly identically to the native GPT model.
|
|
4
4
|
|
|
5
5
|
Codex keeps using the OpenAI `Responses API` wire format. The gateway translates requests to DeepSeek-compatible `Chat Completions`, calls DeepSeek, then translates the result back to Responses JSON or `response.*` SSE events.
|
|
6
6
|
|
|
7
7
|
Package: [@galaxy-yearn/codex-deepseek-gateway](https://www.npmjs.com/package/@galaxy-yearn/codex-deepseek-gateway)
|
|
8
8
|
|
|
9
|
+
DeepSeek is a great company.
|
|
10
|
+
|
|
9
11
|
## Requirements
|
|
10
12
|
|
|
11
13
|
- Node.js 22 or newer
|
|
@@ -28,7 +30,8 @@ The runtime is copied to `~/.codex/deepseek-gateway`. Put your DeepSeek API key
|
|
|
28
30
|
|
|
29
31
|
```json
|
|
30
32
|
{
|
|
31
|
-
"upstreamApiKey": "sk-..."
|
|
33
|
+
"upstreamApiKey": "sk-...",
|
|
34
|
+
"codexPromptLanguage": "en"
|
|
32
35
|
}
|
|
33
36
|
```
|
|
34
37
|
|
|
@@ -41,7 +44,16 @@ codex-deepseek-gateway status
|
|
|
41
44
|
|
|
42
45
|
`status` should show `"reachable": true`.
|
|
43
46
|
|
|
44
|
-
|
|
47
|
+
To remove the local runtime and the global package:
|
|
48
|
+
|
|
49
|
+
```sh
|
|
50
|
+
codex-deepseek-gateway uninstall
|
|
51
|
+
npm uninstall -g @galaxy-yearn/codex-deepseek-gateway
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Configuration
|
|
55
|
+
|
|
56
|
+
### Codex Provider
|
|
45
57
|
|
|
46
58
|
Add this provider to `~/.codex/config.toml`:
|
|
47
59
|
|
|
@@ -60,6 +72,35 @@ wire_api = "responses"
|
|
|
60
72
|
|
|
61
73
|
Restart Codex after editing `config.toml`.
|
|
62
74
|
|
|
75
|
+
### System Prompt Language
|
|
76
|
+
|
|
77
|
+
`codexPromptLanguage` in `gateway.local.json` selects the packaged prompt catalog. Supported values are `en` and `zh`; invalid values fall back to `en`:
|
|
78
|
+
|
|
79
|
+
```text
|
|
80
|
+
en -> ~/.codex/deepseek-gateway/config/codex-model-catalog.json
|
|
81
|
+
zh -> ~/.codex/deepseek-gateway/config/codex-model-catalog.zh.json
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### Model Aliases
|
|
85
|
+
|
|
86
|
+
Model aliases are read from:
|
|
87
|
+
|
|
88
|
+
```text
|
|
89
|
+
~/.codex/deepseek-gateway/config/model-aliases.json
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
`model-aliases.json` is managed by this package and refreshed on install. The packaged Codex catalog currently allows the default aliases `deepseek-v4-flash` and `deepseek-v4-pro` for Codex-native sub-agent validation.
|
|
93
|
+
|
|
94
|
+
### Session State
|
|
95
|
+
|
|
96
|
+
The gateway persists its Responses-side `previous_response_id` / `conversation` graph under:
|
|
97
|
+
|
|
98
|
+
```text
|
|
99
|
+
~/.codex/deepseek-gateway/state/sessions.json
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
That state lets DeepSeek receive reconstructed Chat history — including raw reasoning for thinking-mode tool turns — after a gateway restart. Codex sends `store: false`, so its turns persist only a compact per-`call_id` reasoning cache; full history snapshots are kept only for clients that use `previous_response_id` / `conversation` with storage enabled. The file is human-readable JSON (`state/sessions.example.json` shows the shape) and safe to delete at any time. Tune it with `sessionStorePath`, `sessionStoreMaxSessions` (default 500), `sessionStoreMaxBytes` (default 16 MB), or `sessionStoreEnabled: false`; the matching `SESSION_STORE_*` environment variables work too.
|
|
103
|
+
|
|
63
104
|
## Usage
|
|
64
105
|
|
|
65
106
|
Start a new Codex conversation with gateway overrides:
|
|
@@ -74,7 +115,7 @@ Resume a Codex session from the current project:
|
|
|
74
115
|
codex-deepseek-gateway sessions
|
|
75
116
|
```
|
|
76
117
|
|
|
77
|
-
|
|
118
|
+
Prefer these `new` / `sessions` commands over plain `codex` / `codex resume`. The launcher adds the gateway provider, model catalog, model, and reasoning overrides.
|
|
78
119
|
|
|
79
120
|
In the interactive session picker, use Up/Down to move through a scrolling window of sessions. Press `n` to start a new conversation instead of resuming an existing session.
|
|
80
121
|
|
|
@@ -93,17 +134,9 @@ codex-deepseek-gateway sessions --exec <id-or-row> # r
|
|
|
93
134
|
codex -c model_provider=deepseek-gateway -c model=<model> -c model_reasoning_effort=<effort> -c model_supports_reasoning_summaries=true -c model_reasoning_summary=auto
|
|
94
135
|
```
|
|
95
136
|
|
|
96
|
-
The
|
|
97
|
-
|
|
98
|
-
Inside a launcher-started Codex TUI, `/model` can switch between the packaged DeepSeek models and reasoning efforts.
|
|
99
|
-
|
|
100
|
-
Model aliases are read from:
|
|
101
|
-
|
|
102
|
-
```text
|
|
103
|
-
~/.codex/deepseek-gateway/config/model-aliases.json
|
|
104
|
-
```
|
|
137
|
+
The launcher also passes `model_catalog_json` pointing at the packaged catalog, so Codex-native multi-agent validation accepts the DeepSeek model aliases and `low|medium|high|xhigh` reasoning efforts. This setting replaces the default model catalog for that Codex process; it is not merged into it. The default context window is expanded to 1M since both `deepseek-v4-flash` and `deepseek-v4-pro` model supports that. `context_window` and `max_context_window` can be customized.
|
|
105
138
|
|
|
106
|
-
|
|
139
|
+
Inside a launcher-started Codex TUI, `/model` switches between the packaged DeepSeek models and reasoning efforts, and `/personality` works with the catalog's `personality_default`, `personality_friendly`, and `personality_pragmatic` entries.
|
|
107
140
|
|
|
108
141
|
## Commands
|
|
109
142
|
|
|
@@ -118,16 +151,11 @@ codex-deepseek-gateway sessions # pick and resume a Codex session through the
|
|
|
118
151
|
codex-deepseek-gateway uninstall # remove the local runtime
|
|
119
152
|
```
|
|
120
153
|
|
|
121
|
-
`doctor` checks the active Codex config, DeepSeek request shape, reasoning mode, and optional web-search backend readiness.
|
|
154
|
+
`doctor` checks the active Codex config, DeepSeek request shape, reasoning mode, and optional web-search backend readiness. For deeper debugging, set `debugPayload: true` in `gateway.local.json` to log per-request mapping summaries to `gateway.debug.log` (rotated at 5 MB).
|
|
122
155
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
```sh
|
|
126
|
-
codex-deepseek-gateway uninstall
|
|
127
|
-
npm uninstall -g @galaxy-yearn/codex-deepseek-gateway
|
|
128
|
-
```
|
|
156
|
+
## Capabilities
|
|
129
157
|
|
|
130
|
-
|
|
158
|
+
### Reasoning
|
|
131
159
|
|
|
132
160
|
Codex effort maps to DeepSeek V4 thinking mode:
|
|
133
161
|
|
|
@@ -138,9 +166,13 @@ Codex effort maps to DeepSeek V4 thinking mode:
|
|
|
138
166
|
| `high` | `thinking.type = enabled`, `reasoning_effort = high` |
|
|
139
167
|
| `xhigh` | `thinking.type = enabled`, `reasoning_effort = max` |
|
|
140
168
|
|
|
141
|
-
When DeepSeek returns `reasoning_content`, the
|
|
169
|
+
When DeepSeek returns `reasoning_content`, the raw text is preserved for DeepSeek history, while Codex receives a display summary: Markdown-cleaned, with a leading bold `**Reasoning**` header. The header drives the Codex status line while the model thinks.
|
|
170
|
+
|
|
171
|
+
### Tool Discovery
|
|
172
|
+
|
|
173
|
+
Codex keeps some native tools out of the initial tool list and lets the model discover them with `tool_search`. The gateway bridges this end to end: `tool_search` is exposed to DeepSeek as a callable function, Codex executes the search locally, and the tool definitions returned in `tool_search_output` history are merged into the DeepSeek tool list, so discovered tools become directly callable in later turns.
|
|
142
174
|
|
|
143
|
-
|
|
175
|
+
### Web Search
|
|
144
176
|
|
|
145
177
|
Web search is optional and off by default. Configure Tavily for search:
|
|
146
178
|
|
|
@@ -160,7 +192,7 @@ Configure Firecrawl if you also want opened-page reading:
|
|
|
160
192
|
}
|
|
161
193
|
```
|
|
162
194
|
|
|
163
|
-
Codex can keep requesting `web_search` / `web_search_preview`. The gateway exposes compact internal web tools to DeepSeek, executes Tavily/Firecrawl calls itself, feeds tool results back to the model, and returns Codex-compatible `web_search_call` items. `TAVILY_MAX_SEARCH_ROUNDS`
|
|
195
|
+
Codex can keep requesting `web_search` / `web_search_preview`. The gateway exposes compact internal web tools to DeepSeek, executes Tavily/Firecrawl calls itself, feeds tool results back to the model, and returns Codex-compatible `web_search_call` items. Streaming stays live through every round — reasoning, `web_search_call` progress, and the final answer — and turns that never search behave like the non-web path. `TAVILY_MAX_SEARCH_ROUNDS` (default `20`, hard cap `40`) is a runaway/cost guardrail; when reached, the gateway disables web tools for one final-answer turn.
|
|
164
196
|
|
|
165
197
|
Final answers should include useful source titles and URLs directly.
|
|
166
198
|
|
|
@@ -171,8 +203,8 @@ Chat Completions is not a full Responses API replacement.
|
|
|
171
203
|
- Hosted tools without a local Codex executor are represented as function shims. Web search is the only hosted tool the gateway emulates directly.
|
|
172
204
|
- Tavily/Firecrawl web emulation is text-focused; it does not provide browser control, screenshots, raw HTML, cookies, crawl jobs, or private-network access.
|
|
173
205
|
- OpenAI `file_id` values are passed through; the gateway cannot fetch private OpenAI-hosted files.
|
|
174
|
-
- In-memory `previous_response_id` / `conversation` history is lost when the gateway process restarts.
|
|
175
206
|
- Plain `codex` commands do not automatically load the packaged model catalog. Use the launcher when you want TUI `/model` and sub-agent validation to use the DeepSeek catalog.
|
|
207
|
+
- Resumed sessions may hide parts of earlier assistant replies that contain Markdown tables. This is a Codex TUI replay bug ([openai/codex#29218](https://github.com/openai/codex/issues/29218)); the session data itself is intact.
|
|
176
208
|
|
|
177
209
|
## License
|
|
178
210
|
|
|
@@ -50,6 +50,8 @@ Options:
|
|
|
50
50
|
--exec <id> With sessions, run the generated codex resume command
|
|
51
51
|
--limit <n> With sessions, max rows to print or show, defaults to ${DEFAULT_SESSION_LIMIT}
|
|
52
52
|
--print With sessions, print resume commands instead of picker
|
|
53
|
+
|
|
54
|
+
Prompt language is configured in gateway.local.json with codexPromptLanguage.
|
|
53
55
|
`);
|
|
54
56
|
}
|
|
55
57
|
|
|
@@ -224,6 +226,9 @@ function copyRuntime(installDir) {
|
|
|
224
226
|
cpSync(join(ROOT, 'bin'), join(installDir, 'bin'), { recursive: true });
|
|
225
227
|
cpSync(join(ROOT, 'src'), join(installDir, 'src'), { recursive: true });
|
|
226
228
|
copyFileSync(join(ROOT, 'config', 'codex-model-catalog.json'), join(installDir, 'config', 'codex-model-catalog.json'));
|
|
229
|
+
copyFileSync(join(ROOT, 'config', 'codex-model-catalog.zh.json'), join(installDir, 'config', 'codex-model-catalog.zh.json'));
|
|
230
|
+
rmSync(join(installDir, 'config', 'frontend-design-guidance'), { recursive: true, force: true });
|
|
231
|
+
cpSync(join(ROOT, 'config', 'frontend-design-guidance'), join(installDir, 'config', 'frontend-design-guidance'), { recursive: true });
|
|
227
232
|
rmSync(join(installDir, 'config', 'codex-model-catalog.base.json'), { force: true });
|
|
228
233
|
copyFileSync(join(ROOT, 'config', 'model-aliases.example.json'), join(installDir, 'config', 'model-aliases.json'));
|
|
229
234
|
const localConfig = configPath(installDir);
|
|
@@ -397,6 +402,8 @@ async function doctor(options) {
|
|
|
397
402
|
codexReasoningSummary: config.codexReasoningSummary || null,
|
|
398
403
|
codexModelSupportsReasoningSummaries: config.codexModelSupportsReasoningSummaries || null,
|
|
399
404
|
codexHideAgentReasoning: config.codexHideAgentReasoning || null,
|
|
405
|
+
codexPromptLanguage: config.codexPromptLanguage,
|
|
406
|
+
codexModelCatalog: join(options.dir, 'config', config.codexPromptLanguage === 'zh' ? 'codex-model-catalog.zh.json' : 'codex-model-catalog.json'),
|
|
400
407
|
sampleModel: model,
|
|
401
408
|
upstreamModel: upstreamRequest.model,
|
|
402
409
|
deepseekThinking: upstreamRequest.thinking || null,
|