yymaxapi 1.0.68 → 1.0.69
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/bin/yymaxapi.js
CHANGED
|
@@ -676,7 +676,7 @@ function writeClaudeCodeSettings(baseUrl, apiKey) {
|
|
|
676
676
|
}
|
|
677
677
|
}
|
|
678
678
|
|
|
679
|
-
function writeCodexConfig(baseUrl, apiKey) {
|
|
679
|
+
function writeCodexConfig(baseUrl, apiKey, modelId = 'gpt-5.4') {
|
|
680
680
|
const codexDir = path.join(os.homedir(), '.codex');
|
|
681
681
|
if (!fs.existsSync(codexDir)) fs.mkdirSync(codexDir, { recursive: true });
|
|
682
682
|
|
|
@@ -698,7 +698,7 @@ function writeCodexConfig(baseUrl, apiKey) {
|
|
|
698
698
|
}
|
|
699
699
|
const section = [
|
|
700
700
|
marker,
|
|
701
|
-
`model = "
|
|
701
|
+
`model = "${modelId}"`,
|
|
702
702
|
`model_provider = "${providerKey}"`,
|
|
703
703
|
``,
|
|
704
704
|
`[model_providers.${providerKey}]`,
|
|
@@ -3077,6 +3077,95 @@ async function activateOpencode(paths, args = {}) {
|
|
|
3077
3077
|
console.log(chalk.yellow('\n 切换模型: 在 opencode 内使用 /model 命令切换 yunyi-claude / yunyi-codex'));
|
|
3078
3078
|
}
|
|
3079
3079
|
|
|
3080
|
+
// ============ 单独配置 Codex CLI ============
|
|
3081
|
+
async function activateCodex(paths, args = {}) {
|
|
3082
|
+
console.log(chalk.cyan.bold('\n🔧 配置 Codex CLI\n'));
|
|
3083
|
+
|
|
3084
|
+
// ---- 选模型 ----
|
|
3085
|
+
let modelId = CODEX_MODELS[0]?.id || 'gpt-5.4';
|
|
3086
|
+
if (CODEX_MODELS.length > 1) {
|
|
3087
|
+
const { selected } = await inquirer.prompt([{
|
|
3088
|
+
type: 'list',
|
|
3089
|
+
name: 'selected',
|
|
3090
|
+
message: '选择模型:',
|
|
3091
|
+
choices: CODEX_MODELS.map(m => ({ name: m.name, value: m.id }))
|
|
3092
|
+
}]);
|
|
3093
|
+
modelId = selected;
|
|
3094
|
+
}
|
|
3095
|
+
const modelConfig = CODEX_MODELS.find(m => m.id === modelId) || { id: modelId, name: modelId };
|
|
3096
|
+
|
|
3097
|
+
// ---- 测速选节点 ----
|
|
3098
|
+
const shouldTest = !(args['no-test'] || args.noTest);
|
|
3099
|
+
let selectedEndpoint = ENDPOINTS[0];
|
|
3100
|
+
|
|
3101
|
+
if (shouldTest) {
|
|
3102
|
+
console.log(chalk.cyan('📡 开始测速节点...\n'));
|
|
3103
|
+
const speedResult = await testAllEndpoints(ENDPOINTS, { autoFallback: true });
|
|
3104
|
+
const sorted = speedResult.ranked || [];
|
|
3105
|
+
if (sorted.length > 0) {
|
|
3106
|
+
const defaultEp = ENDPOINTS[0];
|
|
3107
|
+
const { selectedIndex } = await inquirer.prompt([{
|
|
3108
|
+
type: 'list',
|
|
3109
|
+
name: 'selectedIndex',
|
|
3110
|
+
message: '选择节点:',
|
|
3111
|
+
choices: [
|
|
3112
|
+
{ name: `* 使用默认节点 (${defaultEp.name})`, value: -1 },
|
|
3113
|
+
new inquirer.Separator(' ---- 或按测速结果选择 ----'),
|
|
3114
|
+
...sorted.map((e, i) => ({
|
|
3115
|
+
name: `${e.name} - ${e.latency}ms (评分:${e.score})`,
|
|
3116
|
+
value: i
|
|
3117
|
+
}))
|
|
3118
|
+
]
|
|
3119
|
+
}]);
|
|
3120
|
+
selectedEndpoint = selectedIndex === -1 ? defaultEp : sorted[selectedIndex];
|
|
3121
|
+
} else {
|
|
3122
|
+
console.log(chalk.red('\n⚠️ 所有节点均不可达'));
|
|
3123
|
+
const { proceed } = await inquirer.prompt([{
|
|
3124
|
+
type: 'confirm', name: 'proceed',
|
|
3125
|
+
message: '仍要使用默认节点配置吗?', default: false
|
|
3126
|
+
}]);
|
|
3127
|
+
if (!proceed) { console.log(chalk.gray('已取消')); return; }
|
|
3128
|
+
}
|
|
3129
|
+
}
|
|
3130
|
+
|
|
3131
|
+
// ---- API Key ----
|
|
3132
|
+
const directKey = (args['api-key'] || args.apiKey || args.key || '').toString().trim();
|
|
3133
|
+
let apiKey;
|
|
3134
|
+
if (directKey) {
|
|
3135
|
+
apiKey = directKey;
|
|
3136
|
+
} else {
|
|
3137
|
+
const envKey = process.env.OPENAI_API_KEY || '';
|
|
3138
|
+
apiKey = await promptApiKey('请输入 API Key:', envKey);
|
|
3139
|
+
}
|
|
3140
|
+
if (!apiKey) { console.log(chalk.gray('已取消')); return; }
|
|
3141
|
+
|
|
3142
|
+
// ---- 验证 ----
|
|
3143
|
+
console.log('');
|
|
3144
|
+
const validation = await validateApiKey(selectedEndpoint.url, apiKey);
|
|
3145
|
+
if (!validation.valid) {
|
|
3146
|
+
const { continueAnyway } = await inquirer.prompt([{
|
|
3147
|
+
type: 'confirm', name: 'continueAnyway',
|
|
3148
|
+
message: 'API Key 验证失败,是否仍然继续写入配置?', default: false
|
|
3149
|
+
}]);
|
|
3150
|
+
if (!continueAnyway) { console.log(chalk.gray('已取消')); return; }
|
|
3151
|
+
}
|
|
3152
|
+
|
|
3153
|
+
// ---- 写入配置 ----
|
|
3154
|
+
const codexBaseUrl = buildFullUrl(selectedEndpoint.url, 'codex');
|
|
3155
|
+
const writeSpinner = ora({ text: '正在写入 Codex 配置...', spinner: 'dots' }).start();
|
|
3156
|
+
writeCodexConfig(codexBaseUrl, apiKey, modelId);
|
|
3157
|
+
writeSpinner.succeed('Codex 配置写入完成');
|
|
3158
|
+
|
|
3159
|
+
console.log(chalk.green('\n✅ Codex CLI 配置完成!'));
|
|
3160
|
+
console.log(chalk.cyan(` Base URL: ${codexBaseUrl}`));
|
|
3161
|
+
console.log(chalk.gray(` 模型: ${modelConfig.name} (${modelId})`));
|
|
3162
|
+
console.log(chalk.gray(' API Key: 已设置'));
|
|
3163
|
+
console.log(chalk.gray('\n 已写入:'));
|
|
3164
|
+
console.log(chalk.gray(' • ~/.codex/config.toml (model + model_providers)'));
|
|
3165
|
+
console.log(chalk.gray(' • ~/.codex/auth.json (OPENAI_API_KEY)'));
|
|
3166
|
+
console.log(chalk.yellow('\n 提示: 请重新打开终端使配置生效'));
|
|
3167
|
+
}
|
|
3168
|
+
|
|
3080
3169
|
// ============ yycode 精简模式(零交互一键配置) ============
|
|
3081
3170
|
async function yycodeQuickSetup(paths) {
|
|
3082
3171
|
console.log(chalk.cyan.bold('\n⚡ yycode 一键配置\n'));
|
|
@@ -3296,6 +3385,7 @@ async function main() {
|
|
|
3296
3385
|
{ name: ' 配置 OpenClaw(Claude + Codex)', value: 'auto_activate' },
|
|
3297
3386
|
{ name: ' 配置 Claude Code', value: 'activate_claude_code' },
|
|
3298
3387
|
{ name: ' 配置 Opencode', value: 'activate_opencode' },
|
|
3388
|
+
{ name: ' 配置 Codex CLI', value: 'activate_codex' },
|
|
3299
3389
|
new inquirer.Separator(' -- 工具 --'),
|
|
3300
3390
|
{ name: ' 切换模型', value: 'switch_model' },
|
|
3301
3391
|
{ name: ` 权限管理${getToolsProfileTag(paths)}`, value: 'tools_profile' },
|
|
@@ -3340,6 +3430,9 @@ async function main() {
|
|
|
3340
3430
|
case 'activate_opencode':
|
|
3341
3431
|
await activateOpencode(paths);
|
|
3342
3432
|
break;
|
|
3433
|
+
case 'activate_codex':
|
|
3434
|
+
await activateCodex(paths);
|
|
3435
|
+
break;
|
|
3343
3436
|
}
|
|
3344
3437
|
} catch (error) {
|
|
3345
3438
|
console.log(chalk.red(`\n错误: ${error.message}\n`));
|
|
@@ -107,3 +107,62 @@ npx yymaxapi@latest
|
|
|
107
107
|
- GPT 可用模型:`gpt-5.4`
|
|
108
108
|
- 已验证环境:腾讯云 OpenCloudOS,OpenClaw `2026.2.3-1`
|
|
109
109
|
- 参考文档:https://cloud.tencent.com/developer/article/2624003
|
|
110
|
+
|
|
111
|
+
### 腾讯云 + Claude Code CLI 一起写入(同一 Key)
|
|
112
|
+
|
|
113
|
+
云翼一张卡可同时用于 Claude 与 GPT。按下面两步做即可同时生效。
|
|
114
|
+
|
|
115
|
+
**1. 腾讯云 OpenClaw 自定义模型(添加两条)**
|
|
116
|
+
|
|
117
|
+
在腾讯云 OpenClaw 的「自定义模型」里添加**两条**,`api_key` 用同一云翼 Key 即可。
|
|
118
|
+
|
|
119
|
+
第一条 — Claude Sonnet 4.6:
|
|
120
|
+
|
|
121
|
+
```json
|
|
122
|
+
{
|
|
123
|
+
"provider": "anthropic",
|
|
124
|
+
"base_url": "https://yunyi.rdzhvip.com/claude",
|
|
125
|
+
"api": "anthropic-messages",
|
|
126
|
+
"api_key": "<你的云翼 API Key>",
|
|
127
|
+
"model": {
|
|
128
|
+
"id": "claude-sonnet-4-6",
|
|
129
|
+
"name": "Claude Sonnet 4.6"
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
第二条 — GPT 5.4:
|
|
135
|
+
|
|
136
|
+
```json
|
|
137
|
+
{
|
|
138
|
+
"provider": "openai",
|
|
139
|
+
"base_url": "https://yunyi.rdzhvip.com/codex",
|
|
140
|
+
"api": "openai-responses",
|
|
141
|
+
"api_key": "<你的云翼 API Key>",
|
|
142
|
+
"model": {
|
|
143
|
+
"id": "gpt-5.4",
|
|
144
|
+
"name": "GPT 5.4"
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
**2. Claude Code CLI(本机终端)**
|
|
150
|
+
|
|
151
|
+
在终端执行一次,或写入 `~/.zshrc` / `~/.bashrc` 后 `source`,Claude Code 即走云翼 Claude:
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
export ANTHROPIC_BASE_URL="https://yunyi.rdzhvip.com/claude"
|
|
155
|
+
export ANTHROPIC_AUTH_TOKEN="<你的云翼 API Key>"
|
|
156
|
+
# 若遇证书报错可加:
|
|
157
|
+
export NODE_TLS_REJECT_UNAUTHORIZED=0
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
Windows(PowerShell,用户级环境变量):
|
|
161
|
+
|
|
162
|
+
```powershell
|
|
163
|
+
[Environment]::SetEnvironmentVariable('ANTHROPIC_BASE_URL', 'https://yunyi.rdzhvip.com/claude', 'User')
|
|
164
|
+
[Environment]::SetEnvironmentVariable('ANTHROPIC_AUTH_TOKEN', '<你的云翼 API Key>', 'User')
|
|
165
|
+
[Environment]::SetEnvironmentVariable('NODE_TLS_REJECT_UNAUTHORIZED', '0', 'User')
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
完成后:腾讯云 OpenClaw 里可选 Claude 或 GPT;本机 Claude Code CLI 使用同一 Key 走云翼 Claude。
|