fix: add dialog for vercel ai gateway activation (#1195)

This commit is contained in:
Nico Albanese 2025-09-13 20:40:08 +01:00 committed by GitHub
parent a9c812b5c4
commit 38156eafcf
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 68 additions and 5 deletions

View file

@ -242,6 +242,16 @@ export async function POST(request: Request) {
return error.toResponse(); return error.toResponse();
} }
// Check for Vercel AI Gateway credit card error
if (
error instanceof Error &&
error.message?.includes(
'AI Gateway requires a valid credit card on file to service requests',
)
) {
return new ChatSDKError('bad_request:activate_gateway').toResponse();
}
console.error('Unhandled error in chat API:', error); console.error('Unhandled error in chat API:', error);
return new ChatSDKError('offline:chat').toResponse(); return new ChatSDKError('offline:chat').toResponse();
} }

View file

@ -22,6 +22,16 @@ import { useAutoResume } from '@/hooks/use-auto-resume';
import { ChatSDKError } from '@/lib/errors'; import { ChatSDKError } from '@/lib/errors';
import type { Attachment, ChatMessage } from '@/lib/types'; import type { Attachment, ChatMessage } from '@/lib/types';
import { useDataStream } from './data-stream-provider'; import { useDataStream } from './data-stream-provider';
import {
AlertDialog,
AlertDialogAction,
AlertDialogCancel,
AlertDialogContent,
AlertDialogDescription,
AlertDialogFooter,
AlertDialogHeader,
AlertDialogTitle,
} from '@/components/ui/alert-dialog';
export function Chat({ export function Chat({
id, id,
@ -54,6 +64,7 @@ export function Chat({
const [usage, setUsage] = useState<LanguageModelUsage | undefined>( const [usage, setUsage] = useState<LanguageModelUsage | undefined>(
initialLastContext, initialLastContext,
); );
const [showCreditCardAlert, setShowCreditCardAlert] = useState(false);
const { const {
messages, messages,
@ -94,10 +105,17 @@ export function Chat({
}, },
onError: (error) => { onError: (error) => {
if (error instanceof ChatSDKError) { if (error instanceof ChatSDKError) {
toast({ // Check if it's a credit card error
type: 'error', if (
description: error.message, error.message?.includes('AI Gateway requires a valid credit card')
}); ) {
setShowCreditCardAlert(true);
} else {
toast({
type: 'error',
description: error.message,
});
}
} }
}, },
}); });
@ -194,6 +212,36 @@ export function Chat({
selectedVisibilityType={visibilityType} selectedVisibilityType={visibilityType}
selectedModelId={initialChatModel} selectedModelId={initialChatModel}
/> />
<AlertDialog
open={showCreditCardAlert}
onOpenChange={setShowCreditCardAlert}
>
<AlertDialogContent>
<AlertDialogHeader>
<AlertDialogTitle>Activate AI Gateway</AlertDialogTitle>
<AlertDialogDescription>
This application requires{' '}
{process.env.NODE_ENV === 'production' ? 'the owner' : 'you'} to
activate Vercel AI Gateway.
</AlertDialogDescription>
</AlertDialogHeader>
<AlertDialogFooter>
<AlertDialogCancel>Cancel</AlertDialogCancel>
<AlertDialogAction
onClick={() => {
window.open(
'https://vercel.com/d?to=%2F%5Bteam%5D%2F%7E%2Fai%3Fmodal%3Dadd-credit-card',
'_blank',
);
window.location.href = '/';
}}
>
Activate
</AlertDialogAction>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
</> </>
); );
} }

View file

@ -15,7 +15,8 @@ export type Surface =
| 'history' | 'history'
| 'vote' | 'vote'
| 'document' | 'document'
| 'suggestions'; | 'suggestions'
| 'activate_gateway';
export type ErrorCode = `${ErrorType}:${Surface}`; export type ErrorCode = `${ErrorType}:${Surface}`;
@ -31,6 +32,7 @@ export const visibilityBySurface: Record<Surface, ErrorVisibility> = {
vote: 'response', vote: 'response',
document: 'response', document: 'response',
suggestions: 'response', suggestions: 'response',
activate_gateway: 'response',
}; };
export class ChatSDKError extends Error { export class ChatSDKError extends Error {
@ -82,6 +84,9 @@ export function getMessageByErrorCode(errorCode: ErrorCode): string {
case 'bad_request:api': case 'bad_request:api':
return "The request couldn't be processed. Please check your input and try again."; return "The request couldn't be processed. Please check your input and try again.";
case 'bad_request:activate_gateway':
return 'AI Gateway requires a valid credit card on file to service requests. Please visit https://vercel.com/d?to=%2F%5Bteam%5D%2F%7E%2Fai%3Fmodal%3Dadd-credit-card to add a card and unlock your free credits.';
case 'unauthorized:auth': case 'unauthorized:auth':
return 'You need to sign in before continuing.'; return 'You need to sign in before continuing.';
case 'forbidden:auth': case 'forbidden:auth':