@sriinnu/runic 1.2.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +11 -0
- package/README.md +8 -1
- package/RuniciOS/Core/RunicTypographyiOS.swift +24 -0
- package/RuniciOS/Views/ProviderDetailView.swift +9 -9
- package/RuniciOS/Views/ProviderListView.swift +10 -10
- package/RuniciOS/Widgets/LargeWidget.swift +14 -14
- package/RuniciOS/Widgets/LiveActivity.swift +19 -19
- package/RuniciOS/Widgets/LockScreenWidget.swift +15 -15
- package/RuniciOS/Widgets/MediumWidget.swift +10 -10
- package/RuniciOS/Widgets/RunicWidget.swift +5 -5
- package/RuniciOS/Widgets/SmallWidget.swift +9 -9
- package/Sources/Runic/About.swift +3 -3
- package/Sources/Runic/AppNotifications.swift +5 -3
- package/Sources/Runic/Controllers/StatusItemController+Actions.swift +7 -3
- package/Sources/Runic/Controllers/StatusItemController+Animation.swift +5 -4
- package/Sources/Runic/Controllers/StatusItemController+ChartSubmenus.swift +30 -16
- package/Sources/Runic/Controllers/StatusItemController+CustomProviders.swift +6 -3
- package/Sources/Runic/Controllers/StatusItemController+Menu.swift +18 -13
- package/Sources/Runic/Controllers/StatusItemController+MenuCards.swift +6 -4
- package/Sources/Runic/Controllers/StatusItemController+MenuHelpers.swift +40 -12
- package/Sources/Runic/Controllers/StatusItemController.swift +43 -43
- package/Sources/Runic/Core/BudgetNotificationManager.swift +2 -1
- package/Sources/Runic/Core/Login/ClaudeLoginRunner.swift +2 -2
- package/Sources/Runic/Core/Login/CodexLoginRunner.swift +1 -1
- package/Sources/Runic/Core/Login/CursorLoginRunner.swift +4 -4
- package/Sources/Runic/Core/Login/GeminiLoginRunner.swift +1 -1
- package/Sources/Runic/Core/Rendering/IconRenderer.swift +91 -85
- package/Sources/Runic/Core/Rendering/IconView.swift +3 -1
- package/Sources/Runic/Core/RunicColors.swift +6 -6
- package/Sources/Runic/Core/RunicSpacing.swift +7 -7
- package/Sources/Runic/Core/RunicTypography.swift +206 -0
- package/Sources/Runic/Core/Stores/AuggieTokenStore.swift +1 -3
- package/Sources/Runic/Core/Stores/AzureOpenAITokenStore.swift +1 -3
- package/Sources/Runic/Core/Stores/CerebrasTokenStore.swift +1 -3
- package/Sources/Runic/Core/Stores/CohereTokenStore.swift +1 -3
- package/Sources/Runic/Core/Stores/CopilotTokenStore.swift +1 -3
- package/Sources/Runic/Core/Stores/CustomProviderStore.swift +10 -10
- package/Sources/Runic/Core/Stores/DeepSeekTokenStore.swift +1 -3
- package/Sources/Runic/Core/Stores/FireworksTokenStore.swift +1 -3
- package/Sources/Runic/Core/Stores/GroqTokenStore.swift +1 -3
- package/Sources/Runic/Core/Stores/KimiTokenStore.swift +1 -3
- package/Sources/Runic/Core/Stores/MiniMaxCookieHeaderStore.swift +1 -3
- package/Sources/Runic/Core/Stores/MiniMaxGroupIDStore.swift +1 -3
- package/Sources/Runic/Core/Stores/MiniMaxTokenStore.swift +1 -3
- package/Sources/Runic/Core/Stores/MistralTokenStore.swift +1 -3
- package/Sources/Runic/Core/Stores/OpenRouterTokenStore.swift +1 -3
- package/Sources/Runic/Core/Stores/PerplexityTokenStore.swift +1 -3
- package/Sources/Runic/Core/Stores/ProviderToggleStore.swift +1 -1
- package/Sources/Runic/Core/Stores/QwenTokenStore.swift +1 -3
- package/Sources/Runic/Core/Stores/SambaNovaTokenStore.swift +1 -3
- package/Sources/Runic/Core/Stores/SettingsStore.swift +89 -51
- package/Sources/Runic/Core/Stores/TogetherTokenStore.swift +1 -3
- package/Sources/Runic/Core/Stores/UsageStore+Accessors.swift +19 -6
- package/Sources/Runic/Core/Stores/UsageStore+TokenCost.swift +1 -1
- package/Sources/Runic/Core/Stores/UsageStore+WidgetSnapshot.swift +1 -1
- package/Sources/Runic/Core/Stores/UsageStore.swift +187 -161
- package/Sources/Runic/Core/Stores/XAITokenStore.swift +1 -3
- package/Sources/Runic/Core/Stores/ZaiTokenStore.swift +1 -2
- package/Sources/Runic/Core/UsageExporter.swift +8 -4
- package/Sources/Runic/ProviderRegistry.swift +1 -1
- package/Sources/Runic/Providers/Antigravity/AntigravityProviderImplementation.swift +1 -1
- package/Sources/Runic/Providers/Auggie/AuggieProviderImplementation.swift +1 -1
- package/Sources/Runic/Providers/Azure/AzureProviderImplementation.swift +1 -1
- package/Sources/Runic/Providers/Bedrock/BedrockProviderImplementation.swift +1 -1
- package/Sources/Runic/Providers/Cerebras/CerebrasProviderImplementation.swift +1 -1
- package/Sources/Runic/Providers/Codex/CodexProviderImplementation.swift +1 -1
- package/Sources/Runic/Providers/Cohere/CohereProviderImplementation.swift +1 -1
- package/Sources/Runic/Providers/Cursor/CursorProviderImplementation.swift +1 -1
- package/Sources/Runic/Providers/DeepSeek/DeepSeekProviderImplementation.swift +1 -1
- package/Sources/Runic/Providers/Factory/FactoryProviderImplementation.swift +1 -1
- package/Sources/Runic/Providers/Fireworks/FireworksProviderImplementation.swift +1 -1
- package/Sources/Runic/Providers/Gemini/GeminiProviderImplementation.swift +1 -1
- package/Sources/Runic/Providers/Groq/GroqProviderImplementation.swift +1 -1
- package/Sources/Runic/Providers/Kimi/KimiProviderImplementation.swift +1 -1
- package/Sources/Runic/Providers/MiniMax/MiniMaxProviderImplementation.swift +1 -1
- package/Sources/Runic/Providers/Mistral/MistralProviderImplementation.swift +1 -1
- package/Sources/Runic/Providers/OpenRouter/OpenRouterProviderImplementation.swift +1 -1
- package/Sources/Runic/Providers/Perplexity/PerplexityProviderImplementation.swift +1 -1
- package/Sources/Runic/Providers/SambaNova/SambaNovaProviderImplementation.swift +1 -1
- package/Sources/Runic/Providers/Shared/ProviderImplementation.swift +5 -2
- package/Sources/Runic/Providers/Shared/ProviderImplementationRegistry.swift +1 -1
- package/Sources/Runic/Providers/Shared/ProviderSettingsDescriptors.swift +1 -1
- package/Sources/Runic/Providers/Together/TogetherProviderImplementation.swift +1 -1
- package/Sources/Runic/Providers/XAI/XAIProviderImplementation.swift +1 -1
- package/Sources/Runic/Providers/Zai/ZaiProviderImplementation.swift +1 -1
- package/Sources/Runic/Resources/Fonts/Caveat-Bold.ttf +0 -0
- package/Sources/Runic/Resources/Fonts/Caveat-Regular.ttf +0 -0
- package/Sources/Runic/Resources/Fonts/FiraCode-Bold.ttf +0 -0
- package/Sources/Runic/Resources/Fonts/FiraCode-Light.ttf +0 -0
- package/Sources/Runic/Resources/Fonts/FiraCode-Medium.ttf +0 -0
- package/Sources/Runic/Resources/Fonts/FiraCode-Regular.ttf +0 -0
- package/Sources/Runic/Resources/Fonts/FiraCode-SemiBold.ttf +0 -0
- package/Sources/Runic/Resources/Fonts/IBMPlexMono-Bold.ttf +0 -0
- package/Sources/Runic/Resources/Fonts/IBMPlexMono-Medium.ttf +0 -0
- package/Sources/Runic/Resources/Fonts/IBMPlexMono-Regular.ttf +0 -0
- package/Sources/Runic/Resources/Fonts/IBMPlexMono-SemiBold.ttf +0 -0
- package/Sources/Runic/Resources/Fonts/Inconsolata-Bold.ttf +0 -0
- package/Sources/Runic/Resources/Fonts/Inconsolata-Medium.ttf +0 -0
- package/Sources/Runic/Resources/Fonts/Inconsolata-Regular.ttf +0 -0
- package/Sources/Runic/Resources/Fonts/Inconsolata-SemiBold.ttf +0 -0
- package/Sources/Runic/Resources/Fonts/JetBrainsMono-Bold.ttf +0 -0
- package/Sources/Runic/Resources/Fonts/JetBrainsMono-Medium.ttf +0 -0
- package/Sources/Runic/Resources/Fonts/JetBrainsMono-Regular.ttf +0 -0
- package/Sources/Runic/Resources/Fonts/JetBrainsMono-SemiBold.ttf +0 -0
- package/Sources/Runic/Resources/Fonts/SpaceMono-Bold.ttf +0 -0
- package/Sources/Runic/Resources/Fonts/SpaceMono-Regular.ttf +0 -0
- package/Sources/Runic/RunicApp.swift +46 -36
- package/Sources/Runic/SessionQuotaNotifications.swift +2 -2
- package/Sources/Runic/UsagePaceText.swift +1 -1
- package/Sources/Runic/UsageProgressBar.swift +13 -9
- package/Sources/Runic/Utilities/LoadingPattern.swift +4 -2
- package/Sources/Runic/Utilities/PerformanceConstants.swift +28 -28
- package/Sources/Runic/Views/Menu/AlertsMenuView.swift +19 -21
- package/Sources/Runic/Views/Menu/CostComparativeChartMenuView.swift +19 -19
- package/Sources/Runic/Views/Menu/CostHistoryChartMenuView.swift +7 -7
- package/Sources/Runic/Views/Menu/CreditsHistoryChartMenuView.swift +5 -5
- package/Sources/Runic/Views/Menu/EfficiencyMetricsMenuView.swift +29 -30
- package/Sources/Runic/Views/Menu/HeroStatCardsMenuView.swift +20 -17
- package/Sources/Runic/Views/Menu/HourlyActivityChartMenuView.swift +14 -14
- package/Sources/Runic/Views/Menu/InlineUsageChartView.swift +12 -10
- package/Sources/Runic/Views/Menu/MenuCardEntranceModifier.swift +3 -4
- package/Sources/Runic/Views/Menu/MenuCardSidebarView.swift +5 -25
- package/Sources/Runic/Views/Menu/MenuCardSkeletonView.swift +1 -1
- package/Sources/Runic/Views/Menu/MenuCardView.swift +120 -131
- package/Sources/Runic/Views/Menu/MenuContent.swift +11 -8
- package/Sources/Runic/Views/Menu/MenuDescriptor.swift +4 -2
- package/Sources/Runic/Views/Menu/MenuHighlightStyle.swift +1 -8
- package/Sources/Runic/Views/Menu/ModelBreakdownMenuView.swift +20 -14
- package/Sources/Runic/Views/Menu/OverviewMenuView.swift +18 -15
- package/Sources/Runic/Views/Menu/ProjectBreakdownMenuView.swift +16 -11
- package/Sources/Runic/Views/Menu/ProjectBudgetMenuView.swift +27 -27
- package/Sources/Runic/Views/Menu/ProviderTabBarView.swift +4 -6
- package/Sources/Runic/Views/Menu/SubscriptionUtilizationChartMenuView.swift +24 -11
- package/Sources/Runic/Views/Menu/UsageBreakdownChartMenuView.swift +5 -5
- package/Sources/Runic/Views/Menu/UsageHeatmapMenuView.swift +7 -8
- package/Sources/Runic/Views/Menu/UsageTimelineChartMenuView.swift +22 -17
- package/Sources/Runic/Views/Menu/UsageWindowComparisonChartMenuView.swift +8 -7
- package/Sources/Runic/Views/Menu/WeeklyActivityChartMenuView.swift +7 -7
- package/Sources/Runic/Views/Performance/PerformanceDashboardView.swift +50 -47
- package/Sources/Runic/Views/Preferences/LiquidComponents.swift +15 -14
- package/Sources/Runic/Views/Preferences/PreferencesAboutPane.swift +7 -7
- package/Sources/Runic/Views/Preferences/PreferencesAdvancedPane.swift +27 -27
- package/Sources/Runic/Views/Preferences/PreferencesAlertsPane.swift +38 -42
- package/Sources/Runic/Views/Preferences/PreferencesAnalyticsPane.swift +39 -43
- package/Sources/Runic/Views/Preferences/PreferencesBudgetsPane.swift +21 -21
- package/Sources/Runic/Views/Preferences/PreferencesComponents.swift +7 -7
- package/Sources/Runic/Views/Preferences/PreferencesCustomProvidersPane.swift +49 -50
- package/Sources/Runic/Views/Preferences/PreferencesDebugPane.swift +10 -10
- package/Sources/Runic/Views/Preferences/PreferencesGeneralPane.swift +40 -21
- package/Sources/Runic/Views/Preferences/PreferencesHelpPane.swift +7 -7
- package/Sources/Runic/Views/Preferences/PreferencesIntegrationsPane.swift +44 -39
- package/Sources/Runic/Views/Preferences/PreferencesPerformancePane.swift +26 -23
- package/Sources/Runic/Views/Preferences/PreferencesProvidersPane.swift +271 -226
- package/Sources/Runic/Views/Preferences/PreferencesSelection.swift +6 -2
- package/Sources/Runic/Views/Preferences/PreferencesSyncPane.swift +7 -5
- package/Sources/Runic/Views/Preferences/PreferencesView.swift +38 -31
- package/Sources/Runic/Views/Rating/QualityRatingView.swift +11 -11
- package/Sources/Runic/Views/Team/TeamDashboardView.swift +29 -24
- package/Sources/Runic/Views/Team/TeamInviteSheet.swift +16 -16
- package/Sources/Runic/Views/Team/TeamManagementView.swift +50 -49
- package/Sources/Runic/Views/Team/TeamMemberRow.swift +8 -8
- package/Sources/RunicCLI/CLIEntry.swift +83 -42
- package/Sources/RunicCLI/CLIRenderer.swift +1 -1
- package/Sources/RunicCLI/Commands/EnhancedUsageCommand.swift +60 -60
- package/Sources/RunicCLI/Commands/ModelsCommand.swift +45 -44
- package/Sources/RunicCLI/Commands/ProjectsCommand.swift +83 -69
- package/Sources/RunicCLI/Commands/ResetCommand.swift +50 -49
- package/Sources/RunicCLI/Commands/UsageLedgerSourceFactory.swift +31 -32
- package/Sources/RunicClaudeWebProbe/main.swift +1 -1
- package/Sources/RunicCore/AlertRuleStore.swift +20 -20
- package/Sources/RunicCore/BrowserCookieImportOrder.swift +3 -3
- package/Sources/RunicCore/CostUsageModels.swift +1 -1
- package/Sources/RunicCore/CustomProviders/CustomProviderModels.swift +29 -30
- package/Sources/RunicCore/CustomProviders/GenericProviderFetcher.swift +73 -75
- package/Sources/RunicCore/CustomProviders/ProviderTemplates.swift +53 -109
- package/Sources/RunicCore/Host/PTY/TTYCommandRunner.swift +3 -3
- package/Sources/RunicCore/Integrations/GitHubIntegration.swift +3 -3
- package/Sources/RunicCore/Models/EnhancedUsageModels.swift +47 -48
- package/Sources/RunicCore/OpenAIWeb/OpenAIDashboardBrowserCookieImporter.swift +1 -1
- package/Sources/RunicCore/OpenAIWeb/OpenAIDashboardFetcher.swift +1 -1
- package/Sources/RunicCore/Performance/PerformanceModels.swift +4 -4
- package/Sources/RunicCore/Performance/PerformanceStorageImpl.swift +81 -64
- package/Sources/RunicCore/Policy/UsagePolicyEngine.swift +2 -2
- package/Sources/RunicCore/ProjectBudgetStore.swift +15 -12
- package/Sources/RunicCore/Providers/Antigravity/AntigravityProviderDescriptor.swift +4 -2
- package/Sources/RunicCore/Providers/Antigravity/AntigravityStatusProbe.swift +2 -2
- package/Sources/RunicCore/Providers/Auggie/AuggieProviderDescriptor.swift +2 -2
- package/Sources/RunicCore/Providers/Auggie/AuggieUsageFetcher.swift +3 -3
- package/Sources/RunicCore/Providers/Azure/AzureProviderDescriptor.swift +8 -8
- package/Sources/RunicCore/Providers/Azure/AzureUsageFetcher.swift +3 -3
- package/Sources/RunicCore/Providers/Bedrock/BedrockProviderDescriptor.swift +6 -6
- package/Sources/RunicCore/Providers/Bedrock/BedrockUsageFetcher.swift +3 -7
- package/Sources/RunicCore/Providers/Cerebras/CerebrasProviderDescriptor.swift +2 -2
- package/Sources/RunicCore/Providers/Cerebras/CerebrasUsageFetcher.swift +2 -2
- package/Sources/RunicCore/Providers/Claude/ClaudeOAuth/ClaudeOAuthUsageFetcher.swift +3 -3
- package/Sources/RunicCore/Providers/Claude/ClaudeProviderDescriptor.swift +4 -2
- package/Sources/RunicCore/Providers/Claude/ClaudeStatusProbe.swift +4 -4
- package/Sources/RunicCore/Providers/Claude/ClaudeUsageDataSource.swift +3 -1
- package/Sources/RunicCore/Providers/Claude/ClaudeWeb/ClaudeWebAPIFetcher.swift +1 -1
- package/Sources/RunicCore/Providers/Codex/CodexOAuth/CodexOAuthUsageFetcher.swift +1 -1
- package/Sources/RunicCore/Providers/Codex/CodexProviderDescriptor.swift +4 -2
- package/Sources/RunicCore/Providers/Codex/CodexUsageDataSource.swift +3 -1
- package/Sources/RunicCore/Providers/Codex/CodexWebDashboardStrategy.swift +5 -3
- package/Sources/RunicCore/Providers/Cohere/CohereProviderDescriptor.swift +2 -2
- package/Sources/RunicCore/Providers/Cohere/CohereUsageFetcher.swift +3 -3
- package/Sources/RunicCore/Providers/Copilot/CopilotGitHubCLITokenReader.swift +7 -4
- package/Sources/RunicCore/Providers/Copilot/CopilotProviderDescriptor.swift +4 -4
- package/Sources/RunicCore/Providers/Copilot/CopilotUsageFetcher.swift +5 -3
- package/Sources/RunicCore/Providers/Copilot/CopilotVSCodeTokenReader.swift +9 -10
- package/Sources/RunicCore/Providers/Cursor/CursorProviderDescriptor.swift +4 -2
- package/Sources/RunicCore/Providers/DeepSeek/DeepSeekProviderDescriptor.swift +2 -2
- package/Sources/RunicCore/Providers/DeepSeek/DeepSeekUsageFetcher.swift +2 -2
- package/Sources/RunicCore/Providers/Factory/FactoryLocalStorageImporter.swift +4 -4
- package/Sources/RunicCore/Providers/Factory/FactoryProviderDescriptor.swift +4 -2
- package/Sources/RunicCore/Providers/Factory/FactoryStatusProbe.swift +2 -2
- package/Sources/RunicCore/Providers/Fireworks/FireworksProviderDescriptor.swift +2 -2
- package/Sources/RunicCore/Providers/Fireworks/FireworksUsageFetcher.swift +2 -2
- package/Sources/RunicCore/Providers/Gemini/GeminiProviderDescriptor.swift +4 -2
- package/Sources/RunicCore/Providers/Gemini/GeminiStatusProbe.swift +5 -2
- package/Sources/RunicCore/Providers/Groq/GroqProviderDescriptor.swift +2 -2
- package/Sources/RunicCore/Providers/Groq/GroqUsageFetcher.swift +2 -2
- package/Sources/RunicCore/Providers/Kimi/KimiProviderDescriptor.swift +2 -2
- package/Sources/RunicCore/Providers/Kimi/KimiUsageFetcher.swift +2 -2
- package/Sources/RunicCore/Providers/MiniMax/MiniMaxProviderDescriptor.swift +10 -5
- package/Sources/RunicCore/Providers/MiniMax/MiniMaxUsageFetcher.swift +7 -7
- package/Sources/RunicCore/Providers/MiniMax/MiniMaxWebUsageFetcher.swift +10 -10
- package/Sources/RunicCore/Providers/Mistral/MistralProviderDescriptor.swift +2 -2
- package/Sources/RunicCore/Providers/Mistral/MistralUsageFetcher.swift +2 -2
- package/Sources/RunicCore/Providers/OpenRouter/OpenRouterProviderDescriptor.swift +2 -2
- package/Sources/RunicCore/Providers/OpenRouter/OpenRouterUsageFetcher.swift +23 -10
- package/Sources/RunicCore/Providers/Perplexity/PerplexityProviderDescriptor.swift +2 -2
- package/Sources/RunicCore/Providers/Perplexity/PerplexityUsageFetcher.swift +2 -2
- package/Sources/RunicCore/Providers/ProviderFetchPlan.swift +2 -2
- package/Sources/RunicCore/Providers/ProviderTokenResolver.swift +2 -2
- package/Sources/RunicCore/Providers/Qwen/QwenProviderDescriptor.swift +5 -3
- package/Sources/RunicCore/Providers/Qwen/QwenUsageStats.swift +26 -13
- package/Sources/RunicCore/Providers/SambaNova/SambaNovaProviderDescriptor.swift +2 -2
- package/Sources/RunicCore/Providers/SambaNova/SambaNovaUsageFetcher.swift +2 -2
- package/Sources/RunicCore/Providers/Together/TogetherProviderDescriptor.swift +2 -2
- package/Sources/RunicCore/Providers/Together/TogetherUsageFetcher.swift +2 -2
- package/Sources/RunicCore/Providers/VertexAI/VertexAIProviderDescriptor.swift +5 -5
- package/Sources/RunicCore/Providers/VertexAI/VertexAISettingsReader.swift +1 -1
- package/Sources/RunicCore/Providers/VertexAI/VertexAIUsageFetcher.swift +3 -3
- package/Sources/RunicCore/Providers/XAI/XAIProviderDescriptor.swift +2 -2
- package/Sources/RunicCore/Providers/XAI/XAIUsageFetcher.swift +2 -2
- package/Sources/RunicCore/Providers/Zai/ZaiProviderDescriptor.swift +4 -2
- package/Sources/RunicCore/Providers/Zai/ZaiUsageStats.swift +48 -21
- package/Sources/RunicCore/Sync/BackgroundSyncManager.swift +76 -77
- package/Sources/RunicCore/Sync/SyncConflictResolver.swift +55 -58
- package/Sources/RunicCore/Sync/SyncProtocol.swift +21 -22
- package/Sources/RunicCore/Sync/SyncRecord.swift +46 -49
- package/Sources/RunicCore/Sync/SyncUsageExample.swift +44 -50
- package/Sources/RunicCore/Sync/TeamSyncRecords.swift +94 -101
- package/Sources/RunicCore/Sync/iCloudSyncEngine.swift +51 -46
- package/Sources/RunicCore/Team/TeamModels.swift +111 -110
- package/Sources/RunicCore/Team/TeamStore.swift +126 -109
- package/Sources/RunicCore/UsageFetcher.swift +2 -2
- package/Sources/RunicCore/UsageFormatter.swift +25 -25
- package/Sources/RunicCore/UsageLedger/ClaudeUsageLogSource.swift +27 -13
- package/Sources/RunicCore/UsageLedger/CodexUsageLogSource.swift +11 -3
- package/Sources/RunicCore/UsageLedger/LedgerCache.swift +5 -2
- package/Sources/RunicCore/UsageLedger/OTelGenAILedgerAdapter.swift +1 -1
- package/Sources/RunicCore/UsageLedger/UsageLedgerAggregator.swift +40 -25
- package/Sources/RunicCore/UsageLedger/UsageLedgerInsightsAdvisor.swift +1 -1
- package/Sources/RunicCore/UsageLedger/UsageLedgerProjectIdentity.swift +55 -16
- package/Sources/RunicCore/Vendored/CostUsage/CostUsageCache.swift +6 -6
- package/Sources/RunicCore/Vendored/CostUsage/CostUsageJsonl.swift +1 -1
- package/Sources/RunicCore/Vendored/CostUsage/CostUsagePricing.swift +2 -2
- package/Sources/RunicCore/Vendored/CostUsage/CostUsageScanner.swift +5 -5
- package/Tests/RunicTests/AppDelegateTests.swift +8 -3
- package/Tests/RunicTests/BrowserCookieOrderLabelTests.swift +2 -3
- package/Tests/RunicTests/CLIArgumentParsingTests.swift +3 -4
- package/Tests/RunicTests/CLICostTests.swift +6 -7
- package/Tests/RunicTests/CLIProviderSelectionTests.swift +2 -3
- package/Tests/RunicTests/CLISnapshotTests.swift +3 -4
- package/Tests/RunicTests/CLIWebFallbackTests.swift +3 -4
- package/Tests/RunicTests/ClaudeOAuthTests.swift +11 -12
- package/Tests/RunicTests/ClaudeResilienceTests.swift +3 -4
- package/Tests/RunicTests/ClaudeUsageTests.swift +20 -21
- package/Tests/RunicTests/CodexOAuthTests.swift +7 -8
- package/Tests/RunicTests/CodexUsageLogSourceTests.swift +1 -3
- package/Tests/RunicTests/CopilotTokenResolverTests.swift +5 -6
- package/Tests/RunicTests/CopilotVSCodeTokenReaderTests.swift +4 -5
- package/Tests/RunicTests/CostUsageDecodingTests.swift +15 -17
- package/Tests/RunicTests/CostUsagePricingTests.swift +5 -7
- package/Tests/RunicTests/CostUsageScannerTests.swift +10 -12
- package/Tests/RunicTests/CursorStatusProbeTests.swift +15 -16
- package/Tests/RunicTests/FactoryStatusProbeTests.swift +3 -5
- package/Tests/RunicTests/GeminiLoginAlertTests.swift +3 -4
- package/Tests/RunicTests/GeminiStatusProbeAPITests.swift +11 -11
- package/Tests/RunicTests/GeminiStatusProbePlanTests.swift +8 -8
- package/Tests/RunicTests/GeminiStatusProbeTests.swift +20 -21
- package/Tests/RunicTests/GoogleWorkspaceStatusTests.swift +2 -3
- package/Tests/RunicTests/InstallOriginTests.swift +1 -2
- package/Tests/RunicTests/KeyboardShortcutsBundleTests.swift +2 -2
- package/Tests/RunicTests/LiveAccountTests.swift +3 -3
- package/Tests/RunicTests/LoadingPatternTests.swift +3 -4
- package/Tests/RunicTests/MenuCardModelTests.swift +33 -34
- package/Tests/RunicTests/MiniMaxCookieHeaderStoreTestSupport.swift +4 -1
- package/Tests/RunicTests/MiniMaxGroupIDStoreTestSupport.swift +4 -1
- package/Tests/RunicTests/MiniMaxParsingTests.swift +4 -5
- package/Tests/RunicTests/MiniMaxTokenStoreTestSupport.swift +4 -1
- package/Tests/RunicTests/OTelGenAILedgerAdapterTests.swift +4 -6
- package/Tests/RunicTests/OpenAIDashboardBrowserCookieImporterTests.swift +1 -2
- package/Tests/RunicTests/OpenAIDashboardFetcherCreditsWaitTests.swift +5 -6
- package/Tests/RunicTests/OpenAIDashboardOffscreenHostTests.swift +2 -3
- package/Tests/RunicTests/OpenAIDashboardParserTests.swift +12 -13
- package/Tests/RunicTests/OpenAIWebAccountSwitchTests.swift +17 -6
- package/Tests/RunicTests/OpenRouterTokenStoreTestSupport.swift +52 -13
- package/Tests/RunicTests/PathBuilderTests.swift +14 -15
- package/Tests/RunicTests/ProviderFetchPipelineTests.swift +3 -4
- package/Tests/RunicTests/ProviderIconResourcesTests.swift +1 -2
- package/Tests/RunicTests/ProviderMetadataStatusLinkTests.swift +1 -2
- package/Tests/RunicTests/ProviderSettingsDescriptorTests.swift +53 -19
- package/Tests/RunicTests/ProviderToggleStoreTests.swift +10 -11
- package/Tests/RunicTests/RunicTests.swift +6 -7
- package/Tests/RunicTests/SessionQuotaNotificationLogicTests.swift +5 -6
- package/Tests/RunicTests/SettingsStoreTests.swift +149 -45
- package/Tests/RunicTests/StatusItemAnimationTests.swift +8 -3
- package/Tests/RunicTests/StatusMenuTests.swift +63 -22
- package/Tests/RunicTests/StatusProbeTests.swift +28 -29
- package/Tests/RunicTests/SubprocessRunnerTests.swift +1 -3
- package/Tests/RunicTests/SubscriptionDetectionTests.swift +8 -9
- package/Tests/RunicTests/TTYCommandRunnerTests.swift +8 -9
- package/Tests/RunicTests/TeamShowbackExporterTests.swift +2 -4
- package/Tests/RunicTests/TextParsingTests.swift +1 -2
- package/Tests/RunicTests/UsageFormatterTests.swift +15 -16
- package/Tests/RunicTests/UsageLedgerAnomalyDetectionTests.swift +12 -14
- package/Tests/RunicTests/UsageLedgerForecastTests.swift +4 -6
- package/Tests/RunicTests/UsageLedgerInsightsAdvisorTests.swift +7 -9
- package/Tests/RunicTests/UsageLedgerProjectNameTests.swift +6 -8
- package/Tests/RunicTests/UsagePaceTests.swift +5 -6
- package/Tests/RunicTests/UsagePaceTextTests.swift +8 -9
- package/Tests/RunicTests/UsagePolicyEngineTests.swift +3 -5
- package/Tests/RunicTests/WidgetSnapshotTests.swift +1 -3
- package/Tests/RunicTests/ZaiProviderTests.swift +3 -5
- package/Tests/RunicTests/ZaiTokenStoreTestSupport.swift +4 -1
- package/appcast.xml +36 -76
- package/package.json +1 -1
- package/runic.png +0 -0
- package/runic.svg +15 -0
- package/version.env +2 -2
|
@@ -18,7 +18,7 @@ public struct MiniMaxModelRemain: Decodable {
|
|
|
18
18
|
public let modelName: String
|
|
19
19
|
public let currentIntervalTotalCount: Int
|
|
20
20
|
public let currentIntervalUsageCount: Int
|
|
21
|
-
|
|
21
|
+
|
|
22
22
|
enum CodingKeys: String, CodingKey {
|
|
23
23
|
case modelName = "model_name"
|
|
24
24
|
case currentIntervalTotalCount = "current_interval_total_count"
|
|
@@ -62,9 +62,9 @@ extension MiniMaxUsageSnapshot {
|
|
|
62
62
|
// But let's assume standard "usage" field naming means USED.
|
|
63
63
|
// If the user reports it shows 100% when new, we invert it.
|
|
64
64
|
// For now, let's map it as Used/Total.
|
|
65
|
-
|
|
65
|
+
|
|
66
66
|
let percent = self.total > 0 ? (Double(self.used) / Double(self.total)) * 100.0 : 0.0
|
|
67
|
-
|
|
67
|
+
|
|
68
68
|
let primary = RateWindow(
|
|
69
69
|
usedPercent: percent,
|
|
70
70
|
windowMinutes: 24 * 60,
|
|
@@ -77,7 +77,7 @@ extension MiniMaxUsageSnapshot {
|
|
|
77
77
|
accountEmail: nil,
|
|
78
78
|
accountOrganization: nil,
|
|
79
79
|
loginMethod: "api-key")
|
|
80
|
-
|
|
80
|
+
|
|
81
81
|
return UsageSnapshot(
|
|
82
82
|
primary: primary,
|
|
83
83
|
secondary: nil,
|
|
@@ -126,11 +126,11 @@ public struct MiniMaxUsageFetcher: Sendable {
|
|
|
126
126
|
let apiResponse = try decoder.decode(MiniMaxQuotaResponse.self, from: data)
|
|
127
127
|
|
|
128
128
|
if apiResponse.baseResponse.statusCode != 0 {
|
|
129
|
-
|
|
129
|
+
throw MiniMaxUsageError.apiError(apiResponse.baseResponse.statusMsg)
|
|
130
130
|
}
|
|
131
131
|
|
|
132
132
|
guard let firstModel = apiResponse.modelRemains?.first else {
|
|
133
|
-
|
|
133
|
+
throw MiniMaxUsageError.parseFailed("No model quota found")
|
|
134
134
|
}
|
|
135
135
|
|
|
136
136
|
return MiniMaxUsageSnapshot(
|
|
@@ -138,7 +138,7 @@ public struct MiniMaxUsageFetcher: Sendable {
|
|
|
138
138
|
used: firstModel.currentIntervalUsageCount,
|
|
139
139
|
modelName: firstModel.modelName,
|
|
140
140
|
updatedAt: Date())
|
|
141
|
-
|
|
141
|
+
|
|
142
142
|
} catch {
|
|
143
143
|
Self.log.error("MiniMax parsing error: \(error.localizedDescription)")
|
|
144
144
|
throw MiniMaxUsageError.parseFailed(error.localizedDescription)
|
|
@@ -225,13 +225,13 @@ public struct MiniMaxWebUsageFetcher: Sendable {
|
|
|
225
225
|
|
|
226
226
|
// MARK: - Parsing helpers
|
|
227
227
|
|
|
228
|
-
struct MiniMaxManualInput
|
|
228
|
+
struct MiniMaxManualInput {
|
|
229
229
|
let cookieHeader: String
|
|
230
230
|
let accessToken: String?
|
|
231
231
|
let groupID: String?
|
|
232
232
|
}
|
|
233
233
|
|
|
234
|
-
struct MiniMaxParsedUsage
|
|
234
|
+
struct MiniMaxParsedUsage {
|
|
235
235
|
let usedPercent: Double
|
|
236
236
|
let windowMinutes: Int?
|
|
237
237
|
let resetsAt: Date?
|
|
@@ -408,9 +408,9 @@ enum MiniMaxWebParsing {
|
|
|
408
408
|
if let remaining = self.captureGroups(
|
|
409
409
|
in: html,
|
|
410
410
|
pattern: "(?i)Available usage[^0-9]*([0-9]+(?:\\.[0-9]+)?)")?.first,
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
411
|
+
let total = self.captureGroups(
|
|
412
|
+
in: html,
|
|
413
|
+
pattern: "(?i)Total usage[^0-9]*([0-9]+(?:\\.[0-9]+)?)")?.first
|
|
414
414
|
{
|
|
415
415
|
let remainingValue = self.doubleValue(remaining) ?? 0
|
|
416
416
|
let totalValue = self.doubleValue(total) ?? 0
|
|
@@ -613,7 +613,7 @@ enum MiniMaxWebParsing {
|
|
|
613
613
|
}
|
|
614
614
|
|
|
615
615
|
#if os(macOS)
|
|
616
|
-
private struct MiniMaxWebSession
|
|
616
|
+
private struct MiniMaxWebSession {
|
|
617
617
|
let cookieHeader: String
|
|
618
618
|
let accessToken: String?
|
|
619
619
|
let groupID: String?
|
|
@@ -621,7 +621,7 @@ private struct MiniMaxWebSession: Sendable {
|
|
|
621
621
|
let isManual: Bool
|
|
622
622
|
}
|
|
623
623
|
|
|
624
|
-
private struct MiniMaxCookieSession
|
|
624
|
+
private struct MiniMaxCookieSession {
|
|
625
625
|
let cookieHeader: String
|
|
626
626
|
let sourceLabel: String
|
|
627
627
|
}
|
|
@@ -674,7 +674,7 @@ private enum MiniMaxCookieImporter {
|
|
|
674
674
|
}
|
|
675
675
|
}
|
|
676
676
|
|
|
677
|
-
private struct MiniMaxLocalStorageToken
|
|
677
|
+
private struct MiniMaxLocalStorageToken {
|
|
678
678
|
let accessToken: String
|
|
679
679
|
let groupID: String?
|
|
680
680
|
let sourceLabel: String
|
|
@@ -706,7 +706,7 @@ private enum MiniMaxLocalStorageImporter {
|
|
|
706
706
|
return tokens
|
|
707
707
|
}
|
|
708
708
|
|
|
709
|
-
private struct LocalStorageCandidate
|
|
709
|
+
private struct LocalStorageCandidate {
|
|
710
710
|
let label: String
|
|
711
711
|
let levelDBURL: URL
|
|
712
712
|
}
|
|
@@ -789,7 +789,7 @@ private enum MiniMaxLocalStorageImporter {
|
|
|
789
789
|
}
|
|
790
790
|
}
|
|
791
791
|
|
|
792
|
-
private struct TokenMatch
|
|
792
|
+
private struct TokenMatch {
|
|
793
793
|
let accessToken: String
|
|
794
794
|
let groupID: String?
|
|
795
795
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import RunicMacroSupport
|
|
2
1
|
import Foundation
|
|
2
|
+
import RunicMacroSupport
|
|
3
3
|
|
|
4
4
|
@ProviderDescriptorRegistration
|
|
5
5
|
@ProviderDescriptorDefinition
|
|
@@ -71,7 +71,7 @@ struct MistralAPIFetchStrategy: ProviderFetchStrategy {
|
|
|
71
71
|
}
|
|
72
72
|
}
|
|
73
73
|
|
|
74
|
-
enum MistralSettingsError: LocalizedError
|
|
74
|
+
enum MistralSettingsError: LocalizedError {
|
|
75
75
|
case missingToken
|
|
76
76
|
|
|
77
77
|
var errorDescription: String? {
|
|
@@ -8,7 +8,7 @@ struct MistralModelsResponse: Decodable {
|
|
|
8
8
|
}
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
enum MistralUsageFetcher {
|
|
12
12
|
static let apiURL = URL(string: "https://api.mistral.ai/v1/models")!
|
|
13
13
|
|
|
14
14
|
static func fetchModels(apiKey: String) async throws -> MistralModelsResponse {
|
|
@@ -57,7 +57,7 @@ extension MistralModelsResponse {
|
|
|
57
57
|
}
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
-
enum MistralAPIError: LocalizedError
|
|
60
|
+
enum MistralAPIError: LocalizedError {
|
|
61
61
|
case invalidResponse
|
|
62
62
|
case httpError(statusCode: Int, body: String?)
|
|
63
63
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import RunicMacroSupport
|
|
2
1
|
import Foundation
|
|
2
|
+
import RunicMacroSupport
|
|
3
3
|
|
|
4
4
|
@ProviderDescriptorRegistration
|
|
5
5
|
@ProviderDescriptorDefinition
|
|
@@ -74,7 +74,7 @@ struct OpenRouterAPIFetchStrategy: ProviderFetchStrategy {
|
|
|
74
74
|
|
|
75
75
|
// MARK: - Settings Errors
|
|
76
76
|
|
|
77
|
-
enum OpenRouterSettingsError: LocalizedError
|
|
77
|
+
enum OpenRouterSettingsError: LocalizedError {
|
|
78
78
|
case missingToken
|
|
79
79
|
|
|
80
80
|
var errorDescription: String? {
|
|
@@ -51,16 +51,30 @@ struct OpenRouterKeyInfoResponse: Decodable {
|
|
|
51
51
|
}
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
-
var keyUsage: Double {
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
var
|
|
54
|
+
var keyUsage: Double {
|
|
55
|
+
self.data?.usage ?? 0
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
var keyLimit: Double? {
|
|
59
|
+
self.data?.limit
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
var isFreeTier: Bool {
|
|
63
|
+
self.data?.is_free_tier ?? false
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
var rateLimitRequests: Int? {
|
|
67
|
+
self.data?.rate_limit?.requests
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
var rateLimitInterval: String? {
|
|
71
|
+
self.data?.rate_limit?.interval
|
|
72
|
+
}
|
|
59
73
|
}
|
|
60
74
|
|
|
61
75
|
// MARK: - Fetcher
|
|
62
76
|
|
|
63
|
-
|
|
77
|
+
enum OpenRouterUsageFetcher {
|
|
64
78
|
static let creditsURL = URL(string: "https://openrouter.ai/api/v1/credits")!
|
|
65
79
|
static let keyInfoURL = URL(string: "https://openrouter.ai/api/v1/auth/key")!
|
|
66
80
|
private static let requestTimeout: TimeInterval = 15
|
|
@@ -98,9 +112,9 @@ struct OpenRouterUsageFetcher {
|
|
|
98
112
|
|
|
99
113
|
private static func fetchKeyInfoBestEffort(apiKey: String) async -> OpenRouterKeyInfoResponse? {
|
|
100
114
|
do {
|
|
101
|
-
return try await
|
|
115
|
+
return try await self.fetchKeyInfo(apiKey: apiKey)
|
|
102
116
|
} catch {
|
|
103
|
-
|
|
117
|
+
self.log.info("OpenRouter key info unavailable: \(error.localizedDescription)")
|
|
104
118
|
return nil
|
|
105
119
|
}
|
|
106
120
|
}
|
|
@@ -124,7 +138,6 @@ struct OpenRouterUsageFetcher {
|
|
|
124
138
|
|
|
125
139
|
return try JSONDecoder().decode(OpenRouterKeyInfoResponse.self, from: data)
|
|
126
140
|
}
|
|
127
|
-
|
|
128
141
|
}
|
|
129
142
|
|
|
130
143
|
// MARK: - Snapshot conversion
|
|
@@ -185,7 +198,7 @@ extension OpenRouterCreditsResponse {
|
|
|
185
198
|
|
|
186
199
|
// MARK: - Errors
|
|
187
200
|
|
|
188
|
-
enum OpenRouterAPIError: LocalizedError
|
|
201
|
+
enum OpenRouterAPIError: LocalizedError {
|
|
189
202
|
case invalidResponse
|
|
190
203
|
case httpError(statusCode: Int)
|
|
191
204
|
case decodingError
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import RunicMacroSupport
|
|
2
1
|
import Foundation
|
|
2
|
+
import RunicMacroSupport
|
|
3
3
|
|
|
4
4
|
@ProviderDescriptorRegistration
|
|
5
5
|
@ProviderDescriptorDefinition
|
|
@@ -71,7 +71,7 @@ struct PerplexityAPIFetchStrategy: ProviderFetchStrategy {
|
|
|
71
71
|
}
|
|
72
72
|
}
|
|
73
73
|
|
|
74
|
-
enum PerplexitySettingsError: LocalizedError
|
|
74
|
+
enum PerplexitySettingsError: LocalizedError {
|
|
75
75
|
case missingToken
|
|
76
76
|
|
|
77
77
|
var errorDescription: String? {
|
|
@@ -8,7 +8,7 @@ struct PerplexityModelsResponse: Decodable {
|
|
|
8
8
|
}
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
enum PerplexityUsageFetcher {
|
|
12
12
|
static let apiURL = URL(string: "https://api.perplexity.ai/models")!
|
|
13
13
|
|
|
14
14
|
static func fetchModels(apiKey: String) async throws -> PerplexityModelsResponse {
|
|
@@ -57,7 +57,7 @@ extension PerplexityModelsResponse {
|
|
|
57
57
|
}
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
-
enum PerplexityAPIError: LocalizedError
|
|
60
|
+
enum PerplexityAPIError: LocalizedError {
|
|
61
61
|
case invalidResponse
|
|
62
62
|
case httpError(statusCode: Int, body: String?)
|
|
63
63
|
|
|
@@ -170,8 +170,8 @@ public struct ProviderFetchPipeline: Sendable {
|
|
|
170
170
|
|
|
171
171
|
public init(
|
|
172
172
|
resolveStrategies: @escaping @Sendable (ProviderFetchContext) async -> [any ProviderFetchStrategy],
|
|
173
|
-
strategyTimeout: TimeInterval = 45
|
|
174
|
-
|
|
173
|
+
strategyTimeout: TimeInterval = 45)
|
|
174
|
+
{
|
|
175
175
|
self.resolveStrategies = resolveStrategies
|
|
176
176
|
self.strategyTimeout = strategyTimeout
|
|
177
177
|
}
|
|
@@ -472,11 +472,11 @@ public enum ProviderTokenResolver {
|
|
|
472
472
|
if dataProtection {
|
|
473
473
|
query[kSecUseDataProtectionKeychain as String] = true
|
|
474
474
|
}
|
|
475
|
-
#if canImport(LocalAuthentication)
|
|
475
|
+
#if canImport(LocalAuthentication)
|
|
476
476
|
let authContext = LAContext()
|
|
477
477
|
authContext.interactionNotAllowed = true
|
|
478
478
|
query[kSecUseAuthenticationContext as String] = authContext
|
|
479
|
-
#endif
|
|
479
|
+
#endif
|
|
480
480
|
|
|
481
481
|
let status = SecItemCopyMatching(query as CFDictionary, &result)
|
|
482
482
|
if status == errSecItemNotFound || status == errSecInteractionNotAllowed {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import RunicMacroSupport
|
|
2
1
|
import Foundation
|
|
2
|
+
import RunicMacroSupport
|
|
3
3
|
|
|
4
4
|
@ProviderDescriptorRegistration
|
|
5
5
|
@ProviderDescriptorDefinition
|
|
@@ -33,7 +33,9 @@ public enum QwenProviderDescriptor {
|
|
|
33
33
|
color: ProviderColor(red: 1.0, green: 0.416, blue: 0.0)),
|
|
34
34
|
tokenCost: ProviderTokenCostConfig(
|
|
35
35
|
supportsTokenCost: false,
|
|
36
|
-
noDataMessage: {
|
|
36
|
+
noDataMessage: {
|
|
37
|
+
"Qwen cost estimates are shown per-model in the details submenu (based on public DashScope pricing)."
|
|
38
|
+
}),
|
|
37
39
|
fetchPlan: ProviderFetchPlan(
|
|
38
40
|
sourceModes: [.auto, .cli],
|
|
39
41
|
pipeline: ProviderFetchPipeline(resolveStrategies: { _ in [QwenAPIFetchStrategy()] })),
|
|
@@ -71,7 +73,7 @@ struct QwenAPIFetchStrategy: ProviderFetchStrategy {
|
|
|
71
73
|
}
|
|
72
74
|
}
|
|
73
75
|
|
|
74
|
-
enum QwenSettingsError: LocalizedError
|
|
76
|
+
enum QwenSettingsError: LocalizedError {
|
|
75
77
|
case missingToken
|
|
76
78
|
|
|
77
79
|
var errorDescription: String? {
|
|
@@ -46,10 +46,10 @@ public enum QwenModelPricing {
|
|
|
46
46
|
"qwen-turbo-latest": Tier(inputPerMillion: 0.30, outputPerMillion: 0.60, contextWindow: 131_072),
|
|
47
47
|
"qwen-plus": Tier(inputPerMillion: 0.80, outputPerMillion: 2.00, contextWindow: 131_072),
|
|
48
48
|
"qwen-plus-latest": Tier(inputPerMillion: 0.80, outputPerMillion: 2.00, contextWindow: 131_072),
|
|
49
|
-
"qwen-max": Tier(inputPerMillion: 2.40, outputPerMillion: 9.60, contextWindow:
|
|
50
|
-
"qwen-max-latest": Tier(inputPerMillion: 2.40, outputPerMillion: 9.60, contextWindow:
|
|
51
|
-
"qwen-vl-max": Tier(inputPerMillion: 3.00, outputPerMillion: 9.60, contextWindow:
|
|
52
|
-
"qwen-vl-max-latest": Tier(inputPerMillion: 3.00, outputPerMillion: 9.60, contextWindow:
|
|
49
|
+
"qwen-max": Tier(inputPerMillion: 2.40, outputPerMillion: 9.60, contextWindow: 32768),
|
|
50
|
+
"qwen-max-latest": Tier(inputPerMillion: 2.40, outputPerMillion: 9.60, contextWindow: 32768),
|
|
51
|
+
"qwen-vl-max": Tier(inputPerMillion: 3.00, outputPerMillion: 9.60, contextWindow: 32768),
|
|
52
|
+
"qwen-vl-max-latest": Tier(inputPerMillion: 3.00, outputPerMillion: 9.60, contextWindow: 32768),
|
|
53
53
|
"qwen-vl-plus": Tier(inputPerMillion: 0.80, outputPerMillion: 2.00, contextWindow: 131_072),
|
|
54
54
|
"qwen-long": Tier(inputPerMillion: 0.50, outputPerMillion: 2.00, contextWindow: 10_000_000),
|
|
55
55
|
"qwen2.5-72b-instruct": Tier(inputPerMillion: 0.56, outputPerMillion: 1.12, contextWindow: 131_072),
|
|
@@ -185,11 +185,25 @@ private struct QwenModelUsageRaw: Decodable {
|
|
|
185
185
|
let requests: Int?
|
|
186
186
|
let calls: Int?
|
|
187
187
|
|
|
188
|
-
var resolvedModelID: String? {
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
var
|
|
188
|
+
var resolvedModelID: String? {
|
|
189
|
+
self.model_id ?? self.model
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
var resolvedInputTokens: Int {
|
|
193
|
+
self.input_tokens ?? 0
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
var resolvedOutputTokens: Int {
|
|
197
|
+
self.output_tokens ?? 0
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
var resolvedTotalTokens: Int {
|
|
201
|
+
self.total_tokens ?? self.tokens ?? (self.resolvedInputTokens + self.resolvedOutputTokens)
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
var resolvedRequestCount: Int {
|
|
205
|
+
self.request_count ?? self.requests ?? self.calls ?? 0
|
|
206
|
+
}
|
|
193
207
|
}
|
|
194
208
|
|
|
195
209
|
// MARK: - Fetcher
|
|
@@ -241,11 +255,10 @@ public struct QwenUsageFetcher: Sendable {
|
|
|
241
255
|
let output = model.resolvedOutputTokens
|
|
242
256
|
let tokens = model.resolvedTotalTokens
|
|
243
257
|
let requests = model.resolvedRequestCount
|
|
244
|
-
let cost: Double?
|
|
245
|
-
|
|
246
|
-
cost = QwenModelPricing.estimateCost(inputTokens: input, outputTokens: output, modelID: modelID)
|
|
258
|
+
let cost: Double? = if input > 0 || output > 0 {
|
|
259
|
+
QwenModelPricing.estimateCost(inputTokens: input, outputTokens: output, modelID: modelID)
|
|
247
260
|
} else {
|
|
248
|
-
|
|
261
|
+
QwenModelPricing.estimateCost(tokens: tokens, modelID: modelID)
|
|
249
262
|
}
|
|
250
263
|
entries.append(QwenModelUsageEntry(
|
|
251
264
|
modelID: modelID,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import RunicMacroSupport
|
|
2
1
|
import Foundation
|
|
2
|
+
import RunicMacroSupport
|
|
3
3
|
|
|
4
4
|
@ProviderDescriptorRegistration
|
|
5
5
|
@ProviderDescriptorDefinition
|
|
@@ -71,7 +71,7 @@ struct SambaNovaAPIFetchStrategy: ProviderFetchStrategy {
|
|
|
71
71
|
}
|
|
72
72
|
}
|
|
73
73
|
|
|
74
|
-
enum SambaNovaSettingsError: LocalizedError
|
|
74
|
+
enum SambaNovaSettingsError: LocalizedError {
|
|
75
75
|
case missingToken
|
|
76
76
|
|
|
77
77
|
var errorDescription: String? {
|
|
@@ -8,7 +8,7 @@ struct SambaNovaModelsResponse: Decodable {
|
|
|
8
8
|
}
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
enum SambaNovaUsageFetcher {
|
|
12
12
|
static let apiURL = URL(string: "https://api.sambanova.ai/v1/models")!
|
|
13
13
|
|
|
14
14
|
static func fetchModels(apiKey: String) async throws -> SambaNovaModelsResponse {
|
|
@@ -57,7 +57,7 @@ extension SambaNovaModelsResponse {
|
|
|
57
57
|
}
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
-
enum SambaNovaAPIError: LocalizedError
|
|
60
|
+
enum SambaNovaAPIError: LocalizedError {
|
|
61
61
|
case invalidResponse
|
|
62
62
|
case httpError(statusCode: Int, body: String?)
|
|
63
63
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import RunicMacroSupport
|
|
2
1
|
import Foundation
|
|
2
|
+
import RunicMacroSupport
|
|
3
3
|
|
|
4
4
|
@ProviderDescriptorRegistration
|
|
5
5
|
@ProviderDescriptorDefinition
|
|
@@ -71,7 +71,7 @@ struct TogetherAPIFetchStrategy: ProviderFetchStrategy {
|
|
|
71
71
|
}
|
|
72
72
|
}
|
|
73
73
|
|
|
74
|
-
enum TogetherSettingsError: LocalizedError
|
|
74
|
+
enum TogetherSettingsError: LocalizedError {
|
|
75
75
|
case missingToken
|
|
76
76
|
|
|
77
77
|
var errorDescription: String? {
|
|
@@ -8,7 +8,7 @@ struct TogetherModelsResponse: Decodable {
|
|
|
8
8
|
}
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
enum TogetherUsageFetcher {
|
|
12
12
|
static let apiURL = URL(string: "https://api.together.xyz/v1/models")!
|
|
13
13
|
|
|
14
14
|
static func fetchModels(apiKey: String) async throws -> TogetherModelsResponse {
|
|
@@ -57,7 +57,7 @@ extension TogetherModelsResponse {
|
|
|
57
57
|
}
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
-
enum TogetherAPIError: LocalizedError
|
|
60
|
+
enum TogetherAPIError: LocalizedError {
|
|
61
61
|
case invalidResponse
|
|
62
62
|
case httpError(statusCode: Int, body: String?)
|
|
63
63
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import RunicMacroSupport
|
|
2
1
|
import Foundation
|
|
2
|
+
import RunicMacroSupport
|
|
3
3
|
|
|
4
4
|
@ProviderDescriptorRegistration
|
|
5
5
|
@ProviderDescriptorDefinition
|
|
@@ -75,7 +75,7 @@ struct VertexAICLIFetchStrategy: ProviderFetchStrategy {
|
|
|
75
75
|
}
|
|
76
76
|
|
|
77
77
|
private static func resolveProject(context: ProviderFetchContext) -> String? {
|
|
78
|
-
if let project =
|
|
78
|
+
if let project = cleaned(context.settings?.vertexai?.project) {
|
|
79
79
|
return project
|
|
80
80
|
}
|
|
81
81
|
if let project = Self.cleaned(context.env["VERTEX_AI_PROJECT"]) {
|
|
@@ -91,7 +91,7 @@ struct VertexAICLIFetchStrategy: ProviderFetchStrategy {
|
|
|
91
91
|
}
|
|
92
92
|
|
|
93
93
|
private static func resolveLocation(context: ProviderFetchContext) -> String? {
|
|
94
|
-
if let location =
|
|
94
|
+
if let location = cleaned(context.settings?.vertexai?.location) {
|
|
95
95
|
return location
|
|
96
96
|
}
|
|
97
97
|
if let location = Self.cleaned(context.env["VERTEX_AI_LOCATION"]) {
|
|
@@ -110,13 +110,13 @@ struct VertexAICLIFetchStrategy: ProviderFetchStrategy {
|
|
|
110
110
|
}
|
|
111
111
|
}
|
|
112
112
|
|
|
113
|
-
enum VertexAISettingsError: LocalizedError
|
|
113
|
+
enum VertexAISettingsError: LocalizedError {
|
|
114
114
|
case missingProject
|
|
115
115
|
|
|
116
116
|
var errorDescription: String? {
|
|
117
117
|
switch self {
|
|
118
118
|
case .missingProject:
|
|
119
|
-
|
|
119
|
+
"Google Cloud project not found. Set it in Preferences \u{2192} Providers \u{2192} Vertex AI or " +
|
|
120
120
|
"export VERTEX_AI_PROJECT."
|
|
121
121
|
}
|
|
122
122
|
}
|
|
@@ -27,7 +27,7 @@ public struct VertexAISettingsReader: Sendable {
|
|
|
27
27
|
public static func credentials(
|
|
28
28
|
environment: [String: String] = ProcessInfo.processInfo.environment) -> String?
|
|
29
29
|
{
|
|
30
|
-
self.cleaned(environment[credentialsKey])
|
|
30
|
+
self.cleaned(environment[self.credentialsKey])
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
static func cleaned(_ raw: String?) -> String? {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import Foundation
|
|
2
2
|
|
|
3
|
-
struct VertexAIModelsResponse: Decodable
|
|
4
|
-
struct Model: Decodable
|
|
3
|
+
struct VertexAIModelsResponse: Decodable {
|
|
4
|
+
struct Model: Decodable {
|
|
5
5
|
let name: String?
|
|
6
6
|
let displayName: String?
|
|
7
7
|
}
|
|
@@ -117,7 +117,7 @@ extension VertexAIModelsResponse {
|
|
|
117
117
|
}
|
|
118
118
|
}
|
|
119
119
|
|
|
120
|
-
enum VertexAICLIError: LocalizedError
|
|
120
|
+
enum VertexAICLIError: LocalizedError {
|
|
121
121
|
case gcloudNotFound
|
|
122
122
|
case commandFailed(statusCode: Int, detail: String?)
|
|
123
123
|
case commandTimedOut
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import RunicMacroSupport
|
|
2
1
|
import Foundation
|
|
2
|
+
import RunicMacroSupport
|
|
3
3
|
|
|
4
4
|
@ProviderDescriptorRegistration
|
|
5
5
|
@ProviderDescriptorDefinition
|
|
@@ -71,7 +71,7 @@ struct XAIApiFetchStrategy: ProviderFetchStrategy {
|
|
|
71
71
|
}
|
|
72
72
|
}
|
|
73
73
|
|
|
74
|
-
enum XAISettingsError: LocalizedError
|
|
74
|
+
enum XAISettingsError: LocalizedError {
|
|
75
75
|
case missingToken
|
|
76
76
|
|
|
77
77
|
var errorDescription: String? {
|
|
@@ -8,7 +8,7 @@ struct XAIModelsResponse: Decodable {
|
|
|
8
8
|
}
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
enum XAIUsageFetcher {
|
|
12
12
|
static let apiURL = URL(string: "https://api.x.ai/v1/models")!
|
|
13
13
|
|
|
14
14
|
static func fetchModels(apiKey: String) async throws -> XAIModelsResponse {
|
|
@@ -57,7 +57,7 @@ extension XAIModelsResponse {
|
|
|
57
57
|
}
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
-
enum XAIApiError: LocalizedError
|
|
60
|
+
enum XAIApiError: LocalizedError {
|
|
61
61
|
case invalidResponse
|
|
62
62
|
case httpError(statusCode: Int, body: String?)
|
|
63
63
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import RunicMacroSupport
|
|
2
1
|
import Foundation
|
|
2
|
+
import RunicMacroSupport
|
|
3
3
|
|
|
4
4
|
@ProviderDescriptorRegistration
|
|
5
5
|
@ProviderDescriptorDefinition
|
|
@@ -33,7 +33,9 @@ public enum ZaiProviderDescriptor {
|
|
|
33
33
|
color: ProviderColor(red: 232 / 255, green: 90 / 255, blue: 106 / 255)),
|
|
34
34
|
tokenCost: ProviderTokenCostConfig(
|
|
35
35
|
supportsTokenCost: false,
|
|
36
|
-
noDataMessage: {
|
|
36
|
+
noDataMessage: {
|
|
37
|
+
"z.ai cost estimates are shown per-model in the details submenu (based on public API pricing)."
|
|
38
|
+
}),
|
|
37
39
|
fetchPlan: ProviderFetchPlan(
|
|
38
40
|
sourceModes: [.auto, .cli],
|
|
39
41
|
pipeline: ProviderFetchPipeline(resolveStrategies: { _ in [ZaiAPIFetchStrategy()] })),
|