From 0b7bfc1ca5e3dbe1e7469c89ea342a2949dc0407 Mon Sep 17 00:00:00 2001 From: NessZerra <90105158+Finesssee@users.noreply.github.com> Date: Sat, 19 Sep 2026 03:27:56 +0700 Subject: [PATCH 1/2] Expose OpenCode Go monthly metric --- .../sections/MenuBarMetricSection.test.tsx | 13 +++++++++---- .../providers/sections/MenuBarMetricSection.tsx | 7 +++++-- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/apps/desktop-tauri/src/surfaces/settings/providers/sections/MenuBarMetricSection.test.tsx b/apps/desktop-tauri/src/surfaces/settings/providers/sections/MenuBarMetricSection.test.tsx index 295d0b9350..8518b51794 100644 --- a/apps/desktop-tauri/src/surfaces/settings/providers/sections/MenuBarMetricSection.test.tsx +++ b/apps/desktop-tauri/src/surfaces/settings/providers/sections/MenuBarMetricSection.test.tsx @@ -50,22 +50,27 @@ function rateWindow(usedPercent: number) { } describe("MenuBarMetricSection", () => { - it("offers Monthly for OpenCode Go only after a tertiary window is observed", () => { + it("offers Monthly for OpenCode Go before a tertiary window is observed", () => { const base = provider(false); base.id = "opencodego"; base.displayName = "OpenCode Go"; base.tertiary = null; + const onChange = vi.fn(); const { rerender } = render( key} - onChange={vi.fn()} + onChange={onChange} />, ); - expect(screen.queryByRole("option", { name: "DetailWindowTertiary" })).not.toBeInTheDocument(); + expect(screen.getByRole("option", { name: "ProviderMonthly" })).toBeInTheDocument(); + fireEvent.change(screen.getByRole("combobox"), { target: { value: "tertiary" } }); + expect(onChange).toHaveBeenCalledWith({ + providerMetrics: { opencodego: "tertiary" }, + }); const observed = { ...base, tertiary: rateWindow(37) }; rerender( @@ -78,7 +83,7 @@ describe("MenuBarMetricSection", () => { />, ); - expect(screen.getByRole("option", { name: "DetailWindowTertiary" })).toBeInTheDocument(); + expect(screen.getByRole("option", { name: "ProviderMonthly" })).toBeInTheDocument(); }); it("offers extra usage when a provider has extra rate windows", () => { const onChange = vi.fn(); diff --git a/apps/desktop-tauri/src/surfaces/settings/providers/sections/MenuBarMetricSection.tsx b/apps/desktop-tauri/src/surfaces/settings/providers/sections/MenuBarMetricSection.tsx index 92f7c4f5c2..5058b3946a 100644 --- a/apps/desktop-tauri/src/surfaces/settings/providers/sections/MenuBarMetricSection.tsx +++ b/apps/desktop-tauri/src/surfaces/settings/providers/sections/MenuBarMetricSection.tsx @@ -87,8 +87,11 @@ function metricOptions( if (provider.modelSpecific) { options.push({ value: "model", label: t("DetailWindowModelSpecific") }); } - if (provider.tertiary) { - options.push({ value: "tertiary", label: t("DetailWindowTertiary") }); + if (provider.tertiary || provider.id === "opencodego") { + options.push({ + value: "tertiary", + label: provider.id === "opencodego" ? t("ProviderMonthly") : t("DetailWindowTertiary"), + }); } if (provider.id === "cursor" || provider.extraRateWindows.length > 0) { options.push({ value: "extraUsage", label: t("ExtraUsage") }); From e0325667ef43712277b99754ce7a6328fc3c6c71 Mon Sep 17 00:00:00 2001 From: NessZerra <90105158+Finesssee@users.noreply.github.com> Date: Sun, 20 Sep 2026 23:32:38 +0700 Subject: [PATCH 2/2] Share OpenCode Go monthly label through provider metadata --- .../src-tauri/src/commands/provider_detail.rs | 4 ++++ .../sections/MenuBarMetricSection.test.tsx | 21 ++++++++++++++++++- .../sections/MenuBarMetricSection.tsx | 6 ++++-- apps/desktop-tauri/src/types/bridge.ts | 2 ++ rust/src/core/provider.rs | 4 ++++ rust/src/providers/abacus/mod.rs | 1 + rust/src/providers/aiand/mod.rs | 1 + rust/src/providers/alibaba/mod.rs | 1 + rust/src/providers/alibabatokenplan/mod.rs | 1 + rust/src/providers/amp/mod.rs | 1 + rust/src/providers/antigravity/mod.rs | 1 + rust/src/providers/augment/mod.rs | 1 + rust/src/providers/azureopenai.rs | 1 + rust/src/providers/bedrock/mod.rs | 1 + rust/src/providers/chutes/mod.rs | 1 + rust/src/providers/claude/mod.rs | 1 + rust/src/providers/clinepass/mod.rs | 1 + rust/src/providers/codebuddy/mod.rs | 1 + rust/src/providers/codebuff/mod.rs | 1 + rust/src/providers/codex/mod.rs | 1 + rust/src/providers/commandcode/mod.rs | 1 + rust/src/providers/copilot/mod.rs | 1 + rust/src/providers/crof/mod.rs | 1 + rust/src/providers/crossmodel/mod.rs | 1 + rust/src/providers/cursor/mod.rs | 1 + rust/src/providers/deepgram/mod.rs | 1 + rust/src/providers/deepinfra/mod.rs | 1 + rust/src/providers/deepseek/mod.rs | 1 + rust/src/providers/devin/mod.rs | 1 + rust/src/providers/doubao/mod.rs | 1 + rust/src/providers/elevenlabs/mod.rs | 1 + rust/src/providers/factory/mod.rs | 1 + rust/src/providers/fireworks/mod.rs | 1 + rust/src/providers/gemini/mod.rs | 1 + rust/src/providers/grok/mod.rs | 1 + rust/src/providers/groq/mod.rs | 1 + rust/src/providers/infini.rs | 1 + rust/src/providers/jetbrains/mod.rs | 1 + rust/src/providers/kilo/mod.rs | 1 + rust/src/providers/kimi/mod.rs | 1 + rust/src/providers/kimik2/mod.rs | 1 + rust/src/providers/kiro/mod.rs | 1 + rust/src/providers/litellm/mod.rs | 1 + rust/src/providers/llmproxy/mod.rs | 1 + rust/src/providers/longcat/mod.rs | 1 + rust/src/providers/manus/mod.rs | 1 + rust/src/providers/meta/mod.rs | 1 + rust/src/providers/mimo/mod.rs | 1 + rust/src/providers/minimax/mod.rs | 1 + rust/src/providers/mistral/mod.rs | 1 + rust/src/providers/nanogpt/mod.rs | 1 + rust/src/providers/neuralwatt/mod.rs | 1 + rust/src/providers/notion/mod.rs | 1 + rust/src/providers/ollama/mod.rs | 1 + rust/src/providers/openaiapi/mod.rs | 1 + rust/src/providers/opencode/mod.rs | 1 + rust/src/providers/opencodego/mod.rs | 1 + rust/src/providers/openrouter/mod.rs | 1 + rust/src/providers/perplexity/mod.rs | 1 + rust/src/providers/poe/mod.rs | 1 + rust/src/providers/qoder/mod.rs | 1 + rust/src/providers/qwencloud/mod.rs | 1 + rust/src/providers/sakana/mod.rs | 1 + rust/src/providers/stepfun/mod.rs | 1 + rust/src/providers/sub2api/mod.rs | 1 + rust/src/providers/t3chat.rs | 1 + rust/src/providers/venice/mod.rs | 1 + rust/src/providers/vertexai/mod.rs | 1 + rust/src/providers/warp/mod.rs | 1 + rust/src/providers/wayfinder.rs | 1 + rust/src/providers/windsurf/mod.rs | 1 + rust/src/providers/xai/mod.rs | 1 + rust/src/providers/zai/mod.rs | 1 + rust/src/providers/zed/mod.rs | 1 + rust/src/providers/zenmux/mod.rs | 1 + rust/src/providers/zoommate/mod.rs | 1 + 76 files changed, 105 insertions(+), 3 deletions(-) diff --git a/apps/desktop-tauri/src-tauri/src/commands/provider_detail.rs b/apps/desktop-tauri/src-tauri/src/commands/provider_detail.rs index 7690a5b2aa..7baa254db7 100644 --- a/apps/desktop-tauri/src-tauri/src/commands/provider_detail.rs +++ b/apps/desktop-tauri/src-tauri/src/commands/provider_detail.rs @@ -25,6 +25,9 @@ pub struct ProviderDetail { pub weekly: Option, pub model_specific: Option, pub tertiary: Option, + /// Locale key naming the tertiary lane when it carries a semantic label + /// beyond "Tertiary" (upstream F5). Drives the settings metric picker. + pub tertiary_label_key: Option<&'static str>, pub extra_rate_windows: Vec, // Cost / pace. @@ -90,6 +93,7 @@ pub(crate) fn build_provider_detail(provider_id: &str) -> Result { - it("offers Monthly for OpenCode Go before a tertiary window is observed", () => { + it("renders the provider-declared tertiary label key before observation", () => { const base = provider(false); base.id = "opencodego"; base.displayName = "OpenCode Go"; base.tertiary = null; + base.tertiaryLabelKey = "ProviderMonthly"; const onChange = vi.fn(); const { rerender } = render( { expect(screen.getByRole("option", { name: "ProviderMonthly" })).toBeInTheDocument(); }); + + it("keeps the generic tertiary label when no provider key is declared", () => { + const base = provider(false); + base.tertiary = rateWindow(37); + + render( + key} + onChange={vi.fn()} + />, + ); + + expect(screen.getByRole("option", { name: "DetailWindowTertiary" })).toBeInTheDocument(); + }); + it("offers extra usage when a provider has extra rate windows", () => { const onChange = vi.fn(); render( diff --git a/apps/desktop-tauri/src/surfaces/settings/providers/sections/MenuBarMetricSection.tsx b/apps/desktop-tauri/src/surfaces/settings/providers/sections/MenuBarMetricSection.tsx index 5058b3946a..7bc89e0d7d 100644 --- a/apps/desktop-tauri/src/surfaces/settings/providers/sections/MenuBarMetricSection.tsx +++ b/apps/desktop-tauri/src/surfaces/settings/providers/sections/MenuBarMetricSection.tsx @@ -87,10 +87,12 @@ function metricOptions( if (provider.modelSpecific) { options.push({ value: "model", label: t("DetailWindowModelSpecific") }); } - if (provider.tertiary || provider.id === "opencodego") { + if (provider.tertiary || provider.tertiaryLabelKey) { options.push({ value: "tertiary", - label: provider.id === "opencodego" ? t("ProviderMonthly") : t("DetailWindowTertiary"), + label: t( + (provider.tertiaryLabelKey ?? "DetailWindowTertiary") as LocaleKey, + ), }); } if (provider.id === "cursor" || provider.extraRateWindows.length > 0) { diff --git a/apps/desktop-tauri/src/types/bridge.ts b/apps/desktop-tauri/src/types/bridge.ts index 865625efeb..642db9c6c7 100644 --- a/apps/desktop-tauri/src/types/bridge.ts +++ b/apps/desktop-tauri/src/types/bridge.ts @@ -887,6 +887,8 @@ export interface ProviderDetail { weekly: RateWindowSnapshot | null; modelSpecific: RateWindowSnapshot | null; tertiary: RateWindowSnapshot | null; + /** Locale key for the tertiary metric lane when it carries a semantic label (upstream F5). */ + tertiaryLabelKey?: string | null; extraRateWindows: Array<{ id: string; title: string; diff --git a/rust/src/core/provider.rs b/rust/src/core/provider.rs index 55ab70d391..6931de57ee 100755 --- a/rust/src/core/provider.rs +++ b/rust/src/core/provider.rs @@ -550,6 +550,10 @@ pub struct ProviderMetadata { pub is_primary: bool, pub dashboard_url: Option<&'static str>, pub status_page_url: Option<&'static str>, + /// Locale key shown for the provider's tertiary metric lane in settings + /// pickers when the lane carries a semantic identity beyond "Tertiary" + /// (upstream F5). `None` renders the generic tertiary label. + pub tertiary_label_key: Option<&'static str>, } /// Errors that can occur when fetching provider data diff --git a/rust/src/providers/abacus/mod.rs b/rust/src/providers/abacus/mod.rs index 0363d87bd5..b59dd8eb32 100644 --- a/rust/src/providers/abacus/mod.rs +++ b/rust/src/providers/abacus/mod.rs @@ -62,6 +62,7 @@ impl AbacusProvider { is_primary: false, dashboard_url: Some("https://apps.abacus.ai/app/billing"), status_page_url: None, + tertiary_label_key: None, }, client: crate::core::credentialed_http_client_builder() .timeout(std::time::Duration::from_secs(30)) diff --git a/rust/src/providers/aiand/mod.rs b/rust/src/providers/aiand/mod.rs index e47c960ae7..005e45a78c 100644 --- a/rust/src/providers/aiand/mod.rs +++ b/rust/src/providers/aiand/mod.rs @@ -144,6 +144,7 @@ impl AiAndProvider { is_primary: false, dashboard_url: Some("https://console.aiand.com"), status_page_url: None, + tertiary_label_key: None, }, client: crate::core::credentialed_http_client_builder() .timeout(std::time::Duration::from_secs(15)) diff --git a/rust/src/providers/alibaba/mod.rs b/rust/src/providers/alibaba/mod.rs index fb6e8a7168..1f8d7d5f4c 100644 --- a/rust/src/providers/alibaba/mod.rs +++ b/rust/src/providers/alibaba/mod.rs @@ -45,6 +45,7 @@ impl AlibabaProvider { is_primary: false, dashboard_url: Some("https://modelstudio.console.alibabacloud.com"), status_page_url: None, + tertiary_label_key: None, }, } } diff --git a/rust/src/providers/alibabatokenplan/mod.rs b/rust/src/providers/alibabatokenplan/mod.rs index 1a96decbd0..32f4083b4e 100644 --- a/rust/src/providers/alibabatokenplan/mod.rs +++ b/rust/src/providers/alibabatokenplan/mod.rs @@ -74,6 +74,7 @@ impl AlibabaTokenPlanProvider { is_primary: false, dashboard_url: Some(DEFAULT_DASHBOARD_URL), status_page_url: Some("https://status.aliyun.com"), + tertiary_label_key: None, }, } } diff --git a/rust/src/providers/amp/mod.rs b/rust/src/providers/amp/mod.rs index 4051f1596d..d248d22d38 100755 --- a/rust/src/providers/amp/mod.rs +++ b/rust/src/providers/amp/mod.rs @@ -37,6 +37,7 @@ impl AmpProvider { is_primary: false, dashboard_url: Some("https://ampcode.com/settings/usage"), status_page_url: Some("https://sourcegraphstatus.com"), + tertiary_label_key: None, }, } } diff --git a/rust/src/providers/antigravity/mod.rs b/rust/src/providers/antigravity/mod.rs index 6864b17f9d..c769e5e832 100755 --- a/rust/src/providers/antigravity/mod.rs +++ b/rust/src/providers/antigravity/mod.rs @@ -121,6 +121,7 @@ impl AntigravityProvider { is_primary: false, dashboard_url: None, status_page_url: None, + tertiary_label_key: None, }, } } diff --git a/rust/src/providers/augment/mod.rs b/rust/src/providers/augment/mod.rs index 388746ef75..761c247d31 100755 --- a/rust/src/providers/augment/mod.rs +++ b/rust/src/providers/augment/mod.rs @@ -44,6 +44,7 @@ impl AugmentProvider { is_primary: false, dashboard_url: Some("https://app.augmentcode.com/account"), status_page_url: Some("https://status.augmentcode.com"), + tertiary_label_key: None, }, } } diff --git a/rust/src/providers/azureopenai.rs b/rust/src/providers/azureopenai.rs index 21acd3cb41..573c40adb4 100644 --- a/rust/src/providers/azureopenai.rs +++ b/rust/src/providers/azureopenai.rs @@ -45,6 +45,7 @@ impl AzureOpenAIProvider { is_primary: false, dashboard_url: Some("https://ai.azure.com"), status_page_url: Some("https://status.azure.com"), + tertiary_label_key: None, }, } } diff --git a/rust/src/providers/bedrock/mod.rs b/rust/src/providers/bedrock/mod.rs index ddf613628f..ad5fdef00b 100644 --- a/rust/src/providers/bedrock/mod.rs +++ b/rust/src/providers/bedrock/mod.rs @@ -117,6 +117,7 @@ impl BedrockProvider { is_primary: false, dashboard_url: Some("https://console.aws.amazon.com/bedrock"), status_page_url: Some("https://health.aws.amazon.com/health/status"), + tertiary_label_key: None, }, client: crate::core::credentialed_http_client_builder() .timeout(std::time::Duration::from_secs(15)) diff --git a/rust/src/providers/chutes/mod.rs b/rust/src/providers/chutes/mod.rs index 222d56f62d..5c69951749 100644 --- a/rust/src/providers/chutes/mod.rs +++ b/rust/src/providers/chutes/mod.rs @@ -29,6 +29,7 @@ impl ChutesProvider { is_primary: false, dashboard_url: Some("https://chutes.ai"), status_page_url: None, + tertiary_label_key: None, }, client: crate::core::credentialed_http_client_builder() .timeout(std::time::Duration::from_secs(15)) diff --git a/rust/src/providers/claude/mod.rs b/rust/src/providers/claude/mod.rs index 75dc76ecd7..b47e770525 100755 --- a/rust/src/providers/claude/mod.rs +++ b/rust/src/providers/claude/mod.rs @@ -138,6 +138,7 @@ impl ClaudeProvider { is_primary: true, dashboard_url: Some("https://claude.ai/settings/usage"), status_page_url: Some("https://status.claude.com/"), + tertiary_label_key: None, }, web_fetcher: ClaudeWebApiFetcher::new(), oauth_fetcher: ClaudeOAuthFetcher::new(), diff --git a/rust/src/providers/clinepass/mod.rs b/rust/src/providers/clinepass/mod.rs index a354765976..0884c57d8c 100644 --- a/rust/src/providers/clinepass/mod.rs +++ b/rust/src/providers/clinepass/mod.rs @@ -56,6 +56,7 @@ impl ClinePassProvider { is_primary: false, dashboard_url: Some("https://app.cline.bot/dashboard/subscription?personal=true"), status_page_url: None, + tertiary_label_key: None, }, client: crate::core::credentialed_http_client_builder() .timeout(std::time::Duration::from_secs(15)) diff --git a/rust/src/providers/codebuddy/mod.rs b/rust/src/providers/codebuddy/mod.rs index eae0fd2faa..3fc1322615 100644 --- a/rust/src/providers/codebuddy/mod.rs +++ b/rust/src/providers/codebuddy/mod.rs @@ -84,6 +84,7 @@ impl CodeBuddyProvider { is_primary: false, dashboard_url: Some("https://www.codebuddy.cn/profile/plans-usage"), status_page_url: None, + tertiary_label_key: None, }, client: crate::core::credentialed_http_client_builder() .timeout(std::time::Duration::from_secs(20)) diff --git a/rust/src/providers/codebuff/mod.rs b/rust/src/providers/codebuff/mod.rs index d0e00fa257..e26fc572bd 100644 --- a/rust/src/providers/codebuff/mod.rs +++ b/rust/src/providers/codebuff/mod.rs @@ -41,6 +41,7 @@ impl CodebuffProvider { is_primary: false, dashboard_url: Some("https://www.codebuff.com/usage"), status_page_url: None, + tertiary_label_key: None, }, client: crate::core::credentialed_http_client_builder() .timeout(std::time::Duration::from_secs(30)) diff --git a/rust/src/providers/codex/mod.rs b/rust/src/providers/codex/mod.rs index 88c11ec984..99175da309 100755 --- a/rust/src/providers/codex/mod.rs +++ b/rust/src/providers/codex/mod.rs @@ -38,6 +38,7 @@ impl CodexProvider { is_primary: true, dashboard_url: Some("https://chatgpt.com/codex/settings/usage"), status_page_url: Some("https://status.openai.com"), + tertiary_label_key: None, }, api: CodexApi::new(), } diff --git a/rust/src/providers/commandcode/mod.rs b/rust/src/providers/commandcode/mod.rs index 1f8f5cfd06..c4739369dd 100644 --- a/rust/src/providers/commandcode/mod.rs +++ b/rust/src/providers/commandcode/mod.rs @@ -112,6 +112,7 @@ impl CommandCodeProvider { is_primary: false, dashboard_url: Some("https://commandcode.ai"), status_page_url: None, + tertiary_label_key: None, }, client: crate::core::credentialed_http_client_builder() .timeout(std::time::Duration::from_secs(15)) diff --git a/rust/src/providers/copilot/mod.rs b/rust/src/providers/copilot/mod.rs index ffca7d978e..dd96858695 100755 --- a/rust/src/providers/copilot/mod.rs +++ b/rust/src/providers/copilot/mod.rs @@ -34,6 +34,7 @@ impl CopilotProvider { is_primary: false, dashboard_url: Some("https://github.com/settings/copilot"), status_page_url: Some("https://www.githubstatus.com/"), + tertiary_label_key: None, }, api: CopilotApi::new(), } diff --git a/rust/src/providers/crof/mod.rs b/rust/src/providers/crof/mod.rs index 25b6990488..4abef6b4ca 100644 --- a/rust/src/providers/crof/mod.rs +++ b/rust/src/providers/crof/mod.rs @@ -43,6 +43,7 @@ impl CrofProvider { is_primary: false, dashboard_url: Some("https://crof.ai"), status_page_url: None, + tertiary_label_key: None, }, client: crate::core::credentialed_http_client_builder() .timeout(std::time::Duration::from_secs(15)) diff --git a/rust/src/providers/crossmodel/mod.rs b/rust/src/providers/crossmodel/mod.rs index 0f23cdb730..41ef871cd4 100644 --- a/rust/src/providers/crossmodel/mod.rs +++ b/rust/src/providers/crossmodel/mod.rs @@ -68,6 +68,7 @@ impl CrossModelProvider { is_primary: false, dashboard_url: Some("https://crossmodel.ai"), status_page_url: None, + tertiary_label_key: None, }, client: crate::core::credentialed_http_client_builder() .timeout(std::time::Duration::from_secs(15)) diff --git a/rust/src/providers/cursor/mod.rs b/rust/src/providers/cursor/mod.rs index ef1caa1bc2..ec8437fa42 100755 --- a/rust/src/providers/cursor/mod.rs +++ b/rust/src/providers/cursor/mod.rs @@ -37,6 +37,7 @@ impl CursorProvider { is_primary: false, dashboard_url: Some("https://cursor.com/dashboard/usage"), status_page_url: None, + tertiary_label_key: None, }, api: CursorApi::new(), } diff --git a/rust/src/providers/deepgram/mod.rs b/rust/src/providers/deepgram/mod.rs index eed4bfec4a..026ca48776 100644 --- a/rust/src/providers/deepgram/mod.rs +++ b/rust/src/providers/deepgram/mod.rs @@ -85,6 +85,7 @@ impl DeepgramProvider { is_primary: false, dashboard_url: Some("https://console.deepgram.com/usage"), status_page_url: Some("https://status.deepgram.com"), + tertiary_label_key: None, }, client: crate::core::credentialed_http_client_builder() .timeout(std::time::Duration::from_secs(15)) diff --git a/rust/src/providers/deepinfra/mod.rs b/rust/src/providers/deepinfra/mod.rs index b8ab5e2600..c34f7fc171 100644 --- a/rust/src/providers/deepinfra/mod.rs +++ b/rust/src/providers/deepinfra/mod.rs @@ -156,6 +156,7 @@ impl DeepInfraProvider { is_primary: false, dashboard_url: Some("https://deepinfra.com/dash"), status_page_url: Some("https://status.deepinfra.com"), + tertiary_label_key: None, }, client: crate::core::credentialed_http_client_builder() .timeout(std::time::Duration::from_secs(30)) diff --git a/rust/src/providers/deepseek/mod.rs b/rust/src/providers/deepseek/mod.rs index 1ff6683c4d..dc5b005fef 100644 --- a/rust/src/providers/deepseek/mod.rs +++ b/rust/src/providers/deepseek/mod.rs @@ -136,6 +136,7 @@ impl DeepSeekProvider { is_primary: false, dashboard_url: Some("https://platform.deepseek.com/usage"), status_page_url: Some("https://status.deepseek.com"), + tertiary_label_key: None, }, client: crate::core::credentialed_http_client_builder() .timeout(std::time::Duration::from_secs(30)) diff --git a/rust/src/providers/devin/mod.rs b/rust/src/providers/devin/mod.rs index 316c5a1510..3b3ed462c3 100644 --- a/rust/src/providers/devin/mod.rs +++ b/rust/src/providers/devin/mod.rs @@ -31,6 +31,7 @@ impl DevinProvider { is_primary: false, dashboard_url: Some("https://app.devin.ai/settings/billing"), status_page_url: None, + tertiary_label_key: None, }, client: crate::core::credentialed_http_client_builder() .timeout(std::time::Duration::from_secs(15)) diff --git a/rust/src/providers/doubao/mod.rs b/rust/src/providers/doubao/mod.rs index f448fd7f9f..b11e6e34ad 100644 --- a/rust/src/providers/doubao/mod.rs +++ b/rust/src/providers/doubao/mod.rs @@ -48,6 +48,7 @@ impl DoubaoProvider { "https://console.volcengine.com/ark/region:ark+cn-beijing/usage", ), status_page_url: None, + tertiary_label_key: None, }, client: crate::core::credentialed_http_client_builder() .timeout(std::time::Duration::from_secs(15)) diff --git a/rust/src/providers/elevenlabs/mod.rs b/rust/src/providers/elevenlabs/mod.rs index a7baf54af2..0f7e126deb 100644 --- a/rust/src/providers/elevenlabs/mod.rs +++ b/rust/src/providers/elevenlabs/mod.rs @@ -59,6 +59,7 @@ impl ElevenLabsProvider { is_primary: false, dashboard_url: Some("https://elevenlabs.io/app/settings/api-keys"), status_page_url: Some("https://status.elevenlabs.io"), + tertiary_label_key: None, }, client: crate::core::credentialed_http_client_builder() .timeout(std::time::Duration::from_secs(15)) diff --git a/rust/src/providers/factory/mod.rs b/rust/src/providers/factory/mod.rs index b95b0d7db1..f10eb85c33 100755 --- a/rust/src/providers/factory/mod.rs +++ b/rust/src/providers/factory/mod.rs @@ -388,6 +388,7 @@ impl FactoryProvider { is_primary: false, dashboard_url: Some("https://app.factory.ai"), status_page_url: Some("https://status.factory.ai"), + tertiary_label_key: None, }, } } diff --git a/rust/src/providers/fireworks/mod.rs b/rust/src/providers/fireworks/mod.rs index 7e2b7231c8..0286a5a9c4 100644 --- a/rust/src/providers/fireworks/mod.rs +++ b/rust/src/providers/fireworks/mod.rs @@ -199,6 +199,7 @@ impl FireworksProvider { is_primary: false, dashboard_url: Some("https://app.fireworks.ai"), status_page_url: None, + tertiary_label_key: None, }, client: crate::core::credentialed_http_client_builder() .timeout(std::time::Duration::from_secs(15)) diff --git a/rust/src/providers/gemini/mod.rs b/rust/src/providers/gemini/mod.rs index 30364c234e..aea2c3574c 100755 --- a/rust/src/providers/gemini/mod.rs +++ b/rust/src/providers/gemini/mod.rs @@ -34,6 +34,7 @@ impl GeminiProvider { is_primary: false, dashboard_url: Some("https://aistudio.google.com"), status_page_url: Some("https://status.cloud.google.com"), + tertiary_label_key: None, }, api: GeminiApi::new(), } diff --git a/rust/src/providers/grok/mod.rs b/rust/src/providers/grok/mod.rs index a6fba75287..976ba76b04 100644 --- a/rust/src/providers/grok/mod.rs +++ b/rust/src/providers/grok/mod.rs @@ -46,6 +46,7 @@ impl GrokProvider { is_primary: false, dashboard_url: Some("https://grok.com/?_s=usage"), status_page_url: Some("https://status.x.ai"), + tertiary_label_key: None, }, client: crate::core::credentialed_http_client_builder() .timeout(std::time::Duration::from_secs(15)) diff --git a/rust/src/providers/groq/mod.rs b/rust/src/providers/groq/mod.rs index fb0da5a6b3..156447ba34 100644 --- a/rust/src/providers/groq/mod.rs +++ b/rust/src/providers/groq/mod.rs @@ -75,6 +75,7 @@ impl GroqProvider { is_primary: false, dashboard_url: Some("https://console.groq.com/settings/metrics"), status_page_url: Some("https://status.groq.com"), + tertiary_label_key: None, }, client: crate::core::credentialed_http_client_builder() .timeout(std::time::Duration::from_secs(15)) diff --git a/rust/src/providers/infini.rs b/rust/src/providers/infini.rs index 839c3461d7..766d5d8798 100644 --- a/rust/src/providers/infini.rs +++ b/rust/src/providers/infini.rs @@ -304,6 +304,7 @@ impl InfiniProvider { is_primary: false, dashboard_url: Some("https://cloud.infini-ai.com"), status_page_url: None, + tertiary_label_key: None, }, client: InfiniClient::new(api_key), } diff --git a/rust/src/providers/jetbrains/mod.rs b/rust/src/providers/jetbrains/mod.rs index 3e5d29060a..9ebf6d16f3 100755 --- a/rust/src/providers/jetbrains/mod.rs +++ b/rust/src/providers/jetbrains/mod.rs @@ -35,6 +35,7 @@ impl JetBrainsProvider { is_primary: false, dashboard_url: Some("https://www.jetbrains.com/ai/"), status_page_url: None, + tertiary_label_key: None, }, } } diff --git a/rust/src/providers/kilo/mod.rs b/rust/src/providers/kilo/mod.rs index db39158569..5aa8bd330a 100644 --- a/rust/src/providers/kilo/mod.rs +++ b/rust/src/providers/kilo/mod.rs @@ -45,6 +45,7 @@ impl KiloProvider { is_primary: false, dashboard_url: Some("https://app.kilo.ai/usage"), status_page_url: None, + tertiary_label_key: None, }, client: crate::core::credentialed_http_client_builder() .timeout(std::time::Duration::from_secs(30)) diff --git a/rust/src/providers/kimi/mod.rs b/rust/src/providers/kimi/mod.rs index ef74d214b7..b9427da00d 100755 --- a/rust/src/providers/kimi/mod.rs +++ b/rust/src/providers/kimi/mod.rs @@ -206,6 +206,7 @@ impl KimiProvider { is_primary: false, dashboard_url: Some("https://kimi.moonshot.cn"), status_page_url: None, + tertiary_label_key: None, }, } } diff --git a/rust/src/providers/kimik2/mod.rs b/rust/src/providers/kimik2/mod.rs index cc9e2b085b..2814431c2f 100755 --- a/rust/src/providers/kimik2/mod.rs +++ b/rust/src/providers/kimik2/mod.rs @@ -159,6 +159,7 @@ impl KimiK2Provider { is_primary: false, dashboard_url: Some("https://platform.moonshot.ai/console/account"), status_page_url: None, + tertiary_label_key: None, }, } } diff --git a/rust/src/providers/kiro/mod.rs b/rust/src/providers/kiro/mod.rs index 7b4bb6cc88..73193b3f85 100755 --- a/rust/src/providers/kiro/mod.rs +++ b/rust/src/providers/kiro/mod.rs @@ -62,6 +62,7 @@ impl KiroProvider { is_primary: false, dashboard_url: Some("https://kiro.dev/account"), status_page_url: Some("https://health.aws.amazon.com"), + tertiary_label_key: None, }, } } diff --git a/rust/src/providers/litellm/mod.rs b/rust/src/providers/litellm/mod.rs index c30e039b18..d27a573668 100644 --- a/rust/src/providers/litellm/mod.rs +++ b/rust/src/providers/litellm/mod.rs @@ -28,6 +28,7 @@ impl LiteLLMProvider { is_primary: false, dashboard_url: None, status_page_url: None, + tertiary_label_key: None, }, client: crate::core::credentialed_http_client_builder() .timeout(std::time::Duration::from_secs(15)) diff --git a/rust/src/providers/llmproxy/mod.rs b/rust/src/providers/llmproxy/mod.rs index 230ee0ce79..f820cbc4b4 100644 --- a/rust/src/providers/llmproxy/mod.rs +++ b/rust/src/providers/llmproxy/mod.rs @@ -102,6 +102,7 @@ impl LLMProxyProvider { is_primary: false, dashboard_url: None, status_page_url: None, + tertiary_label_key: None, }, client: crate::core::credentialed_http_client_builder() .timeout(std::time::Duration::from_secs(15)) diff --git a/rust/src/providers/longcat/mod.rs b/rust/src/providers/longcat/mod.rs index 449c37c887..f3ef3f6ce4 100644 --- a/rust/src/providers/longcat/mod.rs +++ b/rust/src/providers/longcat/mod.rs @@ -38,6 +38,7 @@ impl LongCatProvider { is_primary: false, dashboard_url: Some("https://longcat.chat/platform/"), status_page_url: None, + tertiary_label_key: None, }, // Isolated cookie-free client — auth is only the explicit Cookie header. client: crate::core::credentialed_http_client_builder() diff --git a/rust/src/providers/manus/mod.rs b/rust/src/providers/manus/mod.rs index 73bc90ba35..4d4a816896 100644 --- a/rust/src/providers/manus/mod.rs +++ b/rust/src/providers/manus/mod.rs @@ -59,6 +59,7 @@ impl ManusProvider { is_primary: false, dashboard_url: Some("https://manus.im"), status_page_url: None, + tertiary_label_key: None, }, client: crate::core::credentialed_http_client_builder() .timeout(std::time::Duration::from_secs(15)) diff --git a/rust/src/providers/meta/mod.rs b/rust/src/providers/meta/mod.rs index b405e4aa17..be02405a16 100644 --- a/rust/src/providers/meta/mod.rs +++ b/rust/src/providers/meta/mod.rs @@ -51,6 +51,7 @@ impl MetaProvider { is_primary: false, dashboard_url: Some("https://dev.meta.ai/docs"), status_page_url: None, + tertiary_label_key: None, }, client: crate::core::credentialed_http_client_builder() .timeout(std::time::Duration::from_secs(15)) diff --git a/rust/src/providers/mimo/mod.rs b/rust/src/providers/mimo/mod.rs index e2b163a139..d95709a22b 100644 --- a/rust/src/providers/mimo/mod.rs +++ b/rust/src/providers/mimo/mod.rs @@ -91,6 +91,7 @@ impl MiMoProvider { is_primary: false, dashboard_url: Some("https://platform.xiaomimimo.com/#/console/balance"), status_page_url: None, + tertiary_label_key: None, }, client: crate::core::credentialed_http_client_builder() .timeout(std::time::Duration::from_secs(15)) diff --git a/rust/src/providers/minimax/mod.rs b/rust/src/providers/minimax/mod.rs index b47992664e..8a1dd03a23 100755 --- a/rust/src/providers/minimax/mod.rs +++ b/rust/src/providers/minimax/mod.rs @@ -196,6 +196,7 @@ impl MiniMaxProvider { "https://platform.minimax.io/user-center/payment/coding-plan?cycle_type=3", ), status_page_url: None, + tertiary_label_key: None, }, } } diff --git a/rust/src/providers/mistral/mod.rs b/rust/src/providers/mistral/mod.rs index 5fb8bdf2a3..20fece275e 100644 --- a/rust/src/providers/mistral/mod.rs +++ b/rust/src/providers/mistral/mod.rs @@ -166,6 +166,7 @@ impl MistralProvider { is_primary: false, dashboard_url: Some("https://admin.mistral.ai/organization/usage"), status_page_url: Some("https://status.mistral.ai"), + tertiary_label_key: None, }, client: crate::core::credentialed_http_client_builder() .timeout(std::time::Duration::from_secs(30)) diff --git a/rust/src/providers/nanogpt/mod.rs b/rust/src/providers/nanogpt/mod.rs index 53347c8d83..9a4941124d 100644 --- a/rust/src/providers/nanogpt/mod.rs +++ b/rust/src/providers/nanogpt/mod.rs @@ -74,6 +74,7 @@ impl NanoGPTProvider { is_primary: false, dashboard_url: Some("https://nano-gpt.com/usage"), status_page_url: None, + tertiary_label_key: None, }, } } diff --git a/rust/src/providers/neuralwatt/mod.rs b/rust/src/providers/neuralwatt/mod.rs index 907350df62..acc7d94525 100644 --- a/rust/src/providers/neuralwatt/mod.rs +++ b/rust/src/providers/neuralwatt/mod.rs @@ -92,6 +92,7 @@ impl NeuralwattProvider { is_primary: false, dashboard_url: Some("https://portal.neuralwatt.com/dashboard"), status_page_url: None, + tertiary_label_key: None, }, client: crate::core::credentialed_http_client_builder() .timeout(std::time::Duration::from_secs(15)) diff --git a/rust/src/providers/notion/mod.rs b/rust/src/providers/notion/mod.rs index e4e7be75ca..c917e3b399 100644 --- a/rust/src/providers/notion/mod.rs +++ b/rust/src/providers/notion/mod.rs @@ -143,6 +143,7 @@ impl NotionProvider { is_primary: false, dashboard_url: Some(DASHBOARD_URL), status_page_url: Some(STATUS_PAGE_URL), + tertiary_label_key: None, }, } } diff --git a/rust/src/providers/ollama/mod.rs b/rust/src/providers/ollama/mod.rs index d3e3d8eb8a..561330100c 100755 --- a/rust/src/providers/ollama/mod.rs +++ b/rust/src/providers/ollama/mod.rs @@ -53,6 +53,7 @@ impl OllamaProvider { is_primary: false, dashboard_url: Some("https://ollama.com/settings"), status_page_url: None, + tertiary_label_key: None, }, } } diff --git a/rust/src/providers/openaiapi/mod.rs b/rust/src/providers/openaiapi/mod.rs index 004025eace..91e5abf697 100644 --- a/rust/src/providers/openaiapi/mod.rs +++ b/rust/src/providers/openaiapi/mod.rs @@ -110,6 +110,7 @@ impl OpenAIApiProvider { is_primary: false, dashboard_url: Some("https://platform.openai.com/usage"), status_page_url: Some("https://status.openai.com"), + tertiary_label_key: None, }, client: crate::core::credentialed_http_client_builder() .timeout(std::time::Duration::from_secs(15)) diff --git a/rust/src/providers/opencode/mod.rs b/rust/src/providers/opencode/mod.rs index 5e714f024b..63c205e802 100755 --- a/rust/src/providers/opencode/mod.rs +++ b/rust/src/providers/opencode/mod.rs @@ -51,6 +51,7 @@ impl OpenCodeProvider { is_primary: false, dashboard_url: Some("https://opencode.ai"), status_page_url: None, + tertiary_label_key: None, }, client: crate::core::credentialed_http_client_builder() .timeout(std::time::Duration::from_secs(30)) diff --git a/rust/src/providers/opencodego/mod.rs b/rust/src/providers/opencodego/mod.rs index 62d0ca09d8..0e3f49d38f 100644 --- a/rust/src/providers/opencodego/mod.rs +++ b/rust/src/providers/opencodego/mod.rs @@ -55,6 +55,7 @@ impl OpenCodeGoProvider { is_primary: false, dashboard_url: Some("https://opencode.ai"), status_page_url: None, + tertiary_label_key: Some("ProviderMonthly"), }, client: crate::core::credentialed_http_client_builder() .timeout(std::time::Duration::from_secs(30)) diff --git a/rust/src/providers/openrouter/mod.rs b/rust/src/providers/openrouter/mod.rs index 7accc49f52..ae021ea761 100755 --- a/rust/src/providers/openrouter/mod.rs +++ b/rust/src/providers/openrouter/mod.rs @@ -124,6 +124,7 @@ impl OpenRouterProvider { is_primary: false, dashboard_url: Some("https://openrouter.ai/activity"), status_page_url: Some("https://status.openrouter.ai"), + tertiary_label_key: None, }, } } diff --git a/rust/src/providers/perplexity/mod.rs b/rust/src/providers/perplexity/mod.rs index 99ddc3ee2b..06fbb1c9da 100644 --- a/rust/src/providers/perplexity/mod.rs +++ b/rust/src/providers/perplexity/mod.rs @@ -62,6 +62,7 @@ impl PerplexityProvider { is_primary: false, dashboard_url: Some("https://www.perplexity.ai/account/usage"), status_page_url: None, + tertiary_label_key: None, }, client: crate::core::credentialed_http_client_builder() .timeout(std::time::Duration::from_secs(30)) diff --git a/rust/src/providers/poe/mod.rs b/rust/src/providers/poe/mod.rs index d4548ced6f..e88b4f6c16 100644 --- a/rust/src/providers/poe/mod.rs +++ b/rust/src/providers/poe/mod.rs @@ -46,6 +46,7 @@ impl PoeProvider { is_primary: false, dashboard_url: Some("https://poe.com/settings/subscription"), status_page_url: None, + tertiary_label_key: None, }, client: crate::core::credentialed_http_client_builder() .timeout(std::time::Duration::from_secs(15)) diff --git a/rust/src/providers/qoder/mod.rs b/rust/src/providers/qoder/mod.rs index 17abe9d7d3..a7478375d2 100644 --- a/rust/src/providers/qoder/mod.rs +++ b/rust/src/providers/qoder/mod.rs @@ -35,6 +35,7 @@ impl QoderProvider { is_primary: false, dashboard_url: Some("https://qoder.com/account/usage"), status_page_url: None, + tertiary_label_key: None, }, client: crate::core::credentialed_http_client_builder() .timeout(std::time::Duration::from_secs(15)) diff --git a/rust/src/providers/qwencloud/mod.rs b/rust/src/providers/qwencloud/mod.rs index 760f37c443..ac5db1bf7a 100644 --- a/rust/src/providers/qwencloud/mod.rs +++ b/rust/src/providers/qwencloud/mod.rs @@ -81,6 +81,7 @@ impl QwenCloudProvider { is_primary: false, dashboard_url: Some(DASHBOARD_URL), status_page_url: Some(STATUS_PAGE_URL), + tertiary_label_key: None, }, } } diff --git a/rust/src/providers/sakana/mod.rs b/rust/src/providers/sakana/mod.rs index b6b66fb1dd..bc379c8dbb 100644 --- a/rust/src/providers/sakana/mod.rs +++ b/rust/src/providers/sakana/mod.rs @@ -35,6 +35,7 @@ impl SakanaProvider { is_primary: false, dashboard_url: Some(BILLING_URL), status_page_url: None, + tertiary_label_key: None, }, client: crate::core::credentialed_http_client_builder() .timeout(std::time::Duration::from_secs(15)) diff --git a/rust/src/providers/stepfun/mod.rs b/rust/src/providers/stepfun/mod.rs index f0a66473e7..4f9a875cb8 100644 --- a/rust/src/providers/stepfun/mod.rs +++ b/rust/src/providers/stepfun/mod.rs @@ -85,6 +85,7 @@ impl StepFunProvider { is_primary: false, dashboard_url: Some("https://platform.stepfun.com/dashboard"), status_page_url: None, + tertiary_label_key: None, }, client: crate::core::credentialed_http_client_builder() .timeout(std::time::Duration::from_secs(15)) diff --git a/rust/src/providers/sub2api/mod.rs b/rust/src/providers/sub2api/mod.rs index e738e8700b..569b0ff33f 100644 --- a/rust/src/providers/sub2api/mod.rs +++ b/rust/src/providers/sub2api/mod.rs @@ -159,6 +159,7 @@ impl Sub2ApiProvider { is_primary: false, dashboard_url: None, status_page_url: None, + tertiary_label_key: None, }, client: crate::core::credentialed_http_client_builder() .timeout(std::time::Duration::from_secs(15)) diff --git a/rust/src/providers/t3chat.rs b/rust/src/providers/t3chat.rs index 29e5ac0a45..a8697cc1bf 100644 --- a/rust/src/providers/t3chat.rs +++ b/rust/src/providers/t3chat.rs @@ -64,6 +64,7 @@ impl T3ChatProvider { is_primary: false, dashboard_url: Some("https://t3.chat/settings/customization"), status_page_url: None, + tertiary_label_key: None, }, } } diff --git a/rust/src/providers/venice/mod.rs b/rust/src/providers/venice/mod.rs index 9ff20acf44..95952163bc 100644 --- a/rust/src/providers/venice/mod.rs +++ b/rust/src/providers/venice/mod.rs @@ -48,6 +48,7 @@ impl VeniceProvider { is_primary: false, dashboard_url: Some("https://venice.ai/settings/api"), status_page_url: None, + tertiary_label_key: None, }, client: crate::core::credentialed_http_client_builder() .timeout(std::time::Duration::from_secs(15)) diff --git a/rust/src/providers/vertexai/mod.rs b/rust/src/providers/vertexai/mod.rs index b0b10e4115..fc6855717d 100755 --- a/rust/src/providers/vertexai/mod.rs +++ b/rust/src/providers/vertexai/mod.rs @@ -39,6 +39,7 @@ impl VertexAIProvider { is_primary: false, dashboard_url: Some("https://console.cloud.google.com/vertex-ai"), status_page_url: Some("https://status.cloud.google.com"), + tertiary_label_key: None, }, } } diff --git a/rust/src/providers/warp/mod.rs b/rust/src/providers/warp/mod.rs index e8e502b77c..ce94d0bbd4 100755 --- a/rust/src/providers/warp/mod.rs +++ b/rust/src/providers/warp/mod.rs @@ -134,6 +134,7 @@ impl WarpProvider { is_primary: false, dashboard_url: Some("https://docs.warp.dev/reference/cli/api-keys"), status_page_url: None, + tertiary_label_key: None, }, } } diff --git a/rust/src/providers/wayfinder.rs b/rust/src/providers/wayfinder.rs index 57ad1c0ceb..0eda54c0cd 100644 --- a/rust/src/providers/wayfinder.rs +++ b/rust/src/providers/wayfinder.rs @@ -179,6 +179,7 @@ impl WayfinderProvider { is_primary: false, dashboard_url: None, status_page_url: None, + tertiary_label_key: None, }, } } diff --git a/rust/src/providers/windsurf/mod.rs b/rust/src/providers/windsurf/mod.rs index eb4a2f798c..79b15c0f32 100644 --- a/rust/src/providers/windsurf/mod.rs +++ b/rust/src/providers/windsurf/mod.rs @@ -67,6 +67,7 @@ impl WindsurfProvider { is_primary: false, dashboard_url: Some("https://windsurf.com/subscription"), status_page_url: Some("https://status.windsurf.com"), + tertiary_label_key: None, }, } } diff --git a/rust/src/providers/xai/mod.rs b/rust/src/providers/xai/mod.rs index 3d9504af42..951279095a 100644 --- a/rust/src/providers/xai/mod.rs +++ b/rust/src/providers/xai/mod.rs @@ -187,6 +187,7 @@ impl XaiProvider { is_primary: false, dashboard_url: Some("https://console.x.ai"), status_page_url: Some("https://status.x.ai"), + tertiary_label_key: None, }, client: crate::core::credentialed_http_client_builder() .timeout(std::time::Duration::from_secs(REQUEST_TIMEOUT_SECS)) diff --git a/rust/src/providers/zai/mod.rs b/rust/src/providers/zai/mod.rs index aca7e29702..44d71c19da 100755 --- a/rust/src/providers/zai/mod.rs +++ b/rust/src/providers/zai/mod.rs @@ -126,6 +126,7 @@ impl ZaiProvider { is_primary: false, dashboard_url: Some("https://z.ai/manage-apikey/coding-plan/personal/my-plan"), status_page_url: None, + tertiary_label_key: None, }, } } diff --git a/rust/src/providers/zed/mod.rs b/rust/src/providers/zed/mod.rs index 58fd5ab939..3e4f3e50f5 100644 --- a/rust/src/providers/zed/mod.rs +++ b/rust/src/providers/zed/mod.rs @@ -29,6 +29,7 @@ impl ZedProvider { is_primary: false, dashboard_url: Some("https://zed.dev/account"), status_page_url: None, + tertiary_label_key: None, }, client: crate::core::credentialed_http_client_builder() .timeout(std::time::Duration::from_secs(15)) diff --git a/rust/src/providers/zenmux/mod.rs b/rust/src/providers/zenmux/mod.rs index c8ac671b76..2fa7645dcf 100644 --- a/rust/src/providers/zenmux/mod.rs +++ b/rust/src/providers/zenmux/mod.rs @@ -83,6 +83,7 @@ impl ZenMuxProvider { is_primary: false, dashboard_url: Some("https://zenmux.ai/platform/management"), status_page_url: None, + tertiary_label_key: None, }, client: crate::core::credentialed_http_client_builder() .timeout(std::time::Duration::from_secs(15)) diff --git a/rust/src/providers/zoommate/mod.rs b/rust/src/providers/zoommate/mod.rs index 8cc31f2e37..a3c10f08ec 100644 --- a/rust/src/providers/zoommate/mod.rs +++ b/rust/src/providers/zoommate/mod.rs @@ -188,6 +188,7 @@ impl ZoomMateProvider { is_primary: false, dashboard_url: Some("https://zoommate.zoom.us/#/?settings=credit-usage"), status_page_url: Some("https://www.zoomstatus.com/"), + tertiary_label_key: None, }, client: crate::core::credentialed_http_client_builder() .timeout(Duration::from_secs(15))