Skip to content

Commit 3420e01

Browse files
authored
Merge pull request #355 from wpengine/aug-updates
Aug updates
2 parents aea1996 + 9994629 commit 3420e01

File tree

9 files changed

+554
-520
lines changed

9 files changed

+554
-520
lines changed

package.json

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -20,26 +20,27 @@
2020
"prepare": "husky"
2121
},
2222
"dependencies": {
23-
"@ai-sdk/google-vertex": "^2.2.27",
24-
"@apollo/client": "^3.13.8",
23+
"@ai-sdk/google-vertex": "^3.0.5",
24+
"@ai-sdk/react": "^2.0.9",
25+
"@apollo/client": "^3.13.9",
2526
"@faustwp/blocks": "^6.1.3",
26-
"@faustwp/cli": "^3.2.4",
27+
"@faustwp/cli": "^3.2.5",
2728
"@faustwp/core": "^3.2.4",
28-
"@headlessui/react": "^2.2.6",
29+
"@headlessui/react": "^2.2.7",
2930
"@jsdevtools/rehype-url-inspector": "^2.0.2",
30-
"@next/third-parties": "^15.4.4",
31+
"@next/third-parties": "^15.4.6",
3132
"@octokit/core": "^7.0.3",
32-
"@shikijs/transformers": "^3.8.1",
33+
"@shikijs/transformers": "^3.9.2",
3334
"@sindresorhus/slugify": "^2.2.1",
3435
"@wpengine/atlas-next": "^3.0.0",
35-
"ai": "^4.3.19",
36+
"ai": "^5.0.9",
3637
"date-fns": "^4.1.0",
3738
"date-fns-tz": "^3.2.0",
3839
"feed": "^5.1.0",
3940
"graphql": "^16.11.0",
4041
"http-status-codes": "^2.3.0",
4142
"lodash.debounce": "^4.0.8",
42-
"next": "^15.4.4",
43+
"next": "^15.4.6",
4344
"next-mdx-remote-client": "^2.1.3",
4445
"next-sitemap": "^4.2.3",
4546
"react": "^19.1.1",
@@ -57,22 +58,22 @@
5758
"remark-parse": "^11.0.0",
5859
"remark-smartypants": "^3.0.2",
5960
"remark-stringify": "^11.0.0",
60-
"shiki": "^3.8.1",
61+
"shiki": "^3.9.2",
6162
"strip-markdown": "^6.0.0",
6263
"unified": "^11.0.5",
6364
"vfile-matter": "^5.0.1",
64-
"zod": "^4.0.13"
65+
"zod": "^4.0.17"
6566
},
6667
"devDependencies": {
6768
"@tailwindcss/postcss": "^4.1.11",
6869
"@tailwindcss/typography": "^0.5.16",
6970
"concurrently": "^9.2.0",
70-
"eslint": "^9.32.0",
71+
"eslint": "^9.33.0",
7172
"eslint-config-neon": "^0.2.7",
7273
"eslint-plugin-mdx": "^3.6.2",
7374
"eslint-plugin-unicorn": "^59.0.1",
7475
"husky": "^9.1.7",
75-
"lint-staged": "^16.1.2",
76+
"lint-staged": "^16.1.5",
7677
"next-secure-headers": "^2.2.0",
7778
"postcss": "^8.5.6",
7879
"postcss-nesting": "^13.0.2",
@@ -84,7 +85,7 @@
8485
"node": "^22",
8586
"npm": "use-pnpm"
8687
},
87-
"packageManager": "[email protected]-0+sha512.2cd47a0cbf5f1d1de7693a88307a0ede5be94e0d3b34853d800ee775efbea0650cb562b77605ec80bc8d925f5cd27c4dfe8bb04d3a0b76090784c664450d32d6",
88+
"packageManager": "[email protected]+sha512.ad27a79641b49c3e481a16a805baa71817a04bbe06a38d17e60e2eaee83f6a146c6a688125f5792e48dd5ba30e7da52a5cda4c3992b9ccf333f9ce223af84748",
8889
"lint-staged": {
8990
"*": "pnpm format",
9091
"*.{js,jsx}": "pnpm lint"

pnpm-lock.yaml

Lines changed: 472 additions & 448 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

scripts/smart-search.mjs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ async function main() {
2222
try {
2323
const pages = await collectPages();
2424

25-
console.log("Docs Pages collected for indexing:", pages.length);
25+
console.info("Docs Pages collected for indexing:", pages.length);
2626

2727
await deleteOldDocs();
2828

@@ -146,7 +146,7 @@ async function deleteOldDocs() {
146146
const existingIndexedDocuments = new Set(existingDocs.map((doc) => doc.id));
147147

148148
if (existingIndexedDocuments?.size === 0) {
149-
console.log("No documents to delete.");
149+
console.info("No documents to delete.");
150150
return;
151151
}
152152

@@ -173,7 +173,7 @@ async function deleteOldDocs() {
173173
}
174174
}
175175

176-
console.log(`Deleted ${results.length} documents successfully.`);
176+
console.info(`Deleted ${results.length} documents successfully.`);
177177
} catch (error) {
178178
console.error("Error during deletion process:", error);
179179
}
@@ -206,7 +206,7 @@ async function sendPagesToEndpoint(pages) {
206206
try {
207207
await graphql({ query: bulkIndexMutation, variables });
208208

209-
console.log(`Indexed ${documents.length} documents successfully.`);
209+
console.info(`Indexed ${documents.length} documents successfully.`);
210210
} catch (error) {
211211
console.error("Error during bulk indexing:", error);
212212
}
@@ -233,7 +233,7 @@ async function setSearchConfig() {
233233

234234
try {
235235
const response = await graphql({ query: searchConfigMutation, variables });
236-
console.log(
236+
console.info(
237237
"Search configuration updated successfully.",
238238
JSON.stringify(response.data.config.semanticSearch, undefined, 2),
239239
);

src/app/api/chat/route.js

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { env } from "node:process";
22
import { createVertex } from "@ai-sdk/google-vertex";
3-
import { streamText, convertToCoreMessages } from "ai";
3+
import { streamText, convertToModelMessages } from "ai";
44
import { StatusCodes, ReasonPhrases } from "http-status-codes";
55
import { smartSearchTool } from "@/lib/rag.mjs";
66

@@ -68,12 +68,10 @@ export async function POST(req) {
6868
});
6969
}
7070

71-
const coreMessages = convertToCoreMessages(messages);
72-
7371
const response = await streamText({
7472
model: vertex("gemini-2.5-flash"),
7573
system: [systemPromptContent, smartSearchPrompt].join("\n"),
76-
messages: coreMessages,
74+
messages: convertToModelMessages(messages),
7775
tools: {
7876
smartSearchTool,
7977
},
@@ -84,19 +82,19 @@ export async function POST(req) {
8482
});
8583
},
8684
onToolCall: async (toolCall) => {
87-
console.log("Tool call initiated:", toolCall);
85+
console.info("Tool call initiated:", toolCall);
8886
},
8987
onStepFinish: async (result) => {
9088
if (result.usage) {
91-
console.log(
92-
`[Token Usage] Prompt tokens: ${result.usage.promptTokens}, Completion tokens: ${result.usage.completionTokens}, Total tokens: ${result.usage.totalTokens}`,
89+
console.info(
90+
`[Token Usage] Prompt tokens: ${result.usage.inputTokens}, Completion tokens: ${result.usage.outputTokens}, Total tokens: ${result.usage.totalTokens}`,
9391
);
9492
}
9593
},
9694
maxSteps: 5,
9795
});
9896

99-
return response.toDataStreamResponse();
97+
return response.toUIMessageStreamResponse();
10098
} catch (error) {
10199
console.error("Error in chat API:", error);
102100
return new Response(ReasonPhrases.INTERNAL_SERVER_ERROR, {

src/components/chat/chat-dialog.jsx

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,33 @@
1-
import { useChat } from "ai/react";
2-
import { useEffect } from "react";
1+
import { useChat } from "@ai-sdk/react";
2+
import { lastAssistantMessageIsCompleteWithToolCalls } from "ai";
3+
import { useState } from "react";
34
import { HiXCircle } from "react-icons/hi2";
45
import { useChatDialog } from "./state";
56
import Chat from "@/components/chat/chat";
67
import "./chat.css";
78

89
export default function ChatDialog() {
910
const { dialog } = useChatDialog();
10-
const {
11-
messages,
12-
input,
13-
handleInputChange,
14-
handleSubmit,
15-
setMessages,
16-
status,
17-
} = useChat();
11+
const { messages, sendMessage, status } = useChat({
12+
onError: (error) => {
13+
console.error("Error sending message:", error);
14+
},
15+
sendAutomaticallyWhen: lastAssistantMessageIsCompleteWithToolCalls,
16+
messages: [
17+
{
18+
role: "assistant",
19+
parts: [
20+
{
21+
type: "text",
22+
text: "Hey there! I'm an AI driven chat assistant here to help you with Faust.js! I'm trained on the documentation and can help you with coding tasks, learning, and more. What can I assist you with today?",
23+
},
24+
],
25+
id: "welcome-intro",
26+
},
27+
],
28+
});
1829

19-
useEffect(() => {
20-
if (messages.length === 0) {
21-
setMessages([
22-
{
23-
role: "assistant",
24-
content:
25-
"Hey there! I'm an AI driven chat assistant here to help you with Faust.js! I'm trained on the documentation and can help you with coding tasks, learning, and more. What can I assist you with today?",
26-
id: "welcome-intro",
27-
},
28-
]);
29-
}
30-
}, [messages, setMessages]);
30+
const [input, setInput] = useState("");
3131

3232
return (
3333
<dialog
@@ -54,8 +54,8 @@ export default function ChatDialog() {
5454
<section>
5555
<Chat
5656
input={input}
57-
handleInputChange={handleInputChange}
58-
handleMessageSubmit={handleSubmit}
57+
setInput={setInput}
58+
sendMessage={sendMessage}
5959
messages={messages}
6060
status={status}
6161
/>

src/components/chat/chat-input.jsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { HiOutlinePaperAirplane, HiOutlineArrowPath } from "react-icons/hi2";
22

3-
export default function Input({ input, handleInputChange, status }) {
3+
export default function Input({ input, setInput, status }) {
44
const isReady = status === "ready";
55
const isSubmitted = status === "submitted";
66

@@ -11,7 +11,9 @@ export default function Input({ input, handleInputChange, status }) {
1111
type="text"
1212
wrap="soft"
1313
value={input}
14-
onChange={handleInputChange}
14+
onChange={(event) => {
15+
setInput(event.target.value);
16+
}}
1517
autoFocus
1618
placeholder="Ask about Faust..."
1719
className="no-scrollbar text-md w-full max-w-full rounded-xl bg-gray-700 p-2 text-wrap text-gray-200 placeholder-gray-400 shadow-lg transition-colors focus:ring-2 focus:ring-teal-500 focus:outline-none"

src/components/chat/chat.jsx

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ import { sendChatMessageEvent } from "@/lib/analytics.mjs";
44

55
export default function Chat({
66
input,
7-
handleInputChange,
8-
handleMessageSubmit,
7+
setInput,
8+
sendMessage,
99
status,
1010
messages,
1111
}) {
@@ -15,19 +15,19 @@ export default function Chat({
1515
<form
1616
id="chat-form"
1717
onSubmit={(event) => {
18+
event.preventDefault();
19+
1820
sendChatMessageEvent({
1921
message: input,
2022
});
2123

22-
return handleMessageSubmit(event);
24+
sendMessage({ text: input });
25+
26+
setInput("");
2327
}}
2428
className="absolute bottom-0 left-0 w-[calc(100%-theme(spacing.[1.5]))] bg-gradient-to-b from-transparent via-gray-800 to-gray-800 p-4 md:p-6"
2529
>
26-
<ChatInput
27-
input={input}
28-
handleInputChange={handleInputChange}
29-
status={status}
30-
/>
30+
<ChatInput input={input} setInput={setInput} status={status} />
3131
</form>
3232
</div>
3333
);

src/components/chat/messages.jsx

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,14 @@ export default function Messages({ messages, className }) {
2020
role="log"
2121
>
2222
{messages.map((message) => {
23-
const isAssistant = message.role === "assistant";
24-
const isLoading = message.content === "";
23+
const isAssistant = message.role !== "user";
24+
const isLoading =
25+
message.parts?.length <= 2 &&
26+
message.parts[0].type === "step-start" &&
27+
!(
28+
message.parts?.length && Object.hasOwn(message.parts.at(-1), "text")
29+
);
30+
2531
return (
2632
<div
2733
key={message.id}
@@ -39,14 +45,17 @@ export default function Messages({ messages, className }) {
3945
<div className="animate-think h-2 w-2 rounded-full bg-gray-200" />
4046
</div>
4147
) : (
42-
<Markdown
43-
remarkPlugins={[remarkGfm]}
44-
components={{
45-
a: ChatLink,
46-
}}
47-
>
48-
{message.content}
49-
</Markdown>
48+
message.parts?.map((part, index) => (
49+
<Markdown
50+
key={index}
51+
remarkPlugins={[remarkGfm]}
52+
components={{
53+
a: ChatLink,
54+
}}
55+
>
56+
{part.text}
57+
</Markdown>
58+
))
5059
)}
5160
</div>
5261
);

src/lib/rag.mjs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,15 @@ import { normalizeSmartSearchResponse } from "@/lib/smart-search.mjs";
66
export const smartSearchTool = tool({
77
description:
88
"Search for information about Faust using WP Engine Smart Search. Use this to answer questions about Faust, its features, capabilities, and more when the information is not already known.",
9-
parameters: z.object({
9+
inputSchema: z.object({
1010
query: z
1111
.string()
1212
.describe(
1313
"The search query to find relevant Faust information based on the user's question.",
1414
),
1515
}),
1616
execute: async ({ query }) => {
17-
console.log(`[Tool Execution] Searching with query: "${query}"`);
17+
console.info(`[Tool Execution] Searching with query: "${query}"`);
1818
try {
1919
const context = await getContext(query);
2020

0 commit comments

Comments
 (0)