feat: sync deployed v1.0.0-rc.38-custom.42
Sync production source including routing, billing, Astra detection and public uptime. Update custom build instructions and license packaging.
This commit is contained in:
1 parent
aa6c3f50f4
commit
ceddfd3d6b
828 files changed
+122253
-13702
No files matched your search
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
Copyright (C) 2023-2026 QuantumNous
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
For commercial licensing, please contact support@quantumnous.com
|
||||
*/
|
||||
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
|
||||
import { useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
||||
import { ConfirmDialog } from '@/components/confirm-dialog'
|
||||
import { getUserProfile, updateUserSettings } from '@/features/profile/api'
|
||||
import { parseUserSettings } from '@/features/profile/lib/format'
|
||||
import { handleServerError } from '@/lib/handle-server-error'
|
||||
import { requireServerSuccess } from '@/lib/server-error-message'
|
||||
import { useAuthStore } from '@/stores/auth-store'
|
||||
import { getApiKeys } from '../api'
|
||||
|
||||
export function AstraCostNotice() {
|
||||
const { t } = useTranslation()
|
||||
const userId = useAuthStore((state) => state.auth.user?.id)
|
||||
const queryClient = useQueryClient()
|
||||
const [dismissedUserId, setDismissedUserId] = useState<number>()
|
||||
const noticeKey = ['astra-cost-notice', userId]
|
||||
const { data: profile } = useQuery({
|
||||
queryKey: noticeKey,
|
||||
queryFn: async () => requireServerSuccess(await getUserProfile()).data,
|
||||
enabled: userId !== undefined,
|
||||
})
|
||||
const { data: hasMigratedToken } = useQuery({
|
||||
queryKey: ['astra-cost-notice-tokens', userId],
|
||||
queryFn: async () => {
|
||||
let page = 1
|
||||
for (;;) {
|
||||
const result = await getApiKeys({ p: page, size: 100 })
|
||||
if (!result.success || !result.data) {
|
||||
throw new Error(result.message || t('Failed to load API keys'))
|
||||
}
|
||||
if (result.data.items.some((token) => token.astra_auto_switch === true)) {
|
||||
return true
|
||||
}
|
||||
if (page * result.data.page_size >= result.data.total) return false
|
||||
page += 1
|
||||
}
|
||||
},
|
||||
enabled: userId !== undefined,
|
||||
})
|
||||
const acknowledge = useMutation({
|
||||
mutationFn: async () => requireServerSuccess(await updateUserSettings({ astra_cost_notice_ack: true })),
|
||||
onSuccess: () => {
|
||||
setDismissedUserId(userId)
|
||||
void queryClient.invalidateQueries({ queryKey: noticeKey })
|
||||
},
|
||||
onError: (error) => handleServerError(error, t('Failed to update settings')),
|
||||
})
|
||||
return (
|
||||
<ConfirmDialog
|
||||
open={!!profile && hasMigratedToken === true && !parseUserSettings(profile.setting).astra_cost_notice_ack && dismissedUserId !== userId}
|
||||
onOpenChange={(value) => { if (!value && !acknowledge.isPending) setDismissedUserId(userId) }}
|
||||
title={t('Astra auto-switch and charges')}
|
||||
desc={t('Existing API keys keep Astra auto-switch enabled; new keys default to off. Rejected results still incur usage charges, and every additional upstream attempt is charged separately. You can change this setting for each API key.')}
|
||||
cancelBtnText={t('Remind me next time')}
|
||||
confirmText={t('I understand')}
|
||||
isLoading={acknowledge.isPending}
|
||||
handleConfirm={() => acknowledge.mutate()}
|
||||
/>
|
||||
)
|
||||
}
|
||||
Reference in new issue
Block a user