feat: add INVALID_MODEL_ID retry config + detailed request logging
- Config: new InvalidModelRetries field (default 3, range 0-20) - Admin API: /admin/api/general GET/POST for general settings - Admin UI: new "通用设置" card with retry count input - CallKiroAPI: same-endpoint retry on HTTP 400 INVALID_MODEL_ID before falling back to next endpoint - CallKiroAPI: switched to log.Printf with timestamp, account, model, attempt counter, elapsed time, error body truncation
This commit is contained in:
@@ -969,6 +969,17 @@
|
||||
data-i18n-placeholder="settings.apiKeyPlaceholder"><button class="btn btn-sm btn-secondary" onclick="generateApiKey()" data-i18n="settings.generateApiKey"></button></div></div>
|
||||
<button class="btn btn-primary" onclick="saveSettings()" data-i18n="common.save"></button>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="card-header"><span class="card-title" data-i18n="settings.generalSettings"></span></div>
|
||||
<div class="form-group">
|
||||
<label data-i18n="settings.invalidModelRetries"></label>
|
||||
<input type="number" id="invalidModelRetries" min="0" max="20" step="1" placeholder="3">
|
||||
<small style="color:#64748b;font-size:12px;margin-top:4px;display:block"
|
||||
data-i18n="settings.invalidModelRetriesHint"></small>
|
||||
</div>
|
||||
<button class="btn btn-primary" onclick="saveGeneralConfig()"
|
||||
data-i18n="settings.saveGeneral"></button>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="card-header"><span class="card-title" data-i18n="settings.thinkingSettings"></span></div>
|
||||
<div class="form-group">
|
||||
@@ -1123,6 +1134,11 @@
|
||||
'settings.enableApiKey': '启用 API Key 验证',
|
||||
'settings.apiKeyPlaceholder': '留空则不验证',
|
||||
'settings.generateApiKey': '随机生成',
|
||||
'settings.generalSettings': '通用设置',
|
||||
'settings.invalidModelRetries': 'INVALID_MODEL_ID 同端点重试次数',
|
||||
'settings.invalidModelRetriesHint': '当上游返回 INVALID_MODEL_ID(HTTP 400)时,先在当前端点重试 N 次后再 fallback 到下一个端点。默认 3,范围 0-20',
|
||||
'settings.saveGeneral': '保存通用设置',
|
||||
'settings.generalSaved': '通用设置已保存',
|
||||
'settings.thinkingSettings': 'Thinking 模式设置',
|
||||
'settings.thinkingSuffix': '触发后缀',
|
||||
'settings.thinkingSuffixHint': '模型名称加此后缀即启用思考模式,如 claude-sonnet-4.5-thinking',
|
||||
@@ -1329,6 +1345,11 @@
|
||||
'settings.enableApiKey': 'Enable API Key Verification',
|
||||
'settings.apiKeyPlaceholder': 'Leave empty to disable',
|
||||
'settings.generateApiKey': 'Generate',
|
||||
'settings.generalSettings': 'General Settings',
|
||||
'settings.invalidModelRetries': 'INVALID_MODEL_ID same-endpoint retries',
|
||||
'settings.invalidModelRetriesHint': 'When upstream returns INVALID_MODEL_ID (HTTP 400), retry the current endpoint N times before falling back. Default 3, range 0-20',
|
||||
'settings.saveGeneral': 'Save General Settings',
|
||||
'settings.generalSaved': 'General settings saved',
|
||||
'settings.thinkingSettings': 'Thinking Mode Settings',
|
||||
'settings.thinkingSuffix': 'Trigger Suffix',
|
||||
'settings.thinkingSuffixHint': 'Add this suffix to model name to enable thinking mode, e.g. claude-sonnet-4.5-thinking',
|
||||
@@ -1991,6 +2012,7 @@
|
||||
document.getElementById('apiKeyInput').value = d.apiKey || '';
|
||||
loadThinkingConfig();
|
||||
loadEndpointConfig();
|
||||
loadGeneralConfig();
|
||||
}
|
||||
async function loadThinkingConfig() {
|
||||
const res = await fetch('/admin/api/thinking', { headers: { 'X-Admin-Password': password } });
|
||||
@@ -2020,6 +2042,26 @@
|
||||
const d = await res.json();
|
||||
if (d.success) { alert(t('settings.endpointSaved')); } else { alert(t('common.saveFailed') + ': ' + d.error); }
|
||||
}
|
||||
async function loadGeneralConfig() {
|
||||
const res = await fetch('/admin/api/general', { headers: { 'X-Admin-Password': password } });
|
||||
const d = await res.json();
|
||||
const v = (d && typeof d.invalidModelRetries === 'number') ? d.invalidModelRetries : 3;
|
||||
document.getElementById('invalidModelRetries').value = v;
|
||||
}
|
||||
async function saveGeneralConfig() {
|
||||
const raw = document.getElementById('invalidModelRetries').value;
|
||||
const n = parseInt(raw, 10);
|
||||
if (isNaN(n) || n < 0 || n > 20) {
|
||||
alert(t('common.saveFailed') + ': 0-20');
|
||||
return;
|
||||
}
|
||||
const res = await fetch('/admin/api/general', {
|
||||
method: 'POST', headers: { 'Content-Type': 'application/json', 'X-Admin-Password': password },
|
||||
body: JSON.stringify({ invalidModelRetries: n })
|
||||
});
|
||||
const d = await res.json();
|
||||
if (d.success) { alert(t('settings.generalSaved')); } else { alert(t('common.saveFailed') + ': ' + d.error); }
|
||||
}
|
||||
function generateApiKey() {
|
||||
const chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
|
||||
let key = 'sk-';
|
||||
|
||||
Reference in New Issue
Block a user