diff --git a/agenta-web/src/components/pages/app-management/index.tsx b/agenta-web/src/components/pages/app-management/index.tsx index f5822b29d6..6a69ef89a7 100644 --- a/agenta-web/src/components/pages/app-management/index.tsx +++ b/agenta-web/src/components/pages/app-management/index.tsx @@ -8,7 +8,7 @@ import {createUseStyles} from "react-jss" import {useAppsData} from "@/contexts/app.context" import {useProfileData} from "@/contexts/profile.context" import {usePostHogAg} from "@/lib/helpers/analytics/hooks/usePostHogAg" -import {type LlmProvider} from "@/lib/helpers/llmProviders" +import {LlmProvider, getAllProviderLlmKeys} from "@/lib/helpers/llmProviders" import {dynamicComponent, dynamicContext} from "@/lib/helpers/dynamic" import dayjs from "dayjs" import {useAppTheme} from "@/components/Layout/ThemeContextProvider" @@ -17,7 +17,6 @@ import GetStartedSection from "./components/GetStartedSection" import ApplicationManagementSection from "./components/ApplicationManagementSection" import ResultComponent from "@/components/ResultComponent/ResultComponent" import {useProjectData} from "@/contexts/project.context" -import {useVaultSecret} from "@/hooks/useVaultSecret" const CreateAppStatusModal: any = dynamicComponent( "pages/app-management/modals/CreateAppStatusModal", @@ -84,7 +83,6 @@ const AppManagement: React.FC = () => { details: undefined, appId: undefined, }) - const {secrets} = useVaultSecret() const {project} = useProjectData() const [useOrgData, setUseOrgData] = useState(() => () => "") @@ -120,7 +118,7 @@ const AppManagement: React.FC = () => { setStatusModalOpen(true) // attempt to create and start the template, notify user of the progress - const apiKeys = secrets + const apiKeys = getAllProviderLlmKeys() await createAndStartTemplate({ appName: newApp, templateId: template_id, diff --git a/agenta-web/src/components/pages/evaluations/NewEvaluation/NewEvaluationModal.tsx b/agenta-web/src/components/pages/evaluations/NewEvaluation/NewEvaluationModal.tsx index d49a066293..68cb035392 100644 --- a/agenta-web/src/components/pages/evaluations/NewEvaluation/NewEvaluationModal.tsx +++ b/agenta-web/src/components/pages/evaluations/NewEvaluation/NewEvaluationModal.tsx @@ -14,7 +14,6 @@ import SelectTestsetSection from "./SelectTestsetSection" import SelectVariantSection from "./SelectVariantSection" import SelectEvaluatorSection from "./SelectEvaluatorSection" import {dynamicComponent} from "@/lib/helpers/dynamic" -import {useVaultSecret} from "@/hooks/useVaultSecret" const AdvancedSettingsPopover: any = dynamicComponent( "pages/evaluations/NewEvaluation/AdvancedSettingsPopover", @@ -74,7 +73,7 @@ const NewEvaluationModal: React.FC = ({onSuccess, ...props}) => { const [selectedTestsetId, setSelectedTestsetId] = useState("") const [selectedVariantIds, setSelectedVariantIds] = useState([]) const [selectedEvalConfigs, setSelectedEvalConfigs] = useState([]) - const {secrets} = useVaultSecret() + const [activePanel, setActivePanel] = useState("testsetPanel") const handlePanelChange = (key: string | string[]) => { setActivePanel((prevKey) => (prevKey === key ? null : (key as string))) @@ -164,7 +163,7 @@ const NewEvaluationModal: React.FC = ({onSuccess, ...props}) => { variant_ids: selectedVariantIds, evaluators_configs: selectedEvalConfigs, rate_limit: rateLimitValues, - lm_providers_keys: apiKeyObject(secrets), + lm_providers_keys: apiKeyObject(), correct_answer_column: correctAnswerColumn, }) .then(onSuccess) diff --git a/agenta-web/src/components/pages/settings/Secrets/Secrets.tsx b/agenta-web/src/components/pages/settings/Secrets/Secrets.tsx index a091b00d4e..b28f7dbf68 100644 --- a/agenta-web/src/components/pages/settings/Secrets/Secrets.tsx +++ b/agenta-web/src/components/pages/settings/Secrets/Secrets.tsx @@ -1,25 +1,19 @@ -import {useVaultSecret} from "@/hooks/useVaultSecret" -import {type LlmProvider} from "@/lib/helpers/llmProviders" +import { + getLlmProviderKey, + saveLlmProviderKey, + removeSingleLlmProviderKey, + getAllProviderLlmKeys, + LlmProvider, +} from "@/lib/helpers/llmProviders" import {Button, Input, Space, Typography, message} from "antd" -import {useEffect, useState} from "react" +import {useState} from "react" const {Title, Text} = Typography export default function Secrets() { - const {secrets, handleModifyVaultSecret, handleDeleteVaultSecret} = useVaultSecret() - const [llmProviderKeys, setLlmProviderKeys] = useState([]) - const [loadingSecrets, setLoadingSecrets] = useState>({}) + const [llmProviderKeys, setLlmProviderKeys] = useState(getAllProviderLlmKeys()) const [messageAPI, contextHolder] = message.useMessage() - useEffect(() => { - setLlmProviderKeys(secrets) - }, [secrets]) - - const setSecretLoading = (id: string | undefined, isLoading: boolean) => { - if (!id) return - setLoadingSecrets((prev) => ({...prev, [id]: isLoading})) - } - return (
{contextHolder} @@ -36,69 +30,47 @@ export default function Secrets() { Available Providers
- {llmProviderKeys.map( - ({name, title, key, id: secretId}: LlmProvider, i: number) => ( - - { - const newLlmProviderKeys = [...llmProviderKeys] - newLlmProviderKeys[i].key = e.target.value - setLlmProviderKeys(newLlmProviderKeys) - }} - addonBefore={`${title}`} - visibilityToggle={false} - className={"w-[420px]"} - /> - - - - ), - )} + {llmProviderKeys.map(({title, key}: LlmProvider, i: number) => ( + + { + const newLlmProviderKeys = [...llmProviderKeys] + newLlmProviderKeys[i].key = e.target.value + setLlmProviderKeys(newLlmProviderKeys) + }} + addonBefore={`${title}`} + visibilityToggle={false} + className={"w-[420px]"} + /> + + + + ))}
diff --git a/agenta-web/src/hooks/useVaultSecret.ts b/agenta-web/src/hooks/useVaultSecret.ts deleted file mode 100644 index aee0445a80..0000000000 --- a/agenta-web/src/hooks/useVaultSecret.ts +++ /dev/null @@ -1,151 +0,0 @@ -import {useEffect, useRef, useState} from "react" -import { - getAllProviderLlmKeys, - llmAvailableProviders, - llmAvailableProvidersToken, - LlmProvider, - removeSingleLlmProviderKey, - saveLlmProviderKey, -} from "@/lib/helpers/llmProviders" -import {isDemo} from "@/lib/helpers/utils" -import {dynamicLib, dynamicService} from "@/lib/helpers/dynamic" - -export const useVaultSecret = () => { - const [secrets, setSecrets] = useState(llmAvailableProviders) - const shouldRunMigration = useRef(true) - - const getVaultSecrets = async () => { - try { - if (isDemo()) { - const {fetchVaultSecret} = await dynamicService("vault/api") - const data = await fetchVaultSecret() - - setSecrets((prevSecret) => { - return prevSecret.map((secret) => { - const match = data.find((item: LlmProvider) => item.name === secret.name) - if (match) { - return { - ...secret, - key: match.key, - id: match.id, - } - } else { - return secret - } - }) - }) - } else { - setSecrets(getAllProviderLlmKeys()) - } - } catch (error) { - console.error(error) - } - } - - useEffect(() => { - getVaultSecrets() - }, []) - - const migrateProviderKeys = async () => { - try { - const localStorageProviders = localStorage.getItem(llmAvailableProvidersToken) - - if (localStorageProviders) { - const providers = JSON.parse(localStorageProviders) - - for (const provider of providers) { - if (provider.key) { - await handleModifyVaultSecret(provider as LlmProvider) - } - } - - localStorage.setItem(`${llmAvailableProvidersToken}Backup`, localStorageProviders) - - localStorage.removeItem(llmAvailableProvidersToken) - } - } catch (error) { - console.error(error) - } - } - - useEffect(() => { - if (shouldRunMigration.current) { - shouldRunMigration.current = false - if (isDemo()) { - migrateProviderKeys() - } - } - }, []) - - const handleModifyVaultSecret = async (provider: LlmProvider) => { - try { - if (isDemo()) { - const {updateVaultSecret, createVaultSecret} = await dynamicService("vault/api") - const {SecretDTOProvider, SecretDTOKind} = await dynamicLib("types_ee") - - const envNameMap: Record = { - OPENAI_API_KEY: SecretDTOProvider.OPENAI, - COHERE_API_KEY: SecretDTOProvider.COHERE, - ANYSCALE_API_KEY: SecretDTOProvider.ANYSCALE, - DEEPINFRA_API_KEY: SecretDTOProvider.DEEPINFRA, - ALEPHALPHA_API_KEY: SecretDTOProvider.ALEPHALPHA, - GROQ_API_KEY: SecretDTOProvider.GROQ, - MISTRAL_API_KEY: SecretDTOProvider.MISTRALAI, - ANTHROPIC_API_KEY: SecretDTOProvider.ANTHROPIC, - PERPLEXITYAI_API_KEY: SecretDTOProvider.PERPLEXITYAI, - TOGETHERAI_API_KEY: SecretDTOProvider.TOGETHERAI, - OPENROUTER_API_KEY: SecretDTOProvider.OPENROUTER, - GEMINI_API_KEY: SecretDTOProvider.GEMINI, - } - - const payload = { - header: { - name: provider.title, - description: "", - }, - secret: { - kind: SecretDTOKind.PROVIDER_KEY, - data: { - provider: envNameMap[provider.name], - key: provider.key, - }, - }, - } - - const findSecret = secrets.find((s) => s.name === provider.name) - - if (findSecret && provider.id) { - await updateVaultSecret({secret_id: provider.id, payload}) - } else { - await createVaultSecret({payload}) - } - - await getVaultSecrets() - } else { - saveLlmProviderKey(provider.title, provider.key) - } - } catch (error) { - console.error(error) - } - } - - const handleDeleteVaultSecret = async (provider: LlmProvider) => { - try { - if (isDemo() && provider.id) { - const {deleteVaultSecret} = await dynamicService("vault/api") - await deleteVaultSecret({secret_id: provider.id}) - await getVaultSecrets() - } else { - removeSingleLlmProviderKey(provider.title) - } - } catch (error) { - console.error(error) - } - } - - return { - secrets, - handleModifyVaultSecret, - handleDeleteVaultSecret, - } -} diff --git a/agenta-web/src/lib/helpers/dynamic.ts b/agenta-web/src/lib/helpers/dynamic.ts index effbc89eaa..19f5a003ce 100644 --- a/agenta-web/src/lib/helpers/dynamic.ts +++ b/agenta-web/src/lib/helpers/dynamic.ts @@ -30,11 +30,3 @@ export async function dynamicService(path: string, fallback?: any) { return fallback } } - -export async function dynamicLib(path: string, fallback?: any) { - try { - return await import(`@/lib/${path}`) - } catch (error) { - return fallback - } -} diff --git a/agenta-web/src/lib/helpers/llmProviders.ts b/agenta-web/src/lib/helpers/llmProviders.ts index 4c750a336a..5d2b3105fa 100644 --- a/agenta-web/src/lib/helpers/llmProviders.ts +++ b/agenta-web/src/lib/helpers/llmProviders.ts @@ -1,12 +1,12 @@ import cloneDeep from "lodash/cloneDeep" +import {camelToSnake} from "./utils" -export const llmAvailableProvidersToken = "llmAvailableProvidersToken" +const llmAvailableProvidersToken = "llmAvailableProvidersToken" export type LlmProvider = { title: string key: string name: string - id?: string } export const llmAvailableProviders: LlmProvider[] = [ @@ -55,6 +55,9 @@ export const saveLlmProviderKey = (providerName: string, keyValue: string) => { localStorage.setItem(llmAvailableProvidersToken, JSON.stringify(keys)) } +export const getLlmProviderKey = (providerName: string) => + getAllProviderLlmKeys().find((item: LlmProvider) => item.title === providerName)?.key + export const getAllProviderLlmKeys = () => { const providers = cloneDeep(llmAvailableProviders) try { diff --git a/agenta-web/src/lib/helpers/utils.ts b/agenta-web/src/lib/helpers/utils.ts index 8615726bb8..06d1f52738 100644 --- a/agenta-web/src/lib/helpers/utils.ts +++ b/agenta-web/src/lib/helpers/utils.ts @@ -7,7 +7,7 @@ import dayjs from "dayjs" import utc from "dayjs/plugin/utc" import {notification} from "antd" import Router from "next/router" -import {getApikeys, LlmProvider} from "./llmProviders" +import {getAllProviderLlmKeys, getApikeys} from "./llmProviders" if (typeof window !== "undefined") { //@ts-ignore @@ -49,7 +49,9 @@ export const EvaluationTypeLabels: Record = { [EvaluationType.rag_context_relevancy]: "RAG Context Relevancy", } -export const apiKeyObject = (apiKeys: LlmProvider[]) => { +export const apiKeyObject = () => { + const apiKeys = getAllProviderLlmKeys() + if (!apiKeys) return {} return apiKeys.reduce((acc: GenericObject, {key, name}: GenericObject) => {