feat: 添加定时健康检查供应商类型选择功能

类似启用代理的提供商,现在可以选择对哪些供应商类型进行定时健康检查

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
Wenaixi 2026-03-30 23:28:19 +08:00
parent 21c92ff214
commit 1bc193f5eb
4 changed files with 81 additions and 1 deletions

View file

@ -1759,7 +1759,17 @@ export class ProviderPoolManager {
this._log('info', '[ScheduledHealthCheck] Starting scheduled health checks on all providers...');
// Get selected provider types, if empty/undefined then check all
const selectedProviderTypes = scheduledConfig?.providerTypes;
const checkAllTypes = !selectedProviderTypes || selectedProviderTypes.length === 0;
for (const providerType in this.providerStatus) {
// Filter by selected provider types if specified
if (!checkAllTypes && !selectedProviderTypes.includes(providerType)) {
this._log('debug', `[ScheduledHealthCheck] Skipping provider type ${providerType}: not in selected types`);
continue;
}
for (const provider of this.providerStatus[providerType]) {
// Skip manually disabled providers
if (provider.config.isDisabled === true) {

View file

@ -251,6 +251,21 @@ async function loadConfiguration() {
if (scheduledHealthCheckIntervalEl) scheduledHealthCheckIntervalEl.value = 600000;
}
// 加载定时健康检查的供应商选择
const scheduledHealthCheckProvidersEl = document.getElementById('scheduledHealthCheckProviders');
if (scheduledHealthCheckProvidersEl) {
const enabledProviders = data.SCHEDULED_HEALTH_CHECK?.providerTypes || [];
const tags = scheduledHealthCheckProvidersEl.querySelectorAll('.provider-tag');
tags.forEach(tag => {
const value = tag.getAttribute('data-value');
if (enabledProviders.includes(value)) {
tag.classList.add('selected');
} else {
tag.classList.remove('selected');
}
});
}
// 定时健康检查间隔快捷按钮(防止重复绑定)
const intervalQuickBtns = document.querySelectorAll('#scheduledHealthCheckInterval + .quick-select-btns button');
intervalQuickBtns.forEach(btn => {
@ -377,10 +392,17 @@ async function saveConfiguration() {
}
// 定时健康检查配置
const scheduledHealthCheckProvidersEl = document.getElementById('scheduledHealthCheckProviders');
const scheduledHealthCheckProviderTypes = scheduledHealthCheckProvidersEl
? Array.from(scheduledHealthCheckProvidersEl.querySelectorAll('.provider-tag.selected'))
.map(tag => tag.getAttribute('data-value'))
: [];
config.SCHEDULED_HEALTH_CHECK = {
enabled: document.getElementById('scheduledHealthCheckEnabled')?.checked !== false,
startupRun: document.getElementById('scheduledHealthCheckStartupRun')?.checked !== false,
interval: parseInt(document.getElementById('scheduledHealthCheckInterval')?.value || 600000)
interval: parseInt(document.getElementById('scheduledHealthCheckInterval')?.value || 600000),
providerTypes: scheduledHealthCheckProviderTypes
};
try {

View file

@ -348,6 +348,8 @@ const translations = {
'config.healthCheck.startupRun': '启动时运行',
'config.healthCheck.interval': '检查间隔',
'config.healthCheck.intervalNote': '单位毫秒最小60000ms(1分钟)最大3600000ms(1小时),可手动输入或点击快捷按钮',
'config.healthCheck.providerTypes': '定时检查的供应商',
'config.healthCheck.providerTypesNote': '选择需要进行定时健康检查的供应商类型,留空则检查所有供应商',
'config.log.title': '日志设置',
'config.log.enabled': '启用日志',
'config.log.outputMode': '日志输出模式',

View file

@ -259,6 +259,52 @@
</div>
<small class="form-text" data-i18n="config.healthCheck.intervalNote">单位毫秒最小60000ms(1分钟)最大3600000ms(1小时)</small>
</div>
<div class="form-group">
<label data-i18n="config.healthCheck.providerTypes">定时检查的供应商</label>
<div id="scheduledHealthCheckProviders" class="provider-tags">
<button type="button" class="provider-tag" data-value="gemini-cli-oauth">
<i class="fas fa-robot"></i>
<span>Gemini CLI OAuth</span>
</button>
<button type="button" class="provider-tag" data-value="gemini-antigravity">
<i class="fas fa-rocket"></i>
<span>Gemini Antigravity</span>
</button>
<button type="button" class="provider-tag" data-value="openai-custom">
<i class="fas fa-brain"></i>
<span>OpenAI Custom</span>
</button>
<button type="button" class="provider-tag" data-value="claude-custom">
<i class="fas fa-comment-dots"></i>
<span>Claude Custom</span>
</button>
<button type="button" class="provider-tag" data-value="claude-kiro-oauth">
<i class="fas fa-key"></i>
<span>Claude Kiro OAuth</span>
</button>
<button type="button" class="provider-tag" data-value="openai-qwen-oauth">
<i class="fas fa-cloud"></i>
<span>Qwen OAuth</span>
</button>
<button type="button" class="provider-tag" data-value="openaiResponses-custom">
<i class="fas fa-reply"></i>
<span>OpenAI Responses</span>
</button>
<button type="button" class="provider-tag" data-value="openai-iflow">
<i class="fas fa-stream"></i>
<span>iFlow OAuth</span>
</button>
<button type="button" class="provider-tag" data-value="openai-codex-oauth">
<i class="fas fa-code"></i>
<span>OpenAI Codex OAuth</span>
</button>
<button type="button" class="provider-tag" data-value="grok-custom">
<i class="fas fa-search"></i>
<span>Grok Reverse</span>
</button>
</div>
<small class="form-text" data-i18n="config.healthCheck.providerTypesNote">选择需要进行定时健康检查的供应商类型</small>
</div>
</div>
<!-- 日志管理 -->