Skip to content

Commit c18e0f0

Browse files
committed
feat: 御坂·高P工程准则
fix(web-ui): silence claude model list fetch errors
1 parent 0daa554 commit c18e0f0

2 files changed

Lines changed: 55 additions & 16 deletions

File tree

web-ui/app.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -495,6 +495,14 @@ document.addEventListener('DOMContentLoaded', () => {
495495
console.error('加载 Claude 配置失败:', e);
496496
}
497497
}
498+
if (!this.currentClaudeConfig) {
499+
const claudeConfigNames = Object.keys(this.claudeConfigs || {});
500+
if (claudeConfigNames.length > 0) {
501+
this.currentClaudeConfig = claudeConfigNames[0];
502+
const initialClaudeConfig = this.claudeConfigs[this.currentClaudeConfig];
503+
this.currentClaudeModel = initialClaudeConfig && initialClaudeConfig.model ? initialClaudeConfig.model : '';
504+
}
505+
}
498506
const normalizeOpenclawConfigs = (configs) => {
499507
const source = configs && typeof configs === 'object' && !Array.isArray(configs)
500508
? configs

web-ui/modules/app.methods.startup-claude.mjs

Lines changed: 47 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -330,14 +330,22 @@ export function createStartupClaudeMethods(options = {}) {
330330
}
331331
return;
332332
}
333-
this.currentClaudeConfig = '';
334-
this.currentClaudeModel = '';
335-
this.resetClaudeModelsState();
336-
if (!silent) {
337-
const tip = res && res.exists
338-
? '当前 Claude settings.json 与本地配置不匹配,已取消选中'
339-
: '未检测到 Claude settings.json,已取消选中';
340-
this.showMessage(tip, 'info');
333+
{
334+
const configNames = Object.keys(this.claudeConfigs || {});
335+
const current = typeof this.currentClaudeConfig === 'string' ? this.currentClaudeConfig.trim() : '';
336+
const fallback = current && this.claudeConfigs && this.claudeConfigs[current]
337+
? current
338+
: (configNames[0] || '');
339+
if (!fallback) {
340+
this.currentClaudeConfig = '';
341+
this.currentClaudeModel = '';
342+
this.resetClaudeModelsState();
343+
return;
344+
}
345+
if (this.currentClaudeConfig !== fallback) {
346+
this.currentClaudeConfig = fallback;
347+
}
348+
this.refreshClaudeModelContext({ silentError: silentModelError });
341349
}
342350
} catch (e) {
343351
if (!silent) {
@@ -382,7 +390,6 @@ export function createStartupClaudeMethods(options = {}) {
382390
},
383391

384392
async loadClaudeModels(options = {}) {
385-
const silentError = !!options.silentError;
386393
const config = this.getCurrentClaudeConfig();
387394
const requestSeq = (Number(this.claudeModelsRequestSeq) || 0) + 1;
388395
this.claudeModelsRequestSeq = requestSeq;
@@ -414,7 +421,32 @@ export function createStartupClaudeMethods(options = {}) {
414421
return;
415422
}
416423

417-
this.claudeModelsLoading = true;
424+
const cache = typeof globalThis !== 'undefined'
425+
? (globalThis.__codexmateClaudeModelsCache || (globalThis.__codexmateClaudeModelsCache = new Map()))
426+
: new Map();
427+
const cacheKey = baseUrl;
428+
const ttlMs = 2 * 60 * 1000;
429+
const now = Date.now();
430+
const cached = cache.get(cacheKey);
431+
const cachedOk = cached
432+
&& Number.isFinite(cached.ts)
433+
&& now - cached.ts < ttlMs
434+
&& Array.isArray(cached.models);
435+
if (cachedOk) {
436+
this.claudeModels = cached.models;
437+
this.claudeModelsSource = cached.source || 'remote';
438+
if (this.claudeModels.length) {
439+
this.updateClaudeModelsCurrent();
440+
} else {
441+
this.claudeModelsHasCurrent = true;
442+
}
443+
this.claudeModelsLoading = false;
444+
} else if (localCatalog.length) {
445+
this.claudeModels = localCatalog;
446+
this.claudeModelsSource = 'catalog';
447+
this.updateClaudeModelsCurrent();
448+
this.claudeModelsLoading = false;
449+
}
418450
const isLatestRequest = () => {
419451
if (requestSeq !== Number(this.claudeModelsRequestSeq || 0)) {
420452
return false;
@@ -431,6 +463,9 @@ export function createStartupClaudeMethods(options = {}) {
431463
&& (latestConfig.apiKey || '').trim() === apiKey
432464
&& (typeof latestConfig.externalCredentialType === 'string' ? latestConfig.externalCredentialType.trim() : '') === externalCredentialType;
433465
};
466+
if (cachedOk) {
467+
return;
468+
}
434469
try {
435470
const res = await api('models-by-url', { baseUrl, apiKey });
436471
if (!isLatestRequest()) {
@@ -440,12 +475,10 @@ export function createStartupClaudeMethods(options = {}) {
440475
this.claudeModels = [];
441476
this.claudeModelsSource = 'unlimited';
442477
this.claudeModelsHasCurrent = true;
478+
cache.set(cacheKey, { ts: Date.now(), models: [], source: 'unlimited' });
443479
return;
444480
}
445481
if (res.error) {
446-
if (!silentError) {
447-
this.showMessage('获取模型列表失败', 'error');
448-
}
449482
this.claudeModels = [];
450483
this.claudeModelsSource = 'error';
451484
this.claudeModelsHasCurrent = true;
@@ -455,13 +488,11 @@ export function createStartupClaudeMethods(options = {}) {
455488
this.claudeModels = list;
456489
this.claudeModelsSource = res.source || 'remote';
457490
this.updateClaudeModelsCurrent();
491+
cache.set(cacheKey, { ts: Date.now(), models: list, source: this.claudeModelsSource });
458492
} catch (_) {
459493
if (!isLatestRequest()) {
460494
return;
461495
}
462-
if (!silentError) {
463-
this.showMessage('获取模型列表失败', 'error');
464-
}
465496
this.claudeModels = [];
466497
this.claudeModelsSource = 'error';
467498
this.claudeModelsHasCurrent = true;

0 commit comments

Comments
 (0)