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();
}
// 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);
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 type { Attachment, ChatMessage } from '@/lib/types';
import { useDataStream } from './data-stream-provider';
import {
AlertDialog,
AlertDialogAction,
AlertDialogCancel,
AlertDialogContent,
AlertDialogDescription,
AlertDialogFooter,
AlertDialogHeader,
AlertDialogTitle,
} from '@/components/ui/alert-dialog';
export function Chat({
id,
@ -54,6 +64,7 @@ export function Chat({
const [usage, setUsage] = useState<LanguageModelUsage | undefined>(
initialLastContext,
);
const [showCreditCardAlert, setShowCreditCardAlert] = useState(false);
const {
messages,
@ -94,10 +105,17 @@ export function Chat({
},
onError: (error) => {
if (error instanceof ChatSDKError) {
toast({
type: 'error',
description: error.message,
});
// Check if it's a credit card error
if (
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}
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'
| 'vote'
| 'document'
| 'suggestions';
| 'suggestions'
| 'activate_gateway';
export type ErrorCode = `${ErrorType}:${Surface}`;
@ -31,6 +32,7 @@ export const visibilityBySurface: Record<Surface, ErrorVisibility> = {
vote: 'response',
document: 'response',
suggestions: 'response',
activate_gateway: 'response',
};
export class ChatSDKError extends Error {
@ -82,6 +84,9 @@ export function getMessageByErrorCode(errorCode: ErrorCode): string {
case 'bad_request:api':
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':
return 'You need to sign in before continuing.';
case 'forbidden:auth':