Spaces:
Running
Running
Add automatic 429 rate limit fallback retry chain across models
Browse files- index.html +17 -19
index.html
CHANGED
|
@@ -667,7 +667,7 @@ function runAiAnalysis() {
|
|
| 667 |
var btnConfirm = document.getElementById('btn-confirm-ai');
|
| 668 |
if (btnConfirm) {
|
| 669 |
btnConfirm.disabled = true;
|
| 670 |
-
setTimeout(function() { btnConfirm.disabled = false; }, 3000);
|
| 671 |
}
|
| 672 |
|
| 673 |
document.getElementById('ai-step-confirm').style.display = 'none';
|
|
@@ -689,39 +689,37 @@ function runAiAnalysis() {
|
|
| 689 |
var payload = {
|
| 690 |
contents: [{ parts: [{ text: prompt }] }],
|
| 691 |
generationConfig: {
|
| 692 |
-
maxOutputTokens: 2000
|
| 693 |
}
|
| 694 |
};
|
| 695 |
|
| 696 |
-
var
|
| 697 |
|
| 698 |
-
function
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 699 |
return fetch(url, {
|
| 700 |
method: 'POST',
|
| 701 |
headers: { 'Content-Type': 'application/json' },
|
| 702 |
body: JSON.stringify(payload)
|
| 703 |
-
})
|
| 704 |
-
}
|
| 705 |
-
|
| 706 |
-
callGemini(apiUrl)
|
| 707 |
-
.then(function(r) {
|
| 708 |
if (!r.ok) {
|
| 709 |
-
if (r.status === 404) {
|
| 710 |
-
|
| 711 |
-
return
|
| 712 |
-
if (!r2.ok) throw new Error('API Error (' + r2.status + ')');
|
| 713 |
-
return r2.json();
|
| 714 |
-
});
|
| 715 |
}
|
| 716 |
return r.text().then(function(errText) {
|
| 717 |
-
if (r.status === 429) {
|
| 718 |
-
throw new Error('Gemini API 用量限制 (429 Rate Limit):您的 API Key 已達請求上限,請稍候 1 分鐘後再試。');
|
| 719 |
-
}
|
| 720 |
throw new Error('Gemini API 錯誤 (' + r.status + '):' + errText.substring(0, 150));
|
| 721 |
});
|
| 722 |
}
|
| 723 |
return r.json();
|
| 724 |
-
})
|
|
|
|
|
|
|
|
|
|
| 725 |
.then(function(d) {
|
| 726 |
document.getElementById('ai-step-analyzing').style.display = 'none';
|
| 727 |
var out = '';
|
|
|
|
| 667 |
var btnConfirm = document.getElementById('btn-confirm-ai');
|
| 668 |
if (btnConfirm) {
|
| 669 |
btnConfirm.disabled = true;
|
| 670 |
+
setTimeout(function() { btnConfirm.disabled = false; }, 3000);
|
| 671 |
}
|
| 672 |
|
| 673 |
document.getElementById('ai-step-confirm').style.display = 'none';
|
|
|
|
| 689 |
var payload = {
|
| 690 |
contents: [{ parts: [{ text: prompt }] }],
|
| 691 |
generationConfig: {
|
| 692 |
+
maxOutputTokens: 2000
|
| 693 |
}
|
| 694 |
};
|
| 695 |
|
| 696 |
+
var modelList = ['gemini-3.6-flash', 'gemini-2.0-flash', 'gemini-1.5-flash'];
|
| 697 |
|
| 698 |
+
function tryModel(index) {
|
| 699 |
+
if (index >= modelList.length) {
|
| 700 |
+
throw new Error('Gemini API 觸發頻率限制 (429 Rate Limit):請至 Google AI Studio 檢查是否已綁定 Pay-As-You-Go 付費信用卡帳號,或稍候 1 分鐘再試。');
|
| 701 |
+
}
|
| 702 |
+
var modelName = modelList[index];
|
| 703 |
+
var url = 'https://generativelanguage.googleapis.com/v1beta/models/' + modelName + ':generateContent?key=' + GEMINI_KEY;
|
| 704 |
return fetch(url, {
|
| 705 |
method: 'POST',
|
| 706 |
headers: { 'Content-Type': 'application/json' },
|
| 707 |
body: JSON.stringify(payload)
|
| 708 |
+
}).then(function(r) {
|
|
|
|
|
|
|
|
|
|
|
|
|
| 709 |
if (!r.ok) {
|
| 710 |
+
if (r.status === 429 || r.status === 404) {
|
| 711 |
+
console.warn('Model ' + modelName + ' returned ' + r.status + ', trying next model...');
|
| 712 |
+
return tryModel(index + 1);
|
|
|
|
|
|
|
|
|
|
| 713 |
}
|
| 714 |
return r.text().then(function(errText) {
|
|
|
|
|
|
|
|
|
|
| 715 |
throw new Error('Gemini API 錯誤 (' + r.status + '):' + errText.substring(0, 150));
|
| 716 |
});
|
| 717 |
}
|
| 718 |
return r.json();
|
| 719 |
+
});
|
| 720 |
+
}
|
| 721 |
+
|
| 722 |
+
tryModel(0)
|
| 723 |
.then(function(d) {
|
| 724 |
document.getElementById('ai-step-analyzing').style.display = 'none';
|
| 725 |
var out = '';
|