import { ConnectorIndexingStatus, DocumentBoostStatus, Tag, UserGroup, } from "@/lib/types"; import useSWR, { mutate, useSWRConfig } from "swr"; import { errorHandlingFetcher } from "./fetcher"; import { useEffect, useState } from "react"; import { DateRangePickerValue } from "@tremor/react"; import { SourceMetadata } from "./search/interfaces"; import { destructureValue } from "./llm/utils"; import { ChatSession } from "@/app/chat/interfaces"; import { UsersResponse } from "./users/interfaces"; import { usePaidEnterpriseFeaturesEnabled } from "@/components/settings/usePaidEnterpriseFeaturesEnabled"; import { Credential } from "./connectors/credentials"; const CREDENTIAL_URL = "/api/manage/admin/credential"; export const usePublicCredentials = () => { const { mutate } = useSWRConfig(); const swrResponse = useSWR[]>( CREDENTIAL_URL, errorHandlingFetcher ); return { ...swrResponse, refreshCredentials: () => mutate(CREDENTIAL_URL), }; }; const buildReactedDocsUrl = (ascending: boolean, limit: number) => { return `/api/manage/admin/doc-boosts?ascending=${ascending}&limit=${limit}`; }; export const useMostReactedToDocuments = ( ascending: boolean, limit: number ) => { const url = buildReactedDocsUrl(ascending, limit); const swrResponse = useSWR(url, errorHandlingFetcher); return { ...swrResponse, refreshDocs: () => mutate(url), }; }; export const useObjectState = ( initialValue: T ): [T, (update: Partial) => void] => { const [state, setState] = useState(initialValue); const set = (update: Partial) => { setState((prevState) => { return { ...prevState, ...update, }; }); }; return [state, set]; }; const INDEXING_STATUS_URL = "/api/manage/admin/connector/indexing-status"; export const useConnectorCredentialIndexingStatus = ( refreshInterval = 30000 // 30 seconds ) => { const { mutate } = useSWRConfig(); const swrResponse = useSWR[]>( INDEXING_STATUS_URL, errorHandlingFetcher, { refreshInterval: refreshInterval } ); return { ...swrResponse, refreshIndexingStatus: () => mutate(INDEXING_STATUS_URL), }; }; export const useTimeRange = (initialValue?: DateRangePickerValue) => { return useState(null); }; export interface FilterManager { timeRange: DateRangePickerValue | null; setTimeRange: React.Dispatch< React.SetStateAction >; selectedSources: SourceMetadata[]; setSelectedSources: React.Dispatch>; selectedDocumentSets: string[]; setSelectedDocumentSets: React.Dispatch>; selectedTags: Tag[]; setSelectedTags: React.Dispatch>; } export function useFilters(): FilterManager { const [timeRange, setTimeRange] = useTimeRange(); const [selectedSources, setSelectedSources] = useState([]); const [selectedDocumentSets, setSelectedDocumentSets] = useState( [] ); const [selectedTags, setSelectedTags] = useState([]); return { timeRange, setTimeRange, selectedSources, setSelectedSources, selectedDocumentSets, setSelectedDocumentSets, selectedTags, setSelectedTags, }; } export const useUsers = () => { const url = "/api/manage/users"; const swrResponse = useSWR(url, errorHandlingFetcher); return { ...swrResponse, refreshIndexingStatus: () => mutate(url), }; }; export interface LlmOverride { name: string; provider: string; modelName: string; } export interface LlmOverrideManager { llmOverride: LlmOverride; setLlmOverride: React.Dispatch>; temperature: number | null; setTemperature: React.Dispatch>; updateModelOverrideForChatSession: (chatSession?: ChatSession) => void; } export function useLlmOverride( currentChatSession?: ChatSession, defaultTemperature?: number ): LlmOverrideManager { const [llmOverride, setLlmOverride] = useState( currentChatSession && currentChatSession.current_alternate_model ? destructureValue(currentChatSession.current_alternate_model) : { name: "", provider: "", modelName: "", } ); const updateModelOverrideForChatSession = (chatSession?: ChatSession) => { setLlmOverride( chatSession && chatSession.current_alternate_model ? destructureValue(chatSession.current_alternate_model) : { name: "", provider: "", modelName: "", } ); }; const [temperature, setTemperature] = useState( defaultTemperature != undefined ? defaultTemperature : 0 ); useEffect(() => { setTemperature(defaultTemperature !== undefined ? defaultTemperature : 0); }, [defaultTemperature]); return { updateModelOverrideForChatSession, llmOverride, setLlmOverride, temperature, setTemperature, }; } /* EE Only APIs */ const USER_GROUP_URL = "/api/manage/admin/user-group"; export const useUserGroups = (): { data: UserGroup[] | undefined; isLoading: boolean; error: string; refreshUserGroups: () => void; } => { const swrResponse = useSWR(USER_GROUP_URL, errorHandlingFetcher); const isPaidEnterpriseFeaturesEnabled = usePaidEnterpriseFeaturesEnabled(); if (!isPaidEnterpriseFeaturesEnabled) { return { ...{ data: [], isLoading: false, error: "", }, refreshUserGroups: () => {}, }; } return { ...swrResponse, refreshUserGroups: () => mutate(USER_GROUP_URL), }; }; const MODEL_DISPLAY_NAMES: { [key: string]: string } = { // OpenAI models "gpt-4": "GPT 4", "gpt-4o": "GPT 4o", "gpt-4o-mini": "GPT 4o Mini", "gpt-4-0314": "GPT 4 (March 2023)", "gpt-4-0613": "GPT 4 (June 2023)", "gpt-4-32k-0314": "GPT 4 32k (March 2023)", "gpt-4-turbo": "GPT 4 Turbo", "gpt-4-turbo-preview": "GPT 4 Turbo (Preview)", "gpt-4-1106-preview": "GPT 4 Turbo (November 2023)", "gpt-4-vision-preview": "GPT 4 Vision (Preview)", "gpt-3.5-turbo": "GPT 3.5 Turbo", "gpt-3.5-turbo-0125": "GPT 3.5 Turbo (January 2024)", "gpt-3.5-turbo-1106": "GPT 3.5 Turbo (November 2023)", "gpt-3.5-turbo-16k": "GPT 3.5 Turbo 16k", "gpt-3.5-turbo-0613": "GPT 3.5 Turbo (June 2023)", "gpt-3.5-turbo-16k-0613": "GPT 3.5 Turbo 16k (June 2023)", "gpt-3.5-turbo-0301": "GPT 3.5 Turbo (March 2023)", // Anthropic models "claude-3-opus-20240229": "Claude 3 Opus", "claude-3-sonnet-20240229": "Claude 3 Sonnet", "claude-3-haiku-20240307": "Claude 3 Haiku", "claude-2.1": "Claude 2.1", "claude-2.0": "Claude 2.0", "claude-instant-1.2": "Claude Instant 1.2", "claude-3-5-sonnet-20240620": "Claude 3.5 Sonnet", // Bedrock models "meta.llama3-1-70b-instruct-v1:0": "Llama 3.1 70B", "meta.llama3-1-8b-instruct-v1:0": "Llama 3.1 8B", "meta.llama3-70b-instruct-v1:0": "Llama 3 70B", "meta.llama3-8b-instruct-v1:0": "Llama 3 8B", "meta.llama2-70b-chat-v1": "Llama 2 70B", "meta.llama2-13b-chat-v1": "Llama 2 13B", "cohere.command-r-v1:0": "Command R", "cohere.command-r-plus-v1:0": "Command R Plus", "cohere.command-light-text-v14": "Command Light Text", "cohere.command-text-v14": "Command Text", "anthropic.claude-instant-v1": "Claude Instant", "anthropic.claude-v2:1": "Claude v2.1", "anthropic.claude-v2": "Claude v2", "anthropic.claude-v1": "Claude v1", "anthropic.claude-3-opus-20240229-v1:0": "Claude 3 Opus", "anthropic.claude-3-haiku-20240307-v1:0": "Claude 3 Haiku", "anthropic.claude-3-5-sonnet-20240620-v1:0": "Claude 3.5 Sonnet", "anthropic.claude-3-sonnet-20240229-v1:0": "Claude 3 Sonnet", "mistral.mistral-large-2402-v1:0": "Mistral Large", "mistral.mixtral-8x7b-instruct-v0:1": "Mixtral 8x7B Instruct", "mistral.mistral-7b-instruct-v0:2": "Mistral 7B Instruct", "amazon.titan-text-express-v1": "Titan Text Express", "amazon.titan-text-lite-v1": "Titan Text Lite", "ai21.jamba-instruct-v1:0": "Jamba Instruct", "ai21.j2-ultra-v1": "J2 Ultra", "ai21.j2-mid-v1": "J2 Mid", }; export function getDisplayNameForModel(modelName: string): string { return MODEL_DISPLAY_NAMES[modelName] || modelName; } export const defaultModelsByProvider: { [name: string]: string[] } = { openai: ["gpt-4", "gpt-4o", "gpt-4o-mini"], bedrock: [ "meta.llama3-1-70b-instruct-v1:0", "meta.llama3-1-8b-instruct-v1:0", "anthropic.claude-3-opus-20240229-v1:0", "mistral.mistral-large-2402-v1:0", "anthropic.claude-3-5-sonnet-20240620-v1:0", ], anthropic: ["claude-3-opus-20240229", "claude-3-5-sonnet-20240620"], };