yymaxapi 1.0.117 → 1.0.119
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
CHANGED
|
@@ -16,7 +16,7 @@ npx yymaxapi@latest
|
|
|
16
16
|
npx yymaxapi@latest speed-test
|
|
17
17
|
```
|
|
18
18
|
或在具体配置命令后追加 `--speed-test`,按测速结果手动选点。
|
|
19
|
-
如需直接切换到其他云翼域名,可在预设/一键激活命令后追加 `--endpoint-url https://yunyi.
|
|
19
|
+
如需直接切换到其他云翼域名,可在预设/一键激活命令后追加 `--endpoint-url https://yunyi.yun`,也兼容 `--base-url https://你的域名/claude` 这种写法。
|
|
20
20
|
|
|
21
21
|
**方式二:一键配置 Claude**
|
|
22
22
|
```bash
|
package/bin/yymaxapi.js
CHANGED
|
@@ -853,9 +853,29 @@ function buildPosixAuthCandidates(baseDirs) {
|
|
|
853
853
|
return auths;
|
|
854
854
|
}
|
|
855
855
|
|
|
856
|
-
function
|
|
856
|
+
function formatWslArg(value) {
|
|
857
|
+
const str = String(value || '');
|
|
858
|
+
return /^[A-Za-z0-9_.:-]+$/.test(str) ? str : shellQuote(str);
|
|
859
|
+
}
|
|
860
|
+
|
|
861
|
+
function buildWslCommand(command, target = {}) {
|
|
862
|
+
const parts = ['wsl'];
|
|
863
|
+
const distro = String(target.distro || target.wslDistro || '').trim();
|
|
864
|
+
const user = String(target.user || target.wslUser || '').trim();
|
|
865
|
+
if (distro) parts.push('-d', formatWslArg(distro));
|
|
866
|
+
if (user) parts.push('-u', formatWslArg(user));
|
|
867
|
+
parts.push('--', 'bash', target.login ? '-lc' : '-c', shellQuote(command));
|
|
868
|
+
return parts.join(' ');
|
|
869
|
+
}
|
|
870
|
+
|
|
871
|
+
function runWslCommand(command, options = {}, target = {}) {
|
|
872
|
+
return safeExec(buildWslCommand(command, target), options);
|
|
873
|
+
}
|
|
874
|
+
|
|
875
|
+
function findExistingWslFile(candidates = [], target = {}) {
|
|
857
876
|
for (const candidate of candidates) {
|
|
858
|
-
const
|
|
877
|
+
const quotedCandidate = `'${escapeSingleQuotedShell(candidate)}'`;
|
|
878
|
+
const check = runWslCommand(`test -f ${quotedCandidate} && echo yes`, { timeout: 5000 }, target);
|
|
859
879
|
if (check.ok && check.output.trim() === 'yes') {
|
|
860
880
|
return candidate;
|
|
861
881
|
}
|
|
@@ -1316,7 +1336,7 @@ function writeHermesConfig(baseUrl, apiKey, modelId = getDefaultClaudeModel().id
|
|
|
1316
1336
|
const configPath = path.join(dataDir, 'config.yaml');
|
|
1317
1337
|
const envPath = getHermesEnvPath();
|
|
1318
1338
|
const existingConfigPath = getHermesConfigPath();
|
|
1319
|
-
const wslMirror = getHermesWslMirrorInfo();
|
|
1339
|
+
const wslMirror = getHermesWslMirrorInfo(options);
|
|
1320
1340
|
const modelType = options.type || options.provider || '';
|
|
1321
1341
|
const resolvedType = resolveHermesModelType(modelId, modelType);
|
|
1322
1342
|
const runtimeProvider = resolvedType === 'codex' ? 'custom' : 'anthropic';
|
|
@@ -1324,12 +1344,12 @@ function writeHermesConfig(baseUrl, apiKey, modelId = getDefaultClaudeModel().id
|
|
|
1324
1344
|
|
|
1325
1345
|
let existingConfigRaw = readTextIfExists(existingConfigPath);
|
|
1326
1346
|
if (!existingConfigRaw && wslMirror.sourceConfigPath) {
|
|
1327
|
-
existingConfigRaw = readWslTextFile(wslMirror.sourceConfigPath);
|
|
1347
|
+
existingConfigRaw = readWslTextFile(wslMirror.sourceConfigPath, wslMirror.target);
|
|
1328
1348
|
}
|
|
1329
1349
|
|
|
1330
1350
|
let existingEnvRaw = readTextIfExists(envPath);
|
|
1331
1351
|
if (!existingEnvRaw && wslMirror.envPath) {
|
|
1332
|
-
existingEnvRaw = readWslTextFile(wslMirror.envPath);
|
|
1352
|
+
existingEnvRaw = readWslTextFile(wslMirror.envPath, wslMirror.target);
|
|
1333
1353
|
}
|
|
1334
1354
|
|
|
1335
1355
|
const normalizedBaseUrl = (
|
|
@@ -1357,10 +1377,10 @@ function writeHermesConfig(baseUrl, apiKey, modelId = getDefaultClaudeModel().id
|
|
|
1357
1377
|
fs.writeFileSync(envPath, nextEnvRaw, 'utf8');
|
|
1358
1378
|
|
|
1359
1379
|
if (wslMirror.configPath) {
|
|
1360
|
-
try { syncFileToWsl(configPath, wslMirror.configPath); } catch { /* best-effort */ }
|
|
1380
|
+
try { syncFileToWsl(configPath, wslMirror.configPath, wslMirror.target); } catch { /* best-effort */ }
|
|
1361
1381
|
}
|
|
1362
1382
|
if (wslMirror.envPath) {
|
|
1363
|
-
try { syncFileToWsl(envPath, wslMirror.envPath); } catch { /* best-effort */ }
|
|
1383
|
+
try { syncFileToWsl(envPath, wslMirror.envPath, wslMirror.target); } catch { /* best-effort */ }
|
|
1364
1384
|
}
|
|
1365
1385
|
|
|
1366
1386
|
return {
|
|
@@ -1369,6 +1389,8 @@ function writeHermesConfig(baseUrl, apiKey, modelId = getDefaultClaudeModel().id
|
|
|
1369
1389
|
envPath,
|
|
1370
1390
|
wslConfigPath: wslMirror.configPath,
|
|
1371
1391
|
wslEnvPath: wslMirror.envPath,
|
|
1392
|
+
wslUser: wslMirror.target?.user || '',
|
|
1393
|
+
wslDistro: wslMirror.target?.distro || '',
|
|
1372
1394
|
modelId,
|
|
1373
1395
|
modelType: resolvedType,
|
|
1374
1396
|
provider: runtimeProvider,
|
|
@@ -1624,21 +1646,33 @@ function invalidateGatewayEnvCache() {
|
|
|
1624
1646
|
function isWslAvailable() {
|
|
1625
1647
|
if (process.platform !== 'win32') return false;
|
|
1626
1648
|
if (_wslAvailCache !== null) return _wslAvailCache;
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1649
|
+
const probes = [
|
|
1650
|
+
'wsl -- echo ok',
|
|
1651
|
+
'wsl -u root -- echo ok'
|
|
1652
|
+
];
|
|
1653
|
+
for (const cmd of probes) {
|
|
1654
|
+
const result = safeExec(cmd, { timeout: 5000 });
|
|
1655
|
+
if (result.ok && String(result.output || result.stdout || '').includes('ok')) {
|
|
1656
|
+
_wslAvailCache = true;
|
|
1657
|
+
return _wslAvailCache;
|
|
1658
|
+
}
|
|
1632
1659
|
}
|
|
1660
|
+
_wslAvailCache = false;
|
|
1633
1661
|
return _wslAvailCache;
|
|
1634
1662
|
}
|
|
1635
1663
|
|
|
1636
|
-
function getWslHome() {
|
|
1637
|
-
|
|
1664
|
+
function getWslHome(target = {}) {
|
|
1665
|
+
const hasTarget = !!String(target.user || target.wslUser || target.distro || target.wslDistro || '').trim();
|
|
1666
|
+
if (!hasTarget && _wslHomeCache !== undefined) return _wslHomeCache;
|
|
1638
1667
|
try {
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1668
|
+
const result = runWslCommand('echo $HOME', { timeout: 5000 }, target);
|
|
1669
|
+
const home = result.ok ? (result.output || '').trim() || null : null;
|
|
1670
|
+
if (!hasTarget) _wslHomeCache = home;
|
|
1671
|
+
return home;
|
|
1672
|
+
} catch {
|
|
1673
|
+
if (!hasTarget) _wslHomeCache = null;
|
|
1674
|
+
return null;
|
|
1675
|
+
}
|
|
1642
1676
|
}
|
|
1643
1677
|
|
|
1644
1678
|
// 获取 WSL 内 openclaw CLI 的完整路径(缓存)
|
|
@@ -3195,13 +3229,19 @@ function toWslMountPath(windowsPath) {
|
|
|
3195
3229
|
return `/mnt/${match[1].toLowerCase()}/${match[2]}`;
|
|
3196
3230
|
}
|
|
3197
3231
|
|
|
3198
|
-
function syncFileToWsl(windowsPath, wslDestPath) {
|
|
3232
|
+
function syncFileToWsl(windowsPath, wslDestPath, target = {}) {
|
|
3199
3233
|
if (process.platform !== 'win32' || !wslDestPath) return false;
|
|
3200
3234
|
const wslSrc = toWslMountPath(windowsPath);
|
|
3201
3235
|
if (!wslSrc) return false;
|
|
3202
3236
|
|
|
3203
3237
|
const wslDir = path.posix.dirname(wslDestPath);
|
|
3204
|
-
|
|
3238
|
+
const args = [];
|
|
3239
|
+
const distro = String(target.distro || target.wslDistro || '').trim();
|
|
3240
|
+
const user = String(target.user || target.wslUser || '').trim();
|
|
3241
|
+
if (distro) args.push('-d', distro);
|
|
3242
|
+
if (user) args.push('-u', user);
|
|
3243
|
+
args.push('--', 'bash', '-lc', `mkdir -p ${shellQuote(wslDir)} && cp ${shellQuote(wslSrc)} ${shellQuote(wslDestPath)}`);
|
|
3244
|
+
execFileSync('wsl', args, {
|
|
3205
3245
|
timeout: 10000,
|
|
3206
3246
|
stdio: 'pipe'
|
|
3207
3247
|
});
|
|
@@ -3742,35 +3782,124 @@ function getHermesEnvPath() {
|
|
|
3742
3782
|
return path.join(getHermesDataDir(), '.env');
|
|
3743
3783
|
}
|
|
3744
3784
|
|
|
3745
|
-
function
|
|
3785
|
+
function normalizeHermesWslOptions(options = {}) {
|
|
3786
|
+
return {
|
|
3787
|
+
user: String(options.wslUser || options['wsl-user'] || '').trim(),
|
|
3788
|
+
distro: String(options.wslDistro || options['wsl-distro'] || '').trim(),
|
|
3789
|
+
hermesHome: String(options.hermesHome || options['hermes-home'] || options.hermesDataDir || '').trim()
|
|
3790
|
+
};
|
|
3791
|
+
}
|
|
3792
|
+
|
|
3793
|
+
function hasWslFile(filePath, target = {}) {
|
|
3794
|
+
if (!filePath) return false;
|
|
3795
|
+
const quoted = `'${escapeSingleQuotedShell(filePath)}'`;
|
|
3796
|
+
const result = runWslCommand(`test -f ${quoted} && echo yes`, { timeout: 5000 }, target);
|
|
3797
|
+
return result.ok && (result.output || '').trim() === 'yes';
|
|
3798
|
+
}
|
|
3799
|
+
|
|
3800
|
+
function hasWslDir(dirPath, target = {}) {
|
|
3801
|
+
if (!dirPath) return false;
|
|
3802
|
+
const quoted = `'${escapeSingleQuotedShell(dirPath)}'`;
|
|
3803
|
+
const result = runWslCommand(`test -d ${quoted} && echo yes`, { timeout: 5000 }, target);
|
|
3804
|
+
return result.ok && (result.output || '').trim() === 'yes';
|
|
3805
|
+
}
|
|
3806
|
+
|
|
3807
|
+
function probeHermesWslCommand(target = {}) {
|
|
3808
|
+
const result = runWslCommand(
|
|
3809
|
+
'command -v hermes 2>/dev/null || { test -x "$HOME/.local/bin/hermes" && echo "$HOME/.local/bin/hermes"; } || true',
|
|
3810
|
+
{ timeout: 5000 },
|
|
3811
|
+
target
|
|
3812
|
+
);
|
|
3813
|
+
return result.ok ? (result.output || '').trim() : '';
|
|
3814
|
+
}
|
|
3815
|
+
|
|
3816
|
+
function buildHermesWslCandidate(target = {}, explicitHermesHome = '') {
|
|
3817
|
+
const user = String(target.user || '').trim();
|
|
3818
|
+
const distro = String(target.distro || '').trim();
|
|
3819
|
+
const home = explicitHermesHome
|
|
3820
|
+
? ''
|
|
3821
|
+
: (getWslHome({ user, distro }) || (user === 'root' ? '/root' : ''));
|
|
3822
|
+
const dataDir = explicitHermesHome || (home ? path.posix.join(home, '.hermes') : '');
|
|
3823
|
+
if (!dataDir) return null;
|
|
3824
|
+
return {
|
|
3825
|
+
target: { user, distro },
|
|
3826
|
+
dataDir,
|
|
3827
|
+
configPath: path.posix.join(dataDir, 'config.yaml'),
|
|
3828
|
+
legacyConfigPath: path.posix.join(dataDir, 'config.yml'),
|
|
3829
|
+
envPath: path.posix.join(dataDir, '.env')
|
|
3830
|
+
};
|
|
3831
|
+
}
|
|
3832
|
+
|
|
3833
|
+
function scoreHermesWslCandidate(candidate) {
|
|
3834
|
+
if (!candidate) return { score: -1, commandPath: '', sourceConfigPath: null };
|
|
3835
|
+
const commandPath = probeHermesWslCommand(candidate.target);
|
|
3836
|
+
const sourceConfigPath = findExistingWslFile(
|
|
3837
|
+
[candidate.configPath, candidate.legacyConfigPath],
|
|
3838
|
+
candidate.target
|
|
3839
|
+
);
|
|
3840
|
+
let score = 0;
|
|
3841
|
+
if (commandPath) score += 4;
|
|
3842
|
+
if (sourceConfigPath) score += 3;
|
|
3843
|
+
if (hasWslFile(candidate.envPath, candidate.target)) score += 1;
|
|
3844
|
+
if (hasWslDir(candidate.dataDir, candidate.target)) score += 1;
|
|
3845
|
+
return { score, commandPath, sourceConfigPath };
|
|
3846
|
+
}
|
|
3847
|
+
|
|
3848
|
+
function getHermesWslMirrorInfo(options = {}) {
|
|
3746
3849
|
if (process.platform !== 'win32' || !isWslAvailable()) {
|
|
3747
3850
|
return {
|
|
3748
3851
|
dataDir: null,
|
|
3749
3852
|
sourceConfigPath: null,
|
|
3750
3853
|
configPath: null,
|
|
3751
|
-
envPath: null
|
|
3854
|
+
envPath: null,
|
|
3855
|
+
target: null
|
|
3752
3856
|
};
|
|
3753
3857
|
}
|
|
3754
3858
|
|
|
3755
|
-
const
|
|
3756
|
-
const
|
|
3757
|
-
const
|
|
3758
|
-
|
|
3759
|
-
|
|
3760
|
-
|
|
3859
|
+
const normalized = normalizeHermesWslOptions(options);
|
|
3860
|
+
const candidates = [];
|
|
3861
|
+
const seen = new Set();
|
|
3862
|
+
const addCandidate = (candidate) => {
|
|
3863
|
+
if (!candidate) return;
|
|
3864
|
+
const key = `${candidate.target.distro}|${candidate.target.user}|${candidate.dataDir}`;
|
|
3865
|
+
if (seen.has(key)) return;
|
|
3866
|
+
seen.add(key);
|
|
3867
|
+
candidates.push(candidate);
|
|
3868
|
+
};
|
|
3869
|
+
|
|
3870
|
+
if (normalized.hermesHome || normalized.user || normalized.distro) {
|
|
3871
|
+
addCandidate(buildHermesWslCandidate({
|
|
3872
|
+
user: normalized.user,
|
|
3873
|
+
distro: normalized.distro
|
|
3874
|
+
}, normalized.hermesHome));
|
|
3875
|
+
}
|
|
3876
|
+
|
|
3877
|
+
addCandidate(buildHermesWslCandidate({ distro: normalized.distro }, ''));
|
|
3878
|
+
addCandidate(buildHermesWslCandidate({ user: 'root', distro: normalized.distro }, normalized.hermesHome && !normalized.user ? normalized.hermesHome : ''));
|
|
3879
|
+
|
|
3880
|
+
const scored = candidates
|
|
3881
|
+
.map(candidate => ({ candidate, ...scoreHermesWslCandidate(candidate) }))
|
|
3882
|
+
.sort((a, b) => b.score - a.score);
|
|
3883
|
+
const selected = scored.find(item => item.score > 0) || scored[0];
|
|
3884
|
+
const candidate = selected?.candidate || buildHermesWslCandidate({}, '') || buildHermesWslCandidate({ user: 'root' }, '/root/.hermes');
|
|
3885
|
+
const sourceConfigPath = selected?.sourceConfigPath || findExistingWslFile([
|
|
3886
|
+
candidate.configPath,
|
|
3887
|
+
candidate.legacyConfigPath
|
|
3888
|
+
], candidate.target);
|
|
3761
3889
|
|
|
3762
3890
|
return {
|
|
3763
|
-
dataDir,
|
|
3891
|
+
dataDir: candidate.dataDir,
|
|
3764
3892
|
sourceConfigPath,
|
|
3765
|
-
configPath:
|
|
3766
|
-
envPath:
|
|
3893
|
+
configPath: candidate.configPath,
|
|
3894
|
+
envPath: candidate.envPath,
|
|
3895
|
+
target: candidate.target
|
|
3767
3896
|
};
|
|
3768
3897
|
}
|
|
3769
3898
|
|
|
3770
|
-
function readWslTextFile(filePath) {
|
|
3899
|
+
function readWslTextFile(filePath, target = {}) {
|
|
3771
3900
|
if (process.platform !== 'win32' || !filePath) return '';
|
|
3772
3901
|
const quoted = shellQuote(filePath);
|
|
3773
|
-
const result =
|
|
3902
|
+
const result = runWslCommand(`cat ${quoted} 2>/dev/null`, { timeout: 10000 }, target);
|
|
3774
3903
|
return result.ok ? (result.output || result.stdout || '') : '';
|
|
3775
3904
|
}
|
|
3776
3905
|
|
|
@@ -5723,7 +5852,12 @@ async function activateHermes(paths, args = {}) {
|
|
|
5723
5852
|
const typeLabel = selectedType === 'codex' ? 'GPT' : 'Claude';
|
|
5724
5853
|
const hermesBaseUrl = buildFullUrl(selectedEndpoint.url, selectedType === 'codex' ? 'codex' : 'claude');
|
|
5725
5854
|
const writeSpinner = ora({ text: '正在写入 Hermes 配置...', spinner: 'dots' }).start();
|
|
5726
|
-
const hermesPaths = writeHermesConfig(hermesBaseUrl, apiKey, selectedModel.id, {
|
|
5855
|
+
const hermesPaths = writeHermesConfig(hermesBaseUrl, apiKey, selectedModel.id, {
|
|
5856
|
+
type: selectedType,
|
|
5857
|
+
hermesHome: args['hermes-home'] || args.hermesHome,
|
|
5858
|
+
wslUser: args['wsl-user'] || args.wslUser,
|
|
5859
|
+
wslDistro: args['wsl-distro'] || args.wslDistro
|
|
5860
|
+
});
|
|
5727
5861
|
writeSpinner.succeed('Hermes 配置写入完成');
|
|
5728
5862
|
|
|
5729
5863
|
console.log(chalk.green('\n✅ Hermes 配置完成!'));
|
|
@@ -5736,10 +5870,14 @@ async function activateHermes(paths, args = {}) {
|
|
|
5736
5870
|
console.log(chalk.gray(` • ${hermesPaths.configPath}`));
|
|
5737
5871
|
console.log(chalk.gray(` • ${hermesPaths.envPath}`));
|
|
5738
5872
|
if (hermesPaths.wslConfigPath && hermesPaths.wslEnvPath) {
|
|
5739
|
-
|
|
5873
|
+
const targetLabel = hermesPaths.wslUser
|
|
5874
|
+
? `WSL ${hermesPaths.wslUser} 用户`
|
|
5875
|
+
: 'WSL 默认用户';
|
|
5876
|
+
console.log(chalk.gray(` • 已额外同步到 ${targetLabel}: ${hermesPaths.wslConfigPath}`));
|
|
5740
5877
|
}
|
|
5741
5878
|
console.log(chalk.yellow('\n 提示: Hermes doctor 当前会固定检查官方 Anthropic /v1/models,不会读取 model.base_url;第三方 Anthropic 中转可能被误报为 invalid API key'));
|
|
5742
5879
|
console.log(chalk.yellow(' 建议: 以 yymaxapi 的 Hermes CLI 运行时测试,或 `hermes chat -Q -q "请只回复 OK"` 的结果为准'));
|
|
5880
|
+
console.log(chalk.yellow(' 如通过飞书/Telegram/Discord 调用,请重启网关: `hermes gateway restart` 或 `hermes gateway run`'));
|
|
5743
5881
|
|
|
5744
5882
|
if (await confirmImmediateTest(args, '是否立即测试 Hermes CLI 连接?')) {
|
|
5745
5883
|
await testAdditionalCliConnections(args, { only: ['hermes'] });
|
|
@@ -13,8 +13,8 @@
|
|
|
13
13
|
```json5
|
|
14
14
|
{
|
|
15
15
|
"endpoints": [
|
|
16
|
-
{ "name": "默认主节点", "url": "https://yunyi.
|
|
17
|
-
{ "name": "CF国外节点1", "url": "https://cdn2.yunyi.
|
|
16
|
+
{ "name": "默认主节点", "url": "https://yunyi.yun" },
|
|
17
|
+
{ "name": "CF国外节点1", "url": "https://cdn2.yunyi.yun" }
|
|
18
18
|
],
|
|
19
19
|
"fallbackEndpoints": [
|
|
20
20
|
{ "name": "备用节点1", "url": "http://47.99.42.193" },
|
|
@@ -75,7 +75,7 @@ npx yymaxapi@latest
|
|
|
75
75
|
```json
|
|
76
76
|
{
|
|
77
77
|
"provider": "anthropic",
|
|
78
|
-
"base_url": "https://yunyi.
|
|
78
|
+
"base_url": "https://yunyi.yun/claude",
|
|
79
79
|
"api": "anthropic-messages",
|
|
80
80
|
"api_key": "<你的云翼 API Key>",
|
|
81
81
|
"model": {
|
|
@@ -90,7 +90,7 @@ npx yymaxapi@latest
|
|
|
90
90
|
```json
|
|
91
91
|
{
|
|
92
92
|
"provider": "openai",
|
|
93
|
-
"base_url": "https://yunyi.
|
|
93
|
+
"base_url": "https://yunyi.yun/codex",
|
|
94
94
|
"api": "openai-completions",
|
|
95
95
|
"api_key": "<你的云翼 API Key>",
|
|
96
96
|
"model": {
|
|
@@ -121,7 +121,7 @@ npx yymaxapi@latest
|
|
|
121
121
|
```json
|
|
122
122
|
{
|
|
123
123
|
"provider": "anthropic",
|
|
124
|
-
"base_url": "https://yunyi.
|
|
124
|
+
"base_url": "https://yunyi.yun/claude",
|
|
125
125
|
"api": "anthropic-messages",
|
|
126
126
|
"api_key": "<你的云翼 API Key>",
|
|
127
127
|
"model": {
|
|
@@ -136,7 +136,7 @@ npx yymaxapi@latest
|
|
|
136
136
|
```json
|
|
137
137
|
{
|
|
138
138
|
"provider": "openai",
|
|
139
|
-
"base_url": "https://yunyi.
|
|
139
|
+
"base_url": "https://yunyi.yun/codex",
|
|
140
140
|
"api": "openai-completions",
|
|
141
141
|
"api_key": "<你的云翼 API Key>",
|
|
142
142
|
"model": {
|
|
@@ -152,10 +152,10 @@ npx yymaxapi@latest
|
|
|
152
152
|
|
|
153
153
|
```json
|
|
154
154
|
{
|
|
155
|
-
"apiBaseUrl": "https://yunyi.
|
|
155
|
+
"apiBaseUrl": "https://yunyi.yun/claude",
|
|
156
156
|
"env": {
|
|
157
157
|
"ANTHROPIC_API_KEY": "<你的云翼 API Key>",
|
|
158
|
-
"ANTHROPIC_BASE_URL": "https://yunyi.
|
|
158
|
+
"ANTHROPIC_BASE_URL": "https://yunyi.yun/claude"
|
|
159
159
|
}
|
|
160
160
|
}
|
|
161
161
|
```
|