1
0
Fork 0

chore: Allow using staging env on DocSearch website (#2829)

This commit is contained in:
Paul Jankowski 2026-01-08 11:27:42 -05:00 committed by GitHub
parent 2800eaf46f
commit 3ffd9f6f29
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 56 additions and 19 deletions

View file

@ -10,17 +10,22 @@ export default function BasicHybrid(): JSX.Element {
<DocSearchButton />
<DocSearchModal
indexName="docsearch"
appId="PMZUYBQDAK"
apiKey="24b09689d5b4223813d9b8e48563c8f6"
askAi="askAIDemo"
appId="beta3G7FSQDJR3"
apiKey="0faad3eae2ba413c16355a0f8670c201"
askAi={{
assistantId: 'e3Kl4lTCBlSA',
useStagingEnv: true,
indexName: 'docsearch-markdown',
}}
/>
<SidepanelButton />
<Sidepanel
indexName="docsearch"
appId="PMZUYBQDAK"
apiKey="24b09689d5b4223813d9b8e48563c8f6"
assistantId="askAIDemo"
useStagingEnv={true}
indexName="docsearch-markdown"
appId="beta3G7FSQDJR3"
apiKey="0faad3eae2ba413c16355a0f8670c201"
assistantId="e3Kl4lTCBlSA"
/>
</DocSearch>
);

View file

@ -62,6 +62,8 @@ export type DocSearchAskAi = {
* @default false
*/
suggestedQuestions?: boolean;
// HACK: This is a hack for testing staging, remove before releasing
useStagingEnv?: boolean;
};
export interface DocSearchIndex {

View file

@ -350,6 +350,7 @@ export function DocSearchModal({
const askAiConfig = typeof askAi === 'object' ? askAi : null;
const askAiConfigurationId = typeof askAi === 'string' ? askAi : askAiConfig?.assistantId || null;
const askAiSearchParameters = askAiConfig?.searchParameters;
const askAiUseStagingEnv = askAiConfig?.useStagingEnv || false;
const [askAiState, setAskAiState] = React.useState<AskAiState>('initial');
const suggestedQuestions = useSuggestedQuestions({
assistantId: askAiConfigurationId,
@ -407,6 +408,7 @@ export function DocSearchModal({
appId: askAiConfig?.appId || appId,
indexName: askAiConfig?.indexName || defaultIndexName,
searchParameters: askAiSearchParameters,
useStagingEnv: askAiUseStagingEnv,
});
const prevStatus = React.useRef(status);

View file

@ -103,6 +103,8 @@ export type SidepanelProps = {
* @default `{ 'Ctrl/Cmd+I': true }`
*/
keyboardShortcuts?: SidepanelShortcuts;
// HACK: This is a hack for testing staging, remove before releasing
useStagingEnv?: boolean;
};
type Props = Omit<DocSearchSidepanelProps, 'button' | 'panel'> &
@ -131,6 +133,7 @@ export const Sidepanel = ({
keyboardShortcuts,
side = 'right',
initialMessage,
useStagingEnv = false,
}: Props): JSX.Element => {
const [isExpanded, setIsExpanded] = React.useState(false);
const [sidepanelState, setSidepanelState] = React.useState<SidepanelState>('new-conversation');
@ -169,6 +172,7 @@ export const Sidepanel = ({
assistantId,
apiKey,
searchParameters,
useStagingEnv,
});
const suggestedQuestions = useSuggestedQuestions({

View file

@ -1,4 +1,4 @@
import { ASK_AI_API_URL, USE_ASK_AI_TOKEN } from './constants';
import { ASK_AI_API_URL, BETA_ASK_AI_API_URL, USE_ASK_AI_TOKEN } from './constants';
// ... existing imports ...
const TOKEN_KEY = 'askai_token';
@ -27,16 +27,20 @@ let inflight: Promise<string> | null = null;
export const getValidToken = async ({
assistantId,
abortSignal,
useStagingEnv = false,
}: {
assistantId: string;
abortSignal: AbortSignal;
useStagingEnv?: boolean;
// eslint-disable-next-line require-await
}): Promise<string> => {
const cached = sessionStorage.getItem(TOKEN_KEY);
if (!isExpired(cached)) return cached!;
const baseUrl = useStagingEnv ? BETA_ASK_AI_API_URL : ASK_AI_API_URL;
if (!inflight) {
inflight = fetch(`${ASK_AI_API_URL}/token`, {
inflight = fetch(`${baseUrl}/token`, {
method: 'POST',
headers: {
'x-algolia-assistant-id': assistantId,
@ -66,23 +70,31 @@ export const postFeedback = async ({
messageId,
appId,
abortSignal,
useStagingEnv = false,
}: {
assistantId: string;
thumbs: 0 | 1;
messageId: string;
appId: string;
abortSignal: AbortSignal;
useStagingEnv?: boolean;
}): Promise<Response> => {
const headers = new Headers();
headers.set('x-algolia-assistant-id', assistantId);
headers.set('content-type', 'application/json');
if (USE_ASK_AI_TOKEN) {
const token = await getValidToken({ assistantId, abortSignal });
const token = await getValidToken({
assistantId,
abortSignal,
useStagingEnv,
});
headers.set('authorization', `TOKEN ${token}`);
}
return fetch(`${ASK_AI_API_URL}/feedback`, {
const baseUrl = useStagingEnv ? BETA_ASK_AI_API_URL : ASK_AI_API_URL;
return fetch(`${baseUrl}/feedback`, {
method: 'POST',
body: JSON.stringify({
appId,

View file

@ -1,4 +1,5 @@
export const MAX_QUERY_SIZE = 512;
export const ASK_AI_API_URL = 'https://askai.algolia.com/chat';
export const BETA_ASK_AI_API_URL = 'https://beta-chat-askai.algolia.com';
export const USE_ASK_AI_TOKEN = true;
export const SUGGESTED_QUETIONS_INDEX_NAME = 'algolia_ask_ai_suggested_questions';

View file

@ -5,7 +5,7 @@ import { useCallback, useMemo, useRef } from 'react';
import { getValidToken, postFeedback } from './askai';
import type { Exchange } from './AskAiScreen';
import { ASK_AI_API_URL, USE_ASK_AI_TOKEN } from './constants';
import { ASK_AI_API_URL, BETA_ASK_AI_API_URL, USE_ASK_AI_TOKEN } from './constants';
import type { StoredSearchPlugin } from './stored-searches';
import { createStoredConversations } from './stored-searches';
import type { AIMessage } from './types/AskiAi';
@ -20,6 +20,7 @@ type UseAskAiParams = {
appId: string;
indexName: string;
searchParameters?: AskAiSearchParameters;
useStagingEnv?: boolean;
};
type UseAskAiReturn = {
@ -37,13 +38,20 @@ type UseAskAiReturn = {
type UseAskAi = (params: UseAskAiParams) => UseAskAiReturn;
export const useAskAi: UseAskAi = ({ assistantId, apiKey, appId, indexName, searchParameters }) => {
export const useAskAi: UseAskAi = ({
assistantId,
apiKey,
appId,
indexName,
searchParameters,
useStagingEnv = false,
}) => {
const abortControllerRef = useRef(new AbortController());
const askAiTransport = useMemo(
() =>
new DefaultChatTransport({
api: ASK_AI_API_URL,
api: useStagingEnv ? BETA_ASK_AI_API_URL : ASK_AI_API_URL,
headers: async (): Promise<Record<string, string>> => {
if (!assistantId) {
throw new Error('Ask AI assistant ID is required');
@ -55,6 +63,7 @@ export const useAskAi: UseAskAi = ({ assistantId, apiKey, appId, indexName, sear
token = await getValidToken({
assistantId,
abortSignal: abortControllerRef.current.signal,
useStagingEnv,
});
}
@ -69,7 +78,7 @@ export const useAskAi: UseAskAi = ({ assistantId, apiKey, appId, indexName, sear
},
body: searchParameters ? { searchParameters } : {},
}),
[apiKey, appId, assistantId, indexName, searchParameters],
[apiKey, appId, assistantId, indexName, searchParameters, useStagingEnv],
);
const { messages, sendMessage, status, setMessages, error, stop } = useChat<AIMessage>({
@ -94,12 +103,13 @@ export const useAskAi: UseAskAi = ({ assistantId, apiKey, appId, indexName, sear
messageId,
appId,
abortSignal: abortControllerRef.current.signal,
useStagingEnv,
});
if (res.status >= 300) throw new Error('Failed, try again later.');
conversations.addFeedback?.(messageId, thumbs === 1 ? 'like' : 'dislike');
},
[assistantId, appId, conversations],
[assistantId, appId, conversations, useStagingEnv],
);
const onStopStreaming = async (): Promise<void> => {

View file

@ -8,9 +8,9 @@ import { createPortal } from 'react-dom';
import '@docsearch/css/dist/sidepanel.css';
const APP_ID = 'PMZUYBQDAK';
const API_KEY = '24b09689d5b4223813d9b8e48563c8f6';
const ASSISTANT_ID = 'askAIDemo';
const APP_ID = 'beta3G7FSQDJR3';
const API_KEY = '0faad3eae2ba413c16355a0f8670c201';
const ASSISTANT_ID = 'e3Kl4lTCBlSA';
const ASK_AI_INDEX_NAME = 'docsearch-markdown';
function useSearchResultUrlProcessor() {
@ -87,6 +87,7 @@ export default function Root({ children }) {
<SidepanelButton />
<Sidepanel
useStagingEnv={true}
appId={APP_ID}
apiKey={API_KEY}
indexName={ASK_AI_INDEX_NAME}