import React, { useEffect, useState } from "react";
import { liteClient as algoliasearch } from "algoliasearch/lite";
import { Chat, InstantSearch } from "react-instantsearch";
const appID = "ALGOLIA_APPLICATION_ID";
const apiKey = "ALGOLIA_SEARCH_ONLY_API_KEY";
const agentId = "YOUR_CHAT_AGENT_ID";
const navPromptId = "YOUR_STARTER_PROMPTS_AGENT_ID";
const searchClient = algoliasearch(appID, apiKey);
async function getInitPrompts() {
const response = await fetch(
`https://${appID}.algolia.net/agent-studio/1/agents/${navPromptId}/completions?stream=false&cache=true&compatibilityMode=ai-sdk-5`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
"X-Algolia-Application-Id": appID,
"X-Algolia-API-Key": apiKey,
},
body: JSON.stringify({
messages: [
{
role: "user",
parts: [{ text: "Return starter prompts for the welcome screen." }],
},
],
}),
}
);
const data = await response.json();
const text = data.parts?.find((part) => part.type === "text")?.text;
if (!text) {
return [];
}
const groups = [];
let currentGroup = null;
for (const line of text.split("\n")) {
const trimmedLine = line.trim();
if (!trimmedLine) {
continue;
}
if (trimmedLine.startsWith("# ")) {
currentGroup = {
title: trimmedLine.replace(/^#\s*/, ""),
prompts: [],
};
groups.push(currentGroup);
continue;
}
if (currentGroup) {
currentGroup.prompts.push(trimmedLine);
}
}
return groups;
}
const initPromptsPromise = getInitPrompts();
function ChatLayout({
open,
messages,
maximized,
headerComponent,
messagesComponent,
promptComponent,
toggleButtonComponent,
sendMessage,
}) {
const [initPrompts, setInitPrompts] = useState([]);
useEffect(() => {
initPromptsPromise.then(setInitPrompts).catch(() => setInitPrompts([]));
}, []);
return (
<>
<div
style={{
position: "fixed",
bottom: 16,
right: 16,
}}
>
{toggleButtonComponent}
</div>
{open && (
<div
style={{
position: "fixed",
bottom: maximized ? 0 : 80,
right: maximized ? 0 : 16,
width: maximized ? "100%" : 400,
height: maximized ? "100%" : undefined,
maxHeight: maximized ? "100%" : 600,
display: "flex",
flexDirection: "column",
background: "white",
borderRadius: maximized ? 0 : 12,
boxShadow: "0 4px 24px rgba(0,0,0,0.12)",
overflow: "hidden",
}}
>
{headerComponent}
<div
style={{
flex: 1,
overflow: "hidden",
display: "flex",
flexDirection: "column",
}}
>
{messages.length === 0 ? (
<div className="ais-ChatMessages">
<div className="ais-ChatMessages-scroll ais-Scrollbar">
<div
style={{
marginBottom: "16px",
}}
>
<h2>How can we help?</h2>
<p>
Start with a prompt from the second agent, or type your own
question.
</p>
{initPrompts.map((group, groupIndex) => (
<section key={group.title || groupIndex}>
<div>
{group.title}
</div>
<div className="ais-ChatPromptSuggestions">
{group.prompts.map((prompt, promptIndex) => (
<button
key={promptIndex}
type="button"
className="ais-Button ais-Button--primary ais-Button--sm ais-ChatPromptSuggestions-suggestion"
onClick={() => sendMessage({ text: prompt })}
>
{prompt}
</button>
))}
</div>
</section>
))}
</div>
</div>
</div>
) : (
messagesComponent
)}
</div>
{promptComponent}
</div>
)}
</>
);
}
function App() {
return (
<InstantSearch searchClient={searchClient}>
<Chat agentId={agentId} layoutComponent={ChatLayout} />
</InstantSearch>
);
}