1- import { createOpenAI } from "@ai-sdk/openai" ;
2- import { createGoogleGenerativeAI } from "@ai-sdk/google" ;
3- import { createOpenAICompatible } from "@ai-sdk/openai-compatible" ;
41import { streamText , UIMessage , convertToModelMessages } from "ai" ;
2+ import { getModel , requiresApiKey , type AIProvider } from "@/lib/ai/models" ;
3+ import { buildSystemMessage } from "@/lib/ai/prompt" ;
54
65// Allow streaming responses up to 30 seconds
76export const maxDuration = 30 ;
87
9- export async function POST ( req : Request ) {
10- const {
11- messages,
12- system,
13- pageContext,
14- provider,
15- apiKey,
16- } : {
17- messages : UIMessage [ ] ;
18- system ?: string ; // System message forwarded from AssistantChatTransport
19- tools ?: unknown ; // Frontend tools forwarded from AssistantChatTransport
20- pageContext ?: {
21- title ?: string ;
22- description ?: string ;
23- content ?: string ;
24- slug ?: string ;
25- } ;
26- provider ?: "openai" | "gemini" | "intern" ;
27- apiKey ?: string ;
28- } = await req . json ( ) ;
29-
30- // Check if API key is provided (not required for intern provider)
31- if ( provider !== "intern" && ( ! apiKey || apiKey . trim ( ) === "" ) ) {
32- return Response . json (
33- {
34- error :
35- "API key is required. Please configure your API key in the settings." ,
36- } ,
37- { status : 400 } ,
38- ) ;
39- }
8+ interface ChatRequest {
9+ messages : UIMessage [ ] ;
10+ system ?: string ; // System message forwarded from AssistantChatTransport
11+ tools ?: unknown ; // Frontend tools forwarded from AssistantChatTransport
12+ pageContext ?: {
13+ title ?: string ;
14+ description ?: string ;
15+ content ?: string ;
16+ slug ?: string ;
17+ } ;
18+ provider ?: AIProvider ;
19+ apiKey ?: string ;
20+ }
4021
22+ export async function POST ( req : Request ) {
4123 try {
42- // Build system message with page context
43- let systemMessage =
44- system ||
45- `You are a helpful AI assistant for a documentation website.
46- You can help users understand the documentation, answer questions about the content,
47- and provide guidance on the topics covered in the docs. Be concise and helpful.` ;
24+ const {
25+ messages,
26+ system,
27+ pageContext,
28+ provider = "openai" , // Default to OpenAI
29+ apiKey,
30+ } : ChatRequest = await req . json ( ) ;
4831
49- // Add current page context if available
50- if ( pageContext ?. content ) {
51- systemMessage += `\n\n--- CURRENT PAGE CONTEXT ---\n` ;
52- if ( pageContext . title ) {
53- systemMessage += `Page Title: ${ pageContext . title } \n` ;
54- }
55- if ( pageContext . description ) {
56- systemMessage += `Page Description: ${ pageContext . description } \n` ;
57- }
58- if ( pageContext . slug ) {
59- systemMessage += `Page URL: /docs/${ pageContext . slug } \n` ;
60- }
61- systemMessage += `Page Content:\n${ pageContext . content } ` ;
62- systemMessage += `\n--- END OF CONTEXT ---\n\nWhen users ask about "this page", "current page", or refer to the content they're reading, use the above context to provide accurate answers. You can summarize, explain, or answer specific questions about the current page content.` ;
32+ // Validate API key for providers that require it
33+ if ( requiresApiKey ( provider ) && ( ! apiKey || apiKey . trim ( ) === "" ) ) {
34+ return Response . json (
35+ {
36+ error :
37+ "API key is required. Please configure your API key in the settings." ,
38+ } ,
39+ { status : 400 } ,
40+ ) ;
6341 }
6442
65- // Select model based on provider
66- let model ;
67- if ( provider === "gemini" ) {
68- const customGoogle = createGoogleGenerativeAI ( {
69- apiKey : apiKey ,
70- } ) ;
71- model = customGoogle ( "models/gemini-2.0-flash" ) ;
72- } else if ( provider === "intern" ) {
73- const intern = createOpenAICompatible ( {
74- name : "intern" ,
75- baseURL : "https://chat.intern-ai.org.cn/api/v1/" ,
76- apiKey : process . env . INTERN_KEY ,
77- } ) ;
78- model = intern ( "intern-s1" ) ;
79- } else {
80- // Default to OpenAI
81- const customOpenAI = createOpenAI ( {
82- apiKey : apiKey ,
83- } ) ;
84- model = customOpenAI ( "gpt-4.1-nano" ) ;
85- }
43+ // Build system message with page context
44+ const systemMessage = buildSystemMessage ( system , pageContext ) ;
45+
46+ // Get AI model instance based on provider
47+ const model = getModel ( provider , apiKey ) ;
8648
49+ // Generate streaming response
8750 const result = streamText ( {
8851 model : model ,
8952 system : systemMessage ,
@@ -93,6 +56,12 @@ export async function POST(req: Request) {
9356 return result . toUIMessageStreamResponse ( ) ;
9457 } catch ( error ) {
9558 console . error ( "Chat API error:" , error ) ;
59+
60+ // Handle specific model creation errors
61+ if ( error instanceof Error && error . message . includes ( "API key" ) ) {
62+ return Response . json ( { error : error . message } , { status : 400 } ) ;
63+ }
64+
9665 return Response . json (
9766 { error : "Failed to process chat request" } ,
9867 { status : 500 } ,
0 commit comments