@tokenaut/opentoken 1.3.5 → 1.4.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 +85 -71
- package/bin/opentoken.js +5 -4
- package/package.json +22 -10
- package/src/atomcode-config.js +94 -0
- package/src/cli.js +207 -147
- package/src/codex-config.js +44 -22
- package/src/config.js +29 -28
- package/src/fetch-models.js +228 -0
- package/src/hermes-config.js +157 -0
- package/src/logo.js +62 -0
- package/src/models.js +61 -0
- package/src/openclaw-config.js +174 -0
- package/src/opencode-config.js +166 -0
- package/src/screen.js +9 -0
- package/src/tools/atomcode.js +253 -0
- package/src/tools/claude.js +302 -0
- package/src/tools/codex.js +327 -0
- package/src/tools/hermes.js +274 -0
- package/src/tools/openclaw.js +244 -0
- package/src/tools/opencode.js +258 -0
package/src/cli.js
CHANGED
|
@@ -1,88 +1,105 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const
|
|
4
|
-
const
|
|
3
|
+
const chalk = require('chalk');
|
|
4
|
+
const inquirer = require('inquirer');
|
|
5
|
+
const { printLogo } = require('./logo');
|
|
6
|
+
const { clearScreen } = require('./screen');
|
|
7
|
+
const claude = require('./tools/claude');
|
|
8
|
+
const atomcode = require('./tools/atomcode');
|
|
9
|
+
const hermes = require('./tools/hermes');
|
|
10
|
+
const openclaw = require('./tools/openclaw');
|
|
11
|
+
const opencode = require('./tools/opencode');
|
|
12
|
+
const codex = require('./tools/codex');
|
|
13
|
+
const { DEFAULT_BASE_URL } = require('./models');
|
|
5
14
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
const CC_DEFAULT_MODEL_ALIAS = 'opus';
|
|
10
|
-
const CX_DEFAULT_MODEL_ALIAS = '5.4';
|
|
11
|
-
|
|
12
|
-
const CC_MODEL_MAP = {
|
|
13
|
-
opus: 'claude-opus-4-8',
|
|
14
|
-
sonnet: 'claude-sonnet-4-6',
|
|
15
|
-
haiku: 'claude-haiku-4-5',
|
|
16
|
-
'claude-opus-4-8': 'claude-opus-4-8',
|
|
17
|
-
'claude-sonnet-4-6': 'claude-sonnet-4-6',
|
|
18
|
-
'claude-haiku-4-5': 'claude-haiku-4-5',
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
const CC_SONNET_MODEL = 'claude-sonnet-4-6';
|
|
22
|
-
const CC_HAIKU_MODEL = 'claude-haiku-4-5';
|
|
15
|
+
function isCcCommand(tool) {
|
|
16
|
+
return tool === 'cc' || tool === 'claude';
|
|
17
|
+
}
|
|
23
18
|
|
|
24
|
-
|
|
25
|
-
'
|
|
26
|
-
|
|
27
|
-
'gpt5.5': 'gpt-5.5',
|
|
28
|
-
'gpt5.4': 'gpt-5.4',
|
|
29
|
-
'gpt-5.5': 'gpt-5.5',
|
|
30
|
-
'gpt-5.4': 'gpt-5.4',
|
|
31
|
-
};
|
|
19
|
+
function isAtomcodeCommand(tool) {
|
|
20
|
+
return tool === 'atomcode' || tool === 'ac';
|
|
21
|
+
}
|
|
32
22
|
|
|
33
|
-
function
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
}
|
|
23
|
+
function isHermesCommand(tool) {
|
|
24
|
+
return tool === 'hermes' || tool === 'hm';
|
|
25
|
+
}
|
|
37
26
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
}
|
|
27
|
+
function isOpenclawCommand(tool) {
|
|
28
|
+
return tool === 'openclaw' || tool === 'oc';
|
|
29
|
+
}
|
|
42
30
|
|
|
43
|
-
|
|
31
|
+
function isOpencodeCommand(tool) {
|
|
32
|
+
return tool === 'opencode' || tool === 'od';
|
|
44
33
|
}
|
|
45
34
|
|
|
46
|
-
function
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
}
|
|
35
|
+
function isCodexCommand(tool) {
|
|
36
|
+
return tool === 'codex' || tool === 'cx';
|
|
37
|
+
}
|
|
50
38
|
|
|
51
|
-
|
|
39
|
+
function printVersion() {
|
|
40
|
+
const pkg = require('../package.json');
|
|
41
|
+
console.log(`${pkg.name} ${pkg.version}`);
|
|
52
42
|
}
|
|
53
43
|
|
|
54
44
|
function printHelp() {
|
|
55
45
|
console.log('');
|
|
56
|
-
console.log('
|
|
46
|
+
console.log(chalk.bold('常用:'));
|
|
47
|
+
console.log(' opentoken help | --help | -h 显示本帮助');
|
|
48
|
+
console.log(' opentoken version | --version | -v | -V 显示版本号');
|
|
57
49
|
console.log('');
|
|
58
|
-
console.log('用法:');
|
|
59
|
-
console.log(' opentoken
|
|
50
|
+
console.log(chalk.bold('用法:'));
|
|
51
|
+
console.log(' opentoken 进入主菜单');
|
|
52
|
+
console.log(' opentoken cc 进入 Claude Code 配置菜单');
|
|
53
|
+
console.log(' opentoken cc --key <apikey> 设置 API Key');
|
|
54
|
+
console.log(' opentoken cc --url <baseurl> 设置 Base URL');
|
|
55
|
+
console.log(' opentoken cc --model <model> 设置模型');
|
|
56
|
+
console.log(' opentoken cc -k <k> -u <u> -m <m> 一键全部设置');
|
|
60
57
|
console.log('');
|
|
61
|
-
console.log('
|
|
62
|
-
console.log('
|
|
63
|
-
console.log('
|
|
64
|
-
console.log('
|
|
58
|
+
console.log(' opentoken atomcode 进入 Atomcode 配置(~/.atomcode/config.toml)');
|
|
59
|
+
console.log(' opentoken ac 同上(缩写)');
|
|
60
|
+
console.log(' opentoken ac --key <apikey> 仅设置 API Key(base_url 固定为 Opentoken /v1)');
|
|
61
|
+
console.log(' opentoken ac --model <model> 仅设置模型');
|
|
62
|
+
console.log(' opentoken ac -k <k> -m <m> 一键设置 Key 与模型');
|
|
65
63
|
console.log('');
|
|
66
|
-
console.log('
|
|
67
|
-
console.log(
|
|
68
|
-
console.log(
|
|
69
|
-
console.log(
|
|
64
|
+
console.log(' opentoken openclaw 进入 OpenClaw 配置(~/.openclaw/openclaw.json)');
|
|
65
|
+
console.log(' opentoken oc 同上(缩写)');
|
|
66
|
+
console.log(' opentoken oc --key <apikey> 写入 models.providers.opentoken.apiKey');
|
|
67
|
+
console.log(' opentoken oc --model <model> 设置 agents.defaults.model.primary(opentoken/<id>)');
|
|
68
|
+
console.log(' opentoken oc -k <k> -m <m> 一键设置 Key 与主模型');
|
|
70
69
|
console.log('');
|
|
71
|
-
console.log('
|
|
72
|
-
console.log(
|
|
73
|
-
console.log(
|
|
70
|
+
console.log(' opentoken hermes 进入 Hermes 配置(~/.hermes)');
|
|
71
|
+
console.log(' opentoken hm 同上(缩写)');
|
|
72
|
+
console.log(' opentoken hm --key <apikey> 设置 Opentoken API KEY(写入 ~/.hermes/.env)');
|
|
73
|
+
console.log(' opentoken hm --model <model> 设置 config.yaml 内 model.default');
|
|
74
|
+
console.log(' opentoken hm -k <k> -m <m> 一键设置 Key 与默认模型');
|
|
74
75
|
console.log('');
|
|
75
|
-
console.log('
|
|
76
|
-
console.log(' opentoken
|
|
77
|
-
console.log(' opentoken
|
|
78
|
-
console.log(' opentoken
|
|
79
|
-
console.log(' opentoken
|
|
80
|
-
console.log(' opentoken cx --url https://gw.opentoken.io/v1');
|
|
76
|
+
console.log(' opentoken opencode 进入 OpenCode 配置(~/.config/opencode/opencode.json)');
|
|
77
|
+
console.log(' opentoken od 同上(缩写)');
|
|
78
|
+
console.log(' opentoken od --key <apikey> 设置 Opentoken API KEY');
|
|
79
|
+
console.log(' opentoken od --model <model> 设置默认模型');
|
|
80
|
+
console.log(' opentoken od -k <k> -m <m> 一键设置 Key 与模型');
|
|
81
81
|
console.log('');
|
|
82
|
-
console.log('
|
|
83
|
-
console.log('
|
|
84
|
-
console.log(
|
|
85
|
-
console.log(
|
|
82
|
+
console.log(' opentoken codex 进入 Codex 配置(~/.codex/config.toml)');
|
|
83
|
+
console.log(' opentoken cx 同上(缩写)');
|
|
84
|
+
console.log(' opentoken cx --key <apikey> 拉取 responses 模型并写入配置(Key 需 export 生效)');
|
|
85
|
+
console.log(' opentoken cx --url <baseurl> 设置 Codex Base URL(需包含 /v1)');
|
|
86
|
+
console.log(' opentoken cx --model <model> 设置默认模型');
|
|
87
|
+
console.log(' opentoken cx -k <k> -u <u> -m <m> 一键设置 URL 与模型');
|
|
88
|
+
console.log('');
|
|
89
|
+
console.log(chalk.bold('快捷别名(--key / -k,--url / -u,--model / -m)'));
|
|
90
|
+
console.log('');
|
|
91
|
+
console.log(chalk.bold('示例:'));
|
|
92
|
+
console.log(' opentoken cc -k sk-xxx');
|
|
93
|
+
console.log(` opentoken cc -k sk-xxx -u ${DEFAULT_BASE_URL} -m claude-opus-4-5`);
|
|
94
|
+
console.log('');
|
|
95
|
+
console.log(chalk.bold('主菜单:'));
|
|
96
|
+
console.log(' 1. 配置 Claude Code');
|
|
97
|
+
console.log(' 2. 配置 Atomcode');
|
|
98
|
+
console.log(' 3. 配置 OpenClaw');
|
|
99
|
+
console.log(' 4. 配置 Hermes');
|
|
100
|
+
console.log(' 5. 配置 OpenCode');
|
|
101
|
+
console.log(' 6. 配置 Codex');
|
|
102
|
+
console.log(' 7. 退出');
|
|
86
103
|
console.log('');
|
|
87
104
|
}
|
|
88
105
|
|
|
@@ -91,138 +108,181 @@ function parseArgs(argv) {
|
|
|
91
108
|
const result = {
|
|
92
109
|
tool: null,
|
|
93
110
|
key: null,
|
|
94
|
-
model: null,
|
|
95
111
|
url: null,
|
|
112
|
+
model: null,
|
|
96
113
|
help: false,
|
|
114
|
+
version: false,
|
|
97
115
|
};
|
|
98
116
|
|
|
99
117
|
let i = 0;
|
|
118
|
+
|
|
100
119
|
if (args[0] && !args[0].startsWith('-')) {
|
|
101
120
|
result.tool = args[0].toLowerCase();
|
|
102
121
|
i = 1;
|
|
103
122
|
}
|
|
104
123
|
|
|
105
|
-
for (; i < args.length; i
|
|
106
|
-
const
|
|
124
|
+
for (; i < args.length; i++) {
|
|
125
|
+
const a = args[i];
|
|
107
126
|
const next = args[i + 1];
|
|
108
|
-
|
|
109
|
-
if (
|
|
110
|
-
|
|
111
|
-
} else if ((current === '--key' || current === '-k') && next) {
|
|
127
|
+
if (a === '--help' || a === '-h') result.help = true;
|
|
128
|
+
else if (a === '--version' || a === '-v' || a === '-V') result.version = true;
|
|
129
|
+
else if ((a === '--key' || a === '-k') && next) {
|
|
112
130
|
result.key = next;
|
|
113
|
-
i
|
|
114
|
-
} else if ((
|
|
115
|
-
result.model = next;
|
|
116
|
-
i += 1;
|
|
117
|
-
} else if ((current === '--url' || current === '-u') && next) {
|
|
131
|
+
i++;
|
|
132
|
+
} else if ((a === '--url' || a === '-u') && next) {
|
|
118
133
|
result.url = next;
|
|
119
|
-
i
|
|
134
|
+
i++;
|
|
135
|
+
} else if ((a === '--model' || a === '-m') && next) {
|
|
136
|
+
result.model = next;
|
|
137
|
+
i++;
|
|
120
138
|
}
|
|
121
139
|
}
|
|
122
140
|
|
|
123
141
|
return result;
|
|
124
142
|
}
|
|
125
143
|
|
|
126
|
-
function
|
|
127
|
-
|
|
128
|
-
|
|
144
|
+
async function mainMenu() {
|
|
145
|
+
while (true) {
|
|
146
|
+
clearScreen();
|
|
147
|
+
printLogo();
|
|
148
|
+
|
|
149
|
+
const { action } = await inquirer.prompt([
|
|
150
|
+
{
|
|
151
|
+
type: 'list',
|
|
152
|
+
name: 'action',
|
|
153
|
+
prefix: '',
|
|
154
|
+
message: '请选择:',
|
|
155
|
+
choices: [
|
|
156
|
+
{ name: '1. 配置 Claude Code', value: 'claude' },
|
|
157
|
+
{ name: '2. 配置 Atomcode', value: 'atomcode' },
|
|
158
|
+
{ name: '3. 配置 OpenClaw', value: 'openclaw' },
|
|
159
|
+
{ name: '4. 配置 Hermes', value: 'hermes' },
|
|
160
|
+
{ name: '5. 配置 OpenCode', value: 'opencode' },
|
|
161
|
+
{ name: '6. 配置 Codex', value: 'codex' },
|
|
162
|
+
{ name: '7. 退出', value: 'exit' },
|
|
163
|
+
],
|
|
164
|
+
pageSize: 8,
|
|
165
|
+
},
|
|
166
|
+
]);
|
|
167
|
+
|
|
168
|
+
if (action === 'exit') {
|
|
169
|
+
clearScreen();
|
|
170
|
+
console.log(chalk.cyan('再见!'));
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
129
173
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
}
|
|
174
|
+
if (action === 'claude') {
|
|
175
|
+
await claude.run();
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
if (action === 'atomcode') {
|
|
179
|
+
await atomcode.run();
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
if (action === 'openclaw') {
|
|
183
|
+
await openclaw.run();
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
if (action === 'hermes') {
|
|
187
|
+
await hermes.run();
|
|
188
|
+
}
|
|
133
189
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
190
|
+
if (action === 'opencode') {
|
|
191
|
+
await opencode.run();
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
if (action === 'codex') {
|
|
195
|
+
await codex.run();
|
|
196
|
+
}
|
|
137
197
|
}
|
|
138
198
|
}
|
|
139
199
|
|
|
140
|
-
async function
|
|
141
|
-
const
|
|
200
|
+
async function run() {
|
|
201
|
+
const args = parseArgs(process.argv);
|
|
142
202
|
|
|
143
|
-
if (args.
|
|
144
|
-
|
|
203
|
+
if (args.help || args.tool === 'help') {
|
|
204
|
+
printHelp();
|
|
205
|
+
return;
|
|
145
206
|
}
|
|
146
207
|
|
|
147
|
-
if (args.
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
patch.haikuModel = resolveModel('haiku', CC_MODEL_MAP, CC_DEFAULT_MODEL_ALIAS);
|
|
208
|
+
if (args.version || args.tool === 'version') {
|
|
209
|
+
printVersion();
|
|
210
|
+
return;
|
|
151
211
|
}
|
|
152
212
|
|
|
153
|
-
if (args.
|
|
154
|
-
|
|
213
|
+
if (isCcCommand(args.tool) && (args.key || args.url || args.model)) {
|
|
214
|
+
clearScreen();
|
|
215
|
+
printLogo();
|
|
216
|
+
claude.quickSet({ key: args.key, url: args.url, model: args.model });
|
|
217
|
+
return;
|
|
155
218
|
}
|
|
156
219
|
|
|
157
|
-
if (
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
220
|
+
if (isAtomcodeCommand(args.tool) && (args.key || args.model)) {
|
|
221
|
+
clearScreen();
|
|
222
|
+
printLogo();
|
|
223
|
+
atomcode.quickSet({ key: args.key, model: args.model });
|
|
161
224
|
return;
|
|
162
225
|
}
|
|
163
226
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
if (patch.baseUrl) console.log(` Base URL: ${patch.baseUrl}`);
|
|
170
|
-
if (patch.model) console.log(` Model: ${patch.model}`);
|
|
171
|
-
if (patch.sonnetModel) console.log(` Sonnet: ${patch.sonnetModel}`);
|
|
172
|
-
if (patch.haikuModel) console.log(` Haiku: ${patch.haikuModel}`);
|
|
173
|
-
console.log(` File: ${SETTINGS_PATH}`);
|
|
174
|
-
console.log('');
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
async function runCodex(args) {
|
|
178
|
-
const patch = {};
|
|
179
|
-
|
|
180
|
-
if (args.key && String(args.key).trim()) {
|
|
181
|
-
patch.apiKey = String(args.key).trim();
|
|
227
|
+
if (isHermesCommand(args.tool) && (args.key || args.model)) {
|
|
228
|
+
clearScreen();
|
|
229
|
+
printLogo();
|
|
230
|
+
hermes.quickSet({ key: args.key, model: args.model });
|
|
231
|
+
return;
|
|
182
232
|
}
|
|
183
233
|
|
|
184
|
-
if (args.
|
|
185
|
-
|
|
234
|
+
if (isOpenclawCommand(args.tool) && (args.key || args.model)) {
|
|
235
|
+
clearScreen();
|
|
236
|
+
printLogo();
|
|
237
|
+
openclaw.quickSet({ key: args.key, model: args.model });
|
|
238
|
+
return;
|
|
186
239
|
}
|
|
187
240
|
|
|
188
|
-
if (args.
|
|
189
|
-
|
|
241
|
+
if (isOpencodeCommand(args.tool) && (args.key || args.model)) {
|
|
242
|
+
clearScreen();
|
|
243
|
+
printLogo();
|
|
244
|
+
await opencode.quickSet({ key: args.key, model: args.model });
|
|
245
|
+
return;
|
|
190
246
|
}
|
|
191
247
|
|
|
192
|
-
if (
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
248
|
+
if (isCodexCommand(args.tool) && (args.key || args.url || args.model)) {
|
|
249
|
+
clearScreen();
|
|
250
|
+
printLogo();
|
|
251
|
+
await codex.quickSet({ key: args.key, url: args.url, model: args.model });
|
|
196
252
|
return;
|
|
197
253
|
}
|
|
198
254
|
|
|
199
|
-
|
|
255
|
+
if (isCcCommand(args.tool)) {
|
|
256
|
+
await claude.run();
|
|
257
|
+
return;
|
|
258
|
+
}
|
|
200
259
|
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
if (patch.model) console.log(` Model: ${patch.model}`);
|
|
206
|
-
console.log(` Config: ${CODEX_CONFIG_PATH}`);
|
|
207
|
-
console.log(` Auth: ${CODEX_AUTH_PATH}`);
|
|
208
|
-
console.log('');
|
|
209
|
-
}
|
|
260
|
+
if (isAtomcodeCommand(args.tool)) {
|
|
261
|
+
await atomcode.run();
|
|
262
|
+
return;
|
|
263
|
+
}
|
|
210
264
|
|
|
211
|
-
|
|
212
|
-
|
|
265
|
+
if (isHermesCommand(args.tool)) {
|
|
266
|
+
await hermes.run();
|
|
267
|
+
return;
|
|
268
|
+
}
|
|
213
269
|
|
|
214
|
-
if (args.
|
|
215
|
-
|
|
270
|
+
if (isOpenclawCommand(args.tool)) {
|
|
271
|
+
await openclaw.run();
|
|
216
272
|
return;
|
|
217
273
|
}
|
|
218
274
|
|
|
219
|
-
|
|
275
|
+
if (isOpencodeCommand(args.tool)) {
|
|
276
|
+
await opencode.run();
|
|
277
|
+
return;
|
|
278
|
+
}
|
|
220
279
|
|
|
221
|
-
if (
|
|
222
|
-
await
|
|
223
|
-
|
|
224
|
-
await runCodex(args);
|
|
280
|
+
if (isCodexCommand(args.tool)) {
|
|
281
|
+
await codex.run();
|
|
282
|
+
return;
|
|
225
283
|
}
|
|
284
|
+
|
|
285
|
+
await mainMenu();
|
|
226
286
|
}
|
|
227
287
|
|
|
228
|
-
module.exports = run;
|
|
288
|
+
module.exports = { run };
|
package/src/codex-config.js
CHANGED
|
@@ -1,18 +1,26 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const fs = require('fs');
|
|
4
|
-
const os = require('os');
|
|
5
4
|
const path = require('path');
|
|
5
|
+
const os = require('os');
|
|
6
6
|
const TOML = require('@iarna/toml');
|
|
7
|
+
const {
|
|
8
|
+
CODEX_OPENTOKEN_BASE_URL,
|
|
9
|
+
CODEX_PROVIDER_KEY,
|
|
10
|
+
CODEX_AUTH_KEY,
|
|
11
|
+
CODEX_DEFAULT_MODEL,
|
|
12
|
+
} = require('./models');
|
|
7
13
|
|
|
8
14
|
const CONFIG_DIR = path.join(os.homedir(), '.codex');
|
|
9
15
|
const CONFIG_PATH = path.join(CONFIG_DIR, 'config.toml');
|
|
10
16
|
const AUTH_PATH = path.join(CONFIG_DIR, 'auth.json');
|
|
11
|
-
|
|
12
|
-
const PROVIDER_KEY = 'opentoken';
|
|
13
|
-
const AUTH_KEY = 'OPENAI_API_KEY';
|
|
14
17
|
const MODEL_AVAILABILITY_LEVEL = 4;
|
|
15
18
|
|
|
19
|
+
function readRaw() {
|
|
20
|
+
if (!fs.existsSync(CONFIG_PATH)) return '';
|
|
21
|
+
return fs.readFileSync(CONFIG_PATH, 'utf-8');
|
|
22
|
+
}
|
|
23
|
+
|
|
16
24
|
function readAuthFile() {
|
|
17
25
|
if (!fs.existsSync(AUTH_PATH)) return {};
|
|
18
26
|
try {
|
|
@@ -26,6 +34,21 @@ function readAuthFile() {
|
|
|
26
34
|
}
|
|
27
35
|
}
|
|
28
36
|
|
|
37
|
+
function readApiKey() {
|
|
38
|
+
const auth = readAuthFile();
|
|
39
|
+
const fromAuth = auth[CODEX_AUTH_KEY];
|
|
40
|
+
if (fromAuth != null && String(fromAuth).trim()) {
|
|
41
|
+
return String(fromAuth).trim();
|
|
42
|
+
}
|
|
43
|
+
if (process.env[CODEX_AUTH_KEY] && String(process.env[CODEX_AUTH_KEY]).trim()) {
|
|
44
|
+
return String(process.env[CODEX_AUTH_KEY]).trim();
|
|
45
|
+
}
|
|
46
|
+
if (process.env.OPENTOKEN_API_KEY && String(process.env.OPENTOKEN_API_KEY).trim()) {
|
|
47
|
+
return String(process.env.OPENTOKEN_API_KEY).trim();
|
|
48
|
+
}
|
|
49
|
+
return '';
|
|
50
|
+
}
|
|
51
|
+
|
|
29
52
|
function applyCodexAuth(apiKey) {
|
|
30
53
|
const key = apiKey == null ? '' : String(apiKey).trim();
|
|
31
54
|
if (!key) return;
|
|
@@ -34,7 +57,7 @@ function applyCodexAuth(apiKey) {
|
|
|
34
57
|
const data = {
|
|
35
58
|
...prev,
|
|
36
59
|
auth_mode: 'apikey',
|
|
37
|
-
[
|
|
60
|
+
[CODEX_AUTH_KEY]: key,
|
|
38
61
|
};
|
|
39
62
|
|
|
40
63
|
if (!fs.existsSync(CONFIG_DIR)) {
|
|
@@ -51,8 +74,7 @@ function ensurePlainObject(parent, key) {
|
|
|
51
74
|
}
|
|
52
75
|
|
|
53
76
|
function parseConfig() {
|
|
54
|
-
|
|
55
|
-
const raw = fs.readFileSync(CONFIG_PATH, 'utf-8');
|
|
77
|
+
const raw = readRaw();
|
|
56
78
|
if (!raw || !String(raw).trim()) return {};
|
|
57
79
|
try {
|
|
58
80
|
const data = TOML.parse(raw);
|
|
@@ -72,15 +94,14 @@ function getCurrentCodexConfig() {
|
|
|
72
94
|
? data.model_providers
|
|
73
95
|
: {};
|
|
74
96
|
const provider =
|
|
75
|
-
providers[
|
|
76
|
-
|
|
97
|
+
providers[CODEX_PROVIDER_KEY] &&
|
|
98
|
+
typeof providers[CODEX_PROVIDER_KEY] === 'object' &&
|
|
99
|
+
!Array.isArray(providers[CODEX_PROVIDER_KEY])
|
|
100
|
+
? providers[CODEX_PROVIDER_KEY]
|
|
77
101
|
: {};
|
|
78
102
|
|
|
79
|
-
const auth = readAuthFile();
|
|
80
|
-
const apiKey = auth[AUTH_KEY] || '';
|
|
81
|
-
|
|
82
103
|
return {
|
|
83
|
-
apiKey,
|
|
104
|
+
apiKey: readApiKey(),
|
|
84
105
|
baseUrl: provider.base_url != null ? String(provider.base_url) : '',
|
|
85
106
|
model: data.model != null ? String(data.model) : '',
|
|
86
107
|
};
|
|
@@ -105,8 +126,10 @@ function applyCodexConfig(patch) {
|
|
|
105
126
|
|
|
106
127
|
const providers = ensurePlainObject(data, 'model_providers');
|
|
107
128
|
const prevProvider =
|
|
108
|
-
providers[
|
|
109
|
-
|
|
129
|
+
providers[CODEX_PROVIDER_KEY] &&
|
|
130
|
+
typeof providers[CODEX_PROVIDER_KEY] === 'object' &&
|
|
131
|
+
!Array.isArray(providers[CODEX_PROVIDER_KEY])
|
|
132
|
+
? { ...providers[CODEX_PROVIDER_KEY] }
|
|
110
133
|
: {};
|
|
111
134
|
|
|
112
135
|
const nextModel =
|
|
@@ -114,24 +137,24 @@ function applyCodexConfig(patch) {
|
|
|
114
137
|
? String(model).trim()
|
|
115
138
|
: data.model != null && String(data.model).trim()
|
|
116
139
|
? String(data.model).trim()
|
|
117
|
-
:
|
|
140
|
+
: CODEX_DEFAULT_MODEL;
|
|
118
141
|
const nextBaseUrl =
|
|
119
142
|
baseUrl !== undefined && String(baseUrl).trim()
|
|
120
143
|
? String(baseUrl).trim()
|
|
121
144
|
: prevProvider.base_url != null && String(prevProvider.base_url).trim()
|
|
122
145
|
? String(prevProvider.base_url).trim()
|
|
123
|
-
:
|
|
146
|
+
: CODEX_OPENTOKEN_BASE_URL;
|
|
124
147
|
|
|
125
148
|
data.model = nextModel;
|
|
126
|
-
data.model_provider =
|
|
149
|
+
data.model_provider = CODEX_PROVIDER_KEY;
|
|
127
150
|
const nextProvider = {
|
|
128
151
|
...prevProvider,
|
|
129
|
-
name: '
|
|
152
|
+
name: 'Opentoken',
|
|
130
153
|
base_url: nextBaseUrl,
|
|
131
154
|
wire_api: 'responses',
|
|
132
155
|
};
|
|
133
156
|
delete nextProvider.env_key;
|
|
134
|
-
providers[
|
|
157
|
+
providers[CODEX_PROVIDER_KEY] = nextProvider;
|
|
135
158
|
|
|
136
159
|
const profileModels = uniqueModels(models, nextModel);
|
|
137
160
|
const profiles = ensurePlainObject(data, 'profiles');
|
|
@@ -142,7 +165,7 @@ function applyCodexConfig(patch) {
|
|
|
142
165
|
: {};
|
|
143
166
|
profiles[id] = {
|
|
144
167
|
...prevProfile,
|
|
145
|
-
model_provider:
|
|
168
|
+
model_provider: CODEX_PROVIDER_KEY,
|
|
146
169
|
model: id,
|
|
147
170
|
};
|
|
148
171
|
});
|
|
@@ -166,7 +189,6 @@ function applyCodexConfig(patch) {
|
|
|
166
189
|
module.exports = {
|
|
167
190
|
CONFIG_PATH,
|
|
168
191
|
AUTH_PATH,
|
|
169
|
-
PROVIDER_KEY,
|
|
170
192
|
getCurrentCodexConfig,
|
|
171
193
|
applyCodexConfig,
|
|
172
194
|
applyCodexAuth,
|