Feat/provider individual config (#663)

* refactor(ui): simplify UpdateBadge to minimal dot indicator

* feat(provider): add individual test and proxy config for providers

Add support for provider-specific model test and proxy configurations:

- Add ProviderTestConfig and ProviderProxyConfig types in Rust and TypeScript
- Create ProviderAdvancedConfig component with collapsible panels
- Update stream_check service to merge provider config with global config
- Proxy config UI follows global proxy style (single URL input)

Provider-level configs stored in meta field, no database schema changes needed.

* feat(ui): add failover toggle and improve proxy controls

- Add FailoverToggle component with slide animation
- Simplify ProxyToggle style to match FailoverToggle
- Add usage statistics button when proxy is active
- Fix i18n parameter passing for failover messages
- Add missing failover translation keys (inQueue, addQueue, priority)
- Replace AboutSection icon with app logo

* fix(proxy): support system proxy fallback and provider-level proxy config

- Remove no_proxy() calls in http_client.rs to allow system proxy fallback
- Add get_for_provider() to build HTTP client with provider-specific proxy
- Update forwarder.rs and stream_check.rs to use provider proxy config
- Fix EditProviderDialog.tsx to include provider.meta in useMemo deps
- Add useEffect in ProviderAdvancedConfig.tsx to sync expand state

Fixes #636
Fixes #583

* fix(ui): sync toast theme with app setting

* feat(settings): add log config management

Fixes #612
Fixes #514

* fix(proxy): increase request body size limit to 200MB

Fixes #666

* docs(proxy): update timeout config descriptions and defaults

Fixes #612

* fix(proxy): filter x-goog-api-key header to prevent duplication

* fix(proxy): prevent proxy recursion when system proxy points to localhost

Detect if HTTP_PROXY, HTTPS_PROXY, or ALL_PROXY environment variables
point to loopback addresses (localhost, 127.0.0.1), and bypass system
proxy in such cases to avoid infinite request loops.

* fix(i18n): add providerAdvanced i18n keys and fix failover toast parameter

- Add providerAdvanced.* i18n keys to en.json, zh.json, and ja.json
- Fix failover toggleFailed toast to pass detail parameter
- Remove Chinese fallback text from UI for English/Japanese users

* fix(tray): restore tray-provider events and enable Auto failover properly

- Emit provider-switched event on tray provider click (backward compatibility)
- Auto button now: starts proxy, takes over live config, enables failover

* fix(log): enable dynamic log level and single file mode

- Initialize log at Trace level for dynamic adjustment
- Change rotation strategy to KeepSome(1) for single file
- Set max file size to 1GB
- Delete old log file on startup for clean start

* fix(tray): fix clippy uninlined format args warning

Use inline format arguments: {app_type_str} instead of {}

* fix(provider): allow typing :// in endpoint URL inputs

Change input type from "url" to "text" to prevent browser
URL validation from blocking :// input.

Closes #681

* fix(stream-check): use Gemini native streaming API format

- Change endpoint from OpenAI-compatible to native streamGenerateContent
- Add alt=sse parameter for SSE format response
- Use x-goog-api-key header instead of Bearer token
- Convert request body to Gemini contents/parts format

* feat(proxy): add request logging for debugging

Add debug logs for outgoing requests including URL and body content
with byte size, matching the existing response logging format.

* fix(log): prevent usize underflow in KeepSome rotation strategy

KeepSome(n) internally computes n-2, so n=1 causes underflow.
Use KeepSome(2) as the minimum safe value.
This commit is contained in:
Dex Miller
2026-01-20 21:02:44 +08:00
committed by GitHub
parent 7bb458eecb
commit e7badb1a24
46 changed files with 2008 additions and 331 deletions
+53
View File
@@ -208,6 +208,29 @@
"responseGroup": "Response Rectification",
"thinkingSignature": "Thinking Signature Rectification",
"thinkingSignatureDescription": "Automatically fix Claude API errors caused by thinking signature validation failures"
},
"logConfig": {
"title": "Log Management",
"description": "Control log output level",
"enabled": "Enable Logging",
"enabledDescription": "Master switch, all logging will be disabled when turned off",
"level": "Log Level",
"levelDescription": "Set the minimum log level to output",
"levels": {
"error": "Error",
"warn": "Warning",
"info": "Info",
"debug": "Debug",
"trace": "Trace"
},
"levelHint": "Log level descriptions:",
"levelDesc": {
"error": "Critical errors only",
"warn": "Errors + warnings",
"info": "General operation info (default)",
"debug": "Detailed info including SSE stream and request/response",
"trace": "All logs, most verbose"
}
}
},
"language": "Language",
@@ -427,6 +450,22 @@
"testFailed": "Speed test failed: {{error}}",
"status": "Status: {{code}}"
},
"providerAdvanced": {
"testConfig": "Model Test Config",
"useCustomConfig": "Use separate config",
"testConfigDesc": "Configure separate model testing parameters for this provider. Uses global settings when disabled.",
"testModel": "Test Model",
"testModelPlaceholder": "Leave empty to use global config",
"timeoutSecs": "Timeout (seconds)",
"testPrompt": "Test Prompt",
"degradedThreshold": "Degraded Threshold (ms)",
"maxRetries": "Max Retries",
"proxyConfig": "Proxy Config",
"useCustomProxy": "Use separate proxy",
"proxyConfigDesc": "Configure separate network proxy for this provider. Uses system proxy or global settings when disabled.",
"proxyUsername": "Username (optional)",
"proxyPassword": "Password (optional)"
},
"codexConfig": {
"authJson": "auth.json (JSON) *",
"authJsonPlaceholder": "{\n \"OPENAI_API_KEY\": \"sk-your-api-key-here\"\n}",
@@ -1088,6 +1127,20 @@
"circuitOpen": "Circuit Open",
"consecutiveFailures": "{{count}} consecutive failures"
},
"failover": {
"enabled": "{{app}} failover enabled",
"disabled": "{{app}} failover disabled",
"toggleFailed": "Operation failed: {{detail}}",
"inQueue": "In queue",
"addQueue": "Add",
"priority": {
"tooltip": "Failover priority {{priority}}"
},
"tooltip": {
"enabled": "{{app}} failover enabled\nAutomatically switch to next available provider",
"disabled": "Enable {{app}} failover\nAutomatically switch when current provider fails"
}
},
"proxy": {
"panel": {
"serviceAddress": "Service Address",