1- // import { env } from "node:process";
1+ import { env } from "node:process" ;
22import { createVertex } from "@ai-sdk/google-vertex" ;
3- import { streamText } from "ai" ;
3+ import { streamText , convertToCoreMessages } from "ai" ;
44import { StatusCodes , ReasonPhrases } from "http-status-codes" ;
5- import { getContext } from "@/lib/smart-search .mjs" ;
5+ import { smartSearchTool } from "@/lib/rag .mjs" ;
66
7- const vertex = createVertex ( ) ;
7+ console . log ( "Initializing Google Vertex AI..." ) ;
8+ // Ensure all required environment variables are set
9+ if ( ! env . GOOGLE_VERTEX_PROJECT ) {
10+ throw new Error ( "GOOGLE_VERTEX_PROJECT is not set" ) ;
11+ }
12+
13+ if ( ! env . GOOGLE_VERTEX_LOCATION ) {
14+ throw new Error ( "GOOGLE_VERTEX_LOCATION is not set" ) ;
15+ }
16+
17+ if ( ! env . GOOGLE_VERTEX_CLIENT_EMAIL ) {
18+ throw new Error ( "GOOGLE_VERTEX_CLIENT_EMAIL is not set" ) ;
19+ }
20+
21+ if ( ! env . GOOGLE_VERTEX_PRIVATE_KEY ) {
22+ throw new Error ( "GOOGLE_VERTEX_PRIVATE_KEY is not set" ) ;
23+ }
24+
25+ if ( ! env . GOOGLE_VERTEX_PRIVATE_KEY . includes ( "-----BEGIN PRIVATE KEY-----" ) ) {
26+ throw new Error ( "GOOGLE_VERTEX_PRIVATE_KEY is not formatted correctly" ) ;
27+ }
28+
29+ const vertex = createVertex ( {
30+ project : env . GOOGLE_VERTEX_PROJECT ,
31+ location : env . GOOGLE_VERTEX_LOCATION ,
32+ googleAuthOptions : {
33+ credentials : {
34+ client_email : env . GOOGLE_VERTEX_CLIENT_EMAIL ,
35+ private_key : env . GOOGLE_VERTEX_PRIVATE_KEY . replaceAll (
36+ String . raw `\n` ,
37+ "\n" ,
38+ ) , // Ensure newlines are correctly formatted
39+ } ,
40+ } ,
41+ } ) ;
42+
43+ const smartSearchPrompt = `
44+ - You can use the 'smartSearchTool' to find information relating to Faust.
45+ - WP Engine Smart Search is a powerful tool for finding information about Faust.
46+ - After the 'smartSearchTool' provides results (even if it's an error or no information found)
47+ - You MUST then formulate a conversational response to the user based on those results but also use the tool if the users query is deemed plausible.
48+ - If search results are found, summarize them for the user.
49+ - If no information is found or an error occurs, inform the user clearly.` ;
50+
51+ const systemPromptContent = `
52+ - You are a friendly and helpful AI assistant
53+ - Do not invent information. Stick to the data provided by the tool.` ;
854
955export async function POST ( req ) {
1056 try {
@@ -16,74 +62,36 @@ export async function POST(req) {
1662 } ) ;
1763 }
1864
19- const [ latestMessage ] = messages . slice ( - 1 ) ;
20- const previousMessages = messages . slice ( - 11 , - 1 ) ;
21-
22- const promptContext = await getContext ( latestMessage . content ) ;
23-
24- if (
25- ! promptContext ||
26- ! promptContext . data ||
27- ! promptContext . data . similarity
28- ) {
29- console . error (
30- "No context found for the latest message:" ,
31- latestMessage . content ,
32- "Context response:" ,
33- promptContext ,
34- ) ;
35- return new Response ( ReasonPhrases . INTERNAL_SERVER_ERROR , {
36- status : StatusCodes . INTERNAL_SERVER_ERROR ,
37- } ) ;
38- }
39-
40- const messageContext = promptContext . data . similarity . docs . map ( ( doc ) => {
41- return `
42- ID: ${ doc . id }
43- Title: ${ doc . data . post_title }
44- Content: ${ doc . data . post_content }
45- SearchScore: ${ doc . score }
46- ` ;
47- } ) ;
48-
49- const prompt = {
50- role : "assistant" ,
51- content : `You are a AI assistant that provides information about Faust.js and headless WordPress.
52- AI assistant is a brand new, powerful, human-like artificial intelligence.
53- The traits of AI include expert knowledge, helpfulness, cleverness, and articulateness.
54- AI is a well-behaved and well-mannered individual.
55- AI is always friendly, kind, and inspiring, and he is eager to provide vivid and thoughtful responses to the user.
56- AI has the sum of all knowledge in their brain, and is able to accurately answer nearly any question about any topic in conversation.
57- AI assistant is a big fan of WP Engine Smart Search.
58- AI assistant uses WP Engine Smart Search to provide the most accurate and relevant information to the user.
59- AI assistant data from WP Engine Smart Search is based on TV Shows.
60- START CONTEXT BLOCK
61- ${ messageContext . join ( "----------------\n\n" ) }
62- END OF CONTEXT BLOCK
63-
64- START OF HISTORY BLOCK
65- ${ JSON . stringify ( previousMessages ) }
66- END OF HISTORY BLOCK
67- AI assistant will take into account any CONTEXT BLOCK that is provided in a conversation.
68- AI assistant will take into account any HISTORY BLOCK that is provided in a conversation.
69- If the context does not provide the answer to question, the AI assistant will say, "I'm sorry, but I don't know the answer to that question".
70- AI assistant will not apologize for previous responses, but instead will indicated new information was gained.
71- AI assistant will not invent anything that is not drawn directly from the context.
72- AI assistant will answer coding questions.
73- ` ,
74- } ;
75-
76- console . log ( "Prompt context:" , prompt ) ;
65+ const coreMessages = convertToCoreMessages ( messages ) ;
7766
7867 const response = await streamText ( {
79- model : vertex . languageModel ( "gemini-2.0-flash-exp" ) ,
80- prompt,
81- messages : messages . filter ( ( message ) => message . role === "user" ) ,
68+ model : vertex ( "gemini-2.5-pro" ) ,
69+ system : [ systemPromptContent , smartSearchPrompt ] . join ( "\n" ) ,
70+ messages : coreMessages ,
71+ tools : {
72+ smartSearchTool,
73+ } ,
74+ onError : ( error ) => {
75+ console . error ( "Error during streaming:" , error ) ;
76+ return new Response ( ReasonPhrases . INTERNAL_SERVER_ERROR , {
77+ status : StatusCodes . INTERNAL_SERVER_ERROR ,
78+ } ) ;
79+ } ,
80+ onToolCall : async ( toolCall ) => {
81+ console . log ( "Tool call initiated:" , toolCall ) ;
82+ } ,
83+ onStepFinish : async ( result ) => {
84+ console . log ( "Step finished:" , result ) ;
85+ if ( result . usage ) {
86+ console . log (
87+ `[Token Usage] Prompt tokens: ${ result . usage . promptTokens } , Completion tokens: ${ result . usage . completionTokens } , Total tokens: ${ result . usage . totalTokens } ` ,
88+ ) ;
89+ }
90+ } ,
91+ maxSteps : 5 ,
8292 } ) ;
8393
84- console . log ( "Response from AI:" , response ) ;
85-
86- return response . toTextStreamResponse ( ) ;
94+ return response . toDataStreamResponse ( ) ;
8795 } catch ( error ) {
8896 console . error ( "Error in chat API:" , error ) ;
8997 return new Response ( ReasonPhrases . INTERNAL_SERVER_ERROR , {
0 commit comments