diff --git a/src/main/services/WindowService.ts b/src/main/services/WindowService.ts index 9b8a176a34..7cf01b9fc7 100644 --- a/src/main/services/WindowService.ts +++ b/src/main/services/WindowService.ts @@ -275,7 +275,8 @@ export class WindowService { 'https://aihubmix.com/topup', 'https://aihubmix.com/statistics', 'https://dash.302.ai/sso/login', - 'https://dash.302.ai/charge' + 'https://dash.302.ai/charge', + 'https://www.aiionly.com/login' ] if (oauthProviderUrls.some((link) => url.startsWith(link))) { diff --git a/src/renderer/src/assets/images/providers/aiOnly.png b/src/renderer/src/assets/images/providers/aiOnly.png new file mode 100644 index 0000000000..a521f3bcb8 Binary files /dev/null and b/src/renderer/src/assets/images/providers/aiOnly.png differ diff --git a/src/renderer/src/components/OAuth/OAuthButton.tsx b/src/renderer/src/components/OAuth/OAuthButton.tsx index fec3aae619..3368f60afe 100644 --- a/src/renderer/src/components/OAuth/OAuthButton.tsx +++ b/src/renderer/src/components/OAuth/OAuthButton.tsx @@ -3,6 +3,7 @@ import { Provider } from '@renderer/types' import { oauthWith302AI, oauthWithAihubmix, + oauthWithAiOnly, oauthWithPPIO, oauthWithSiliconFlow, oauthWithTokenFlux @@ -46,6 +47,10 @@ const OAuthButton: FC = ({ provider, onSuccess, ...buttonProps }) => { if (provider.id === '302ai') { oauthWith302AI(handleSuccess) } + + if (provider.id === 'aionly') { + oauthWithAiOnly(handleSuccess) + } } return ( diff --git a/src/renderer/src/config/models/default.ts b/src/renderer/src/config/models/default.ts index 1b8e9ad1bc..2f13a5e993 100644 --- a/src/renderer/src/config/models/default.ts +++ b/src/renderer/src/config/models/default.ts @@ -1785,5 +1785,37 @@ export const SYSTEM_MODELS: Record = provider: 'poe', group: 'poe' } + ], + aionly: [ + { + id: 'claude-opus-4.1', + name: 'claude-opus-4.1', + provider: 'aionly', + group: 'claude' + }, + { + id: 'claude-sonnet4', + name: 'claude-sonnet4', + provider: 'aionly', + group: 'claude' + }, + { + id: 'claude-3.5-sonnet-v2', + name: 'claude-3.5-sonnet-v2', + provider: 'aionly', + group: 'claude' + }, + { + id: 'gpt-4.1', + name: 'gpt-4.1', + provider: 'aionly', + group: 'gpt' + }, + { + id: 'gemini-2.5-flash', + name: 'gemini-2.5-flash', + provider: 'aionly', + group: 'gemini' + } ] } diff --git a/src/renderer/src/config/providers.ts b/src/renderer/src/config/providers.ts index a710605b64..e07414e2c2 100644 --- a/src/renderer/src/config/providers.ts +++ b/src/renderer/src/config/providers.ts @@ -3,6 +3,7 @@ import HunyuanProviderLogo from '@renderer/assets/images/models/hunyuan.png' import AzureProviderLogo from '@renderer/assets/images/models/microsoft.png' import Ai302ProviderLogo from '@renderer/assets/images/providers/302ai.webp' import AiHubMixProviderLogo from '@renderer/assets/images/providers/aihubmix.webp' +import AiOnlyProviderLogo from '@renderer/assets/images/providers/aiOnly.png' import AlayaNewProviderLogo from '@renderer/assets/images/providers/alayanew.webp' import AnthropicProviderLogo from '@renderer/assets/images/providers/anthropic.png' import AwsProviderLogo from '@renderer/assets/images/providers/aws-bedrock.webp' @@ -600,6 +601,16 @@ export const SYSTEM_PROVIDERS_CONFIG: Record = models: SYSTEM_MODELS['poe'], isSystem: true, enabled: false + }, + aionly: { + id: 'aionly', + name: 'AIOnly', + type: 'openai', + apiKey: '', + apiHost: 'https://api.aiionly.com', + models: SYSTEM_MODELS.aionly, + isSystem: true, + enabled: false } } as const @@ -661,7 +672,8 @@ export const PROVIDER_LOGO_MAP: AtLeast = { vertexai: VertexAIProviderLogo, 'new-api': NewAPIProviderLogo, 'aws-bedrock': AwsProviderLogo, - poe: 'poe' // use svg icon component + poe: 'poe', // use svg icon component + aionly: AiOnlyProviderLogo } as const export function getProviderLogo(providerId: string) { @@ -1255,6 +1267,17 @@ export const PROVIDER_URLS: Record = { docs: 'https://creator.poe.com/docs/external-applications/openai-compatible-api', models: 'https://poe.com/' } + }, + aionly: { + api: { + url: 'https://api.aiionly.com' + }, + websites: { + official: 'https://www.aiionly.com', + apiKey: 'https://www.aiionly.com/keyApi', + docs: 'https://www.aiionly.com/document', + models: 'https://www.aiionly.com' + } } } diff --git a/src/renderer/src/i18n/label.ts b/src/renderer/src/i18n/label.ts index 8d621f6517..a07daa975f 100644 --- a/src/renderer/src/i18n/label.ts +++ b/src/renderer/src/i18n/label.ts @@ -80,7 +80,8 @@ const providerKeyMap = { yi: 'provider.yi', zhinao: 'provider.zhinao', zhipu: 'provider.zhipu', - poe: 'provider.poe' + poe: 'provider.poe', + aionly: 'provider.aionly' } as const /** diff --git a/src/renderer/src/i18n/locales/en-us.json b/src/renderer/src/i18n/locales/en-us.json index d576d5544f..dfd09049ed 100644 --- a/src/renderer/src/i18n/locales/en-us.json +++ b/src/renderer/src/i18n/locales/en-us.json @@ -2018,6 +2018,7 @@ "provider": { "302ai": "302.AI", "aihubmix": "AiHubMix", + "aionly": "AiOnly", "alayanew": "Alaya NeW", "anthropic": "Anthropic", "aws-bedrock": "AWS Bedrock", diff --git a/src/renderer/src/i18n/locales/zh-cn.json b/src/renderer/src/i18n/locales/zh-cn.json index 28a53923e5..defbfe9dd6 100644 --- a/src/renderer/src/i18n/locales/zh-cn.json +++ b/src/renderer/src/i18n/locales/zh-cn.json @@ -2018,6 +2018,7 @@ "provider": { "302ai": "302.AI", "aihubmix": "AiHubMix", + "aionly": "唯一AI(AiOnly)", "alayanew": "Alaya NeW", "anthropic": "Anthropic", "aws-bedrock": "AWS Bedrock", diff --git a/src/renderer/src/i18n/locales/zh-tw.json b/src/renderer/src/i18n/locales/zh-tw.json index e191e940c7..b5ac09bb7f 100644 --- a/src/renderer/src/i18n/locales/zh-tw.json +++ b/src/renderer/src/i18n/locales/zh-tw.json @@ -2018,6 +2018,7 @@ "provider": { "302ai": "302.AI", "aihubmix": "AiHubMix", + "aionly": "唯一AI(AiOnly)", "alayanew": "Alaya NeW", "anthropic": "Anthropic", "aws-bedrock": "AWS Bedrock", diff --git a/src/renderer/src/i18n/translate/el-gr.json b/src/renderer/src/i18n/translate/el-gr.json index 8741347fcf..71aca53b82 100644 --- a/src/renderer/src/i18n/translate/el-gr.json +++ b/src/renderer/src/i18n/translate/el-gr.json @@ -2017,6 +2017,7 @@ "provider": { "302ai": "302.AI", "aihubmix": "AiHubMix", + "aionly": "AiOnly", "alayanew": "Alaya NeW", "anthropic": "Anthropic", "aws-bedrock": "AWS Bedrock", diff --git a/src/renderer/src/i18n/translate/es-es.json b/src/renderer/src/i18n/translate/es-es.json index 7bbb64a11c..de3b5cb17f 100644 --- a/src/renderer/src/i18n/translate/es-es.json +++ b/src/renderer/src/i18n/translate/es-es.json @@ -2017,6 +2017,7 @@ "provider": { "302ai": "302.AI", "aihubmix": "AiHubMix", + "aionly": "AiOnly", "alayanew": "Alaya NeW", "anthropic": "Antropológico", "aws-bedrock": "AWS Bedrock", diff --git a/src/renderer/src/i18n/translate/fr-fr.json b/src/renderer/src/i18n/translate/fr-fr.json index ab74489903..66a3a5b4ae 100644 --- a/src/renderer/src/i18n/translate/fr-fr.json +++ b/src/renderer/src/i18n/translate/fr-fr.json @@ -2017,6 +2017,7 @@ "provider": { "302ai": "302.AI", "aihubmix": "AiHubMix", + "aionly": "AiOnly", "alayanew": "Alaya NeW", "anthropic": "Anthropic", "aws-bedrock": "AWS Bedrock", diff --git a/src/renderer/src/i18n/translate/ja-jp.json b/src/renderer/src/i18n/translate/ja-jp.json index 04bac6fbd0..bee5f54470 100644 --- a/src/renderer/src/i18n/translate/ja-jp.json +++ b/src/renderer/src/i18n/translate/ja-jp.json @@ -2017,6 +2017,7 @@ "provider": { "302ai": "302.AI", "aihubmix": "AiHubMix", + "aionly": "AiOnly", "alayanew": "Alaya NeW", "anthropic": "Anthropic", "aws-bedrock": "AWS Bedrock", diff --git a/src/renderer/src/i18n/translate/pt-pt.json b/src/renderer/src/i18n/translate/pt-pt.json index 4f18f55ef7..5c9bbf566e 100644 --- a/src/renderer/src/i18n/translate/pt-pt.json +++ b/src/renderer/src/i18n/translate/pt-pt.json @@ -2017,6 +2017,7 @@ "provider": { "302ai": "302.AI", "aihubmix": "AiHubMix", + "aionly": "AiOnly", "alayanew": "Alaya NeW", "anthropic": "Antropológico", "aws-bedrock": "AWS Bedrock", diff --git a/src/renderer/src/i18n/translate/ru-ru.json b/src/renderer/src/i18n/translate/ru-ru.json index 88ce796529..ec50afccd0 100644 --- a/src/renderer/src/i18n/translate/ru-ru.json +++ b/src/renderer/src/i18n/translate/ru-ru.json @@ -2017,6 +2017,7 @@ "provider": { "302ai": "302.AI", "aihubmix": "AiHubMix", + "aionly": "AiOnly", "alayanew": "Alaya NeW", "anthropic": "Anthropic", "aws-bedrock": "AWS Bedrock", diff --git a/src/renderer/src/pages/settings/ProviderSettings/ProviderOAuth.tsx b/src/renderer/src/pages/settings/ProviderSettings/ProviderOAuth.tsx index 5315110dc2..5fdafa5f23 100644 --- a/src/renderer/src/pages/settings/ProviderSettings/ProviderOAuth.tsx +++ b/src/renderer/src/pages/settings/ProviderSettings/ProviderOAuth.tsx @@ -1,5 +1,6 @@ import AI302ProviderLogo from '@renderer/assets/images/providers/302ai.webp' import AiHubMixProviderLogo from '@renderer/assets/images/providers/aihubmix.webp' +import AiOnlyProviderLogo from '@renderer/assets/images/providers/aiOnly.png' import PPIOProviderLogo from '@renderer/assets/images/providers/ppio.png' import SiliconFlowProviderLogo from '@renderer/assets/images/providers/silicon.png' import TokenFluxProviderLogo from '@renderer/assets/images/providers/tokenflux.png' @@ -25,7 +26,8 @@ const PROVIDER_LOGO_MAP = { silicon: SiliconFlowProviderLogo, aihubmix: AiHubMixProviderLogo, ppio: PPIOProviderLogo, - tokenflux: TokenFluxProviderLogo + tokenflux: TokenFluxProviderLogo, + aionly: AiOnlyProviderLogo } const ProviderOAuth: FC = ({ providerId }) => { diff --git a/src/renderer/src/services/ProviderService.ts b/src/renderer/src/services/ProviderService.ts index 7a6409c903..da6df82adc 100644 --- a/src/renderer/src/services/ProviderService.ts +++ b/src/renderer/src/services/ProviderService.ts @@ -33,7 +33,7 @@ export function getProviderByModel(model?: Model) { } export function isProviderSupportAuth(provider: Provider) { - const supportProviders = ['302ai', 'silicon', 'aihubmix', 'ppio', 'tokenflux'] + const supportProviders = ['302ai', 'silicon', 'aihubmix', 'ppio', 'tokenflux', 'aionly'] return supportProviders.includes(provider.id) } diff --git a/src/renderer/src/store/migrate.ts b/src/renderer/src/store/migrate.ts index 41fa441945..f7fc92ee44 100644 --- a/src/renderer/src/store/migrate.ts +++ b/src/renderer/src/store/migrate.ts @@ -2479,6 +2479,7 @@ const migrateConfig = { }, '156': (state: RootState) => { try { + addProvider(state, 'aionly') state.llm.providers.forEach((provider) => { if (provider.id === SystemProviderIds.anthropic) { if (provider.apiHost.endsWith('/')) { diff --git a/src/renderer/src/types/index.ts b/src/renderer/src/types/index.ts index cd2562e55a..2d580c8e37 100644 --- a/src/renderer/src/types/index.ts +++ b/src/renderer/src/types/index.ts @@ -321,7 +321,8 @@ export const SystemProviderIds = { gpustack: 'gpustack', voyageai: 'voyageai', 'aws-bedrock': 'aws-bedrock', - poe: 'poe' + poe: 'poe', + aionly: 'aionly' } as const export type SystemProviderId = keyof typeof SystemProviderIds diff --git a/src/renderer/src/utils/oauth.ts b/src/renderer/src/utils/oauth.ts index 9fbb632a07..5d57547f69 100644 --- a/src/renderer/src/utils/oauth.ts +++ b/src/renderer/src/utils/oauth.ts @@ -172,6 +172,27 @@ export const oauthWith302AI = async (setKey) => { window.addEventListener('message', messageHandler) } +export const oauthWithAiOnly = async (setKey) => { + const authUrl = `https://www.aiionly.com/login?inviteCode=1755481173663DrZBBOC0&cherryCode=01` + + const popup = window.open( + authUrl, + 'login', + 'width=720,height=720,toolbar=no,location=no,status=no,menubar=no,scrollbars=yes,resizable=yes,alwaysOnTop=yes,alwaysRaised=yes' + ) + + const messageHandler = (event) => { + if (event.data.length > 0 && event.data[0]['secretKey'] !== undefined) { + setKey(event.data[0]['secretKey']) + popup?.close() + window.removeEventListener('message', messageHandler) + } + } + + window.removeEventListener('message', messageHandler) + window.addEventListener('message', messageHandler) +} + export const providerCharge = async (provider: string) => { const chargeUrlMap = { silicon: { @@ -198,6 +219,11 @@ export const providerCharge = async (provider: string) => { url: 'https://dash.302.ai/charge', width: 900, height: 700 + }, + aionly: { + url: `https://www.aiionly.com/recharge`, + width: 900, + height: 700 } } @@ -236,6 +262,11 @@ export const providerBills = async (provider: string) => { url: 'https://dash.302.ai/charge', width: 900, height: 700 + }, + aionly: { + url: `https://www.aiionly.com/billManagement`, + width: 900, + height: 700 } }