diff --git a/web/app/(commonLayout)/app/(appDetailLayout)/[appId]/overview/tracing/config-popup.tsx b/web/app/(commonLayout)/app/(appDetailLayout)/[appId]/overview/tracing/config-popup.tsx index d46563c430..cfc4e7dade 100644 --- a/web/app/(commonLayout)/app/(appDetailLayout)/[appId]/overview/tracing/config-popup.tsx +++ b/web/app/(commonLayout)/app/(appDetailLayout)/[appId]/overview/tracing/config-popup.tsx @@ -5,7 +5,7 @@ import { useTranslation } from 'react-i18next' import { useBoolean } from 'ahooks' import TracingIcon from './tracing-icon' import ProviderPanel from './provider-panel' -import type { LangFuseConfig, LangSmithConfig, OpikConfig } from './type' +import type { LangFuseConfig, LangSmithConfig, OpikConfig, WeaveConfig } from './type' import { TracingProvider } from './type' import ProviderConfigModal from './provider-config-modal' import Indicator from '@/app/components/header/indicator' @@ -26,7 +26,8 @@ export type PopupProps = { langSmithConfig: LangSmithConfig | null langFuseConfig: LangFuseConfig | null opikConfig: OpikConfig | null - onConfigUpdated: (provider: TracingProvider, payload: LangSmithConfig | LangFuseConfig | OpikConfig) => void + weaveConfig: WeaveConfig | null + onConfigUpdated: (provider: TracingProvider, payload: LangSmithConfig | LangFuseConfig | OpikConfig | WeaveConfig) => void onConfigRemoved: (provider: TracingProvider) => void } @@ -40,6 +41,7 @@ const ConfigPopup: FC = ({ langSmithConfig, langFuseConfig, opikConfig, + weaveConfig, onConfigUpdated, onConfigRemoved, }) => { @@ -63,7 +65,7 @@ const ConfigPopup: FC = ({ } }, [onChooseProvider]) - const handleConfigUpdated = useCallback((payload: LangSmithConfig | LangFuseConfig | OpikConfig) => { + const handleConfigUpdated = useCallback((payload: LangSmithConfig | LangFuseConfig | OpikConfig | WeaveConfig) => { onConfigUpdated(currentProvider!, payload) hideConfigModal() }, [currentProvider, hideConfigModal, onConfigUpdated]) @@ -73,8 +75,8 @@ const ConfigPopup: FC = ({ hideConfigModal() }, [currentProvider, hideConfigModal, onConfigRemoved]) - const providerAllConfigured = langSmithConfig && langFuseConfig && opikConfig - const providerAllNotConfigured = !langSmithConfig && !langFuseConfig && !opikConfig + const providerAllConfigured = langSmithConfig && langFuseConfig && opikConfig && weaveConfig + const providerAllNotConfigured = !langSmithConfig && !langFuseConfig && !opikConfig && !weaveConfig const switchContent = ( = ({ /> ) + const weavePanel = ( + + ) const configuredProviderPanel = () => { const configuredPanels: any[] = [] @@ -135,6 +149,9 @@ const ConfigPopup: FC = ({ if (opikConfig) configuredPanels.push(opikPanel) + if (weaveConfig) + configuredPanels.push(weavePanel) + return configuredPanels } @@ -150,6 +167,8 @@ const ConfigPopup: FC = ({ if (!opikConfig) notConfiguredPanels.push(opikPanel) + if (!weaveConfig) + notConfiguredPanels.push(weavePanel) return notConfiguredPanels } @@ -158,7 +177,9 @@ const ConfigPopup: FC = ({ return langSmithConfig if (currentProvider === TracingProvider.langfuse) return langFuseConfig - return opikConfig + if (currentProvider === TracingProvider.opik) + return opikConfig + return weaveConfig } return ( @@ -202,6 +223,7 @@ const ConfigPopup: FC = ({ {langSmithPanel} {langfusePanel} {opikPanel} + {weavePanel} ) diff --git a/web/app/(commonLayout)/app/(appDetailLayout)/[appId]/overview/tracing/config.ts b/web/app/(commonLayout)/app/(appDetailLayout)/[appId]/overview/tracing/config.ts index 0f3f280b30..5d3c4076bd 100644 --- a/web/app/(commonLayout)/app/(appDetailLayout)/[appId]/overview/tracing/config.ts +++ b/web/app/(commonLayout)/app/(appDetailLayout)/[appId]/overview/tracing/config.ts @@ -4,4 +4,5 @@ export const docURL = { [TracingProvider.langSmith]: 'https://docs.smith.langchain.com/', [TracingProvider.langfuse]: 'https://docs.langfuse.com', [TracingProvider.opik]: 'https://www.comet.com/docs/opik/tracing/integrations/dify#setup-instructions', + [TracingProvider.weave]: 'https://weave-docs.wandb.ai/', } diff --git a/web/app/(commonLayout)/app/(appDetailLayout)/[appId]/overview/tracing/panel.tsx b/web/app/(commonLayout)/app/(appDetailLayout)/[appId]/overview/tracing/panel.tsx index 6df1466df8..0404f5074c 100644 --- a/web/app/(commonLayout)/app/(appDetailLayout)/[appId]/overview/tracing/panel.tsx +++ b/web/app/(commonLayout)/app/(appDetailLayout)/[appId]/overview/tracing/panel.tsx @@ -7,12 +7,12 @@ import { import { useTranslation } from 'react-i18next' import { usePathname } from 'next/navigation' import { useBoolean } from 'ahooks' -import type { LangFuseConfig, LangSmithConfig, OpikConfig } from './type' +import type { LangFuseConfig, LangSmithConfig, OpikConfig, WeaveConfig } from './type' import { TracingProvider } from './type' import TracingIcon from './tracing-icon' import ConfigButton from './config-button' import cn from '@/utils/classnames' -import { LangfuseIcon, LangsmithIcon, OpikIcon } from '@/app/components/base/icons/src/public/tracing' +import { LangfuseIcon, LangsmithIcon, OpikIcon, WeaveIcon } from '@/app/components/base/icons/src/public/tracing' import Indicator from '@/app/components/header/indicator' import { fetchTracingConfig as doFetchTracingConfig, fetchTracingStatus, updateTracingStatus } from '@/service/apps' import type { TracingStatus } from '@/models/app' @@ -82,12 +82,15 @@ const Panel: FC = () => { ? LangfuseIcon : inUseTracingProvider === TracingProvider.opik ? OpikIcon - : null + : inUseTracingProvider === TracingProvider.weave + ? WeaveIcon + : null const [langSmithConfig, setLangSmithConfig] = useState(null) const [langFuseConfig, setLangFuseConfig] = useState(null) const [opikConfig, setOpikConfig] = useState(null) - const hasConfiguredTracing = !!(langSmithConfig || langFuseConfig || opikConfig) + const [weaveConfig, setWeaveConfig] = useState(null) + const hasConfiguredTracing = !!(langSmithConfig || langFuseConfig || opikConfig || weaveConfig) const fetchTracingConfig = async () => { const { tracing_config: langSmithConfig, has_not_configured: langSmithHasNotConfig } = await doFetchTracingConfig({ appId, provider: TracingProvider.langSmith }) @@ -99,6 +102,9 @@ const Panel: FC = () => { const { tracing_config: opikConfig, has_not_configured: OpikHasNotConfig } = await doFetchTracingConfig({ appId, provider: TracingProvider.opik }) if (!OpikHasNotConfig) setOpikConfig(opikConfig as OpikConfig) + const { tracing_config: weaveConfig, has_not_configured: weaveHasNotConfig } = await doFetchTracingConfig({ appId, provider: TracingProvider.weave }) + if (!weaveHasNotConfig) + setWeaveConfig(weaveConfig as WeaveConfig) } const handleTracingConfigUpdated = async (provider: TracingProvider) => { @@ -110,6 +116,8 @@ const Panel: FC = () => { setLangFuseConfig(tracing_config as LangFuseConfig) else if (provider === TracingProvider.opik) setOpikConfig(tracing_config as OpikConfig) + else if (provider === TracingProvider.weave) + setWeaveConfig(tracing_config as WeaveConfig) } const handleTracingConfigRemoved = (provider: TracingProvider) => { @@ -119,6 +127,8 @@ const Panel: FC = () => { setLangFuseConfig(null) else if (provider === TracingProvider.opik) setOpikConfig(null) + else if (provider === TracingProvider.weave) + setWeaveConfig(null) if (provider === inUseTracingProvider) { handleTracingStatusChange({ enabled: false, @@ -178,6 +188,7 @@ const Panel: FC = () => { langSmithConfig={langSmithConfig} langFuseConfig={langFuseConfig} opikConfig={opikConfig} + weaveConfig={weaveConfig} onConfigUpdated={handleTracingConfigUpdated} onConfigRemoved={handleTracingConfigRemoved} controlShowPopup={controlShowPopup} @@ -212,6 +223,7 @@ const Panel: FC = () => { langSmithConfig={langSmithConfig} langFuseConfig={langFuseConfig} opikConfig={opikConfig} + weaveConfig={weaveConfig} onConfigUpdated={handleTracingConfigUpdated} onConfigRemoved={handleTracingConfigRemoved} controlShowPopup={controlShowPopup} diff --git a/web/app/(commonLayout)/app/(appDetailLayout)/[appId]/overview/tracing/provider-config-modal.tsx b/web/app/(commonLayout)/app/(appDetailLayout)/[appId]/overview/tracing/provider-config-modal.tsx index e6a520648f..974db4732a 100644 --- a/web/app/(commonLayout)/app/(appDetailLayout)/[appId]/overview/tracing/provider-config-modal.tsx +++ b/web/app/(commonLayout)/app/(appDetailLayout)/[appId]/overview/tracing/provider-config-modal.tsx @@ -4,7 +4,7 @@ import React, { useCallback, useState } from 'react' import { useTranslation } from 'react-i18next' import { useBoolean } from 'ahooks' import Field from './field' -import type { LangFuseConfig, LangSmithConfig, OpikConfig } from './type' +import type {LangFuseConfig, LangSmithConfig, OpikConfig, WeaveConfig } from './type' import { TracingProvider } from './type' import { docURL } from './config' import { @@ -22,10 +22,10 @@ import Divider from '@/app/components/base/divider' type Props = { appId: string type: TracingProvider - payload?: LangSmithConfig | LangFuseConfig | OpikConfig | null + payload?: LangSmithConfig | LangFuseConfig | OpikConfig | WeaveConfig | null onRemoved: () => void onCancel: () => void - onSaved: (payload: LangSmithConfig | LangFuseConfig | OpikConfig) => void + onSaved: (payload: LangSmithConfig | LangFuseConfig | OpikConfig | WeaveConfig) => void onChosen: (provider: TracingProvider) => void } @@ -50,6 +50,13 @@ const opikConfigTemplate = { workspace: '', } +const weaveConfigTemplate = { + api_key: '', + entity: '', + project: '', + endpoint: '', +} + const ProviderConfigModal: FC = ({ appId, type, @@ -63,7 +70,7 @@ const ProviderConfigModal: FC = ({ const isEdit = !!payload const isAdd = !isEdit const [isSaving, setIsSaving] = useState(false) - const [config, setConfig] = useState((() => { + const [config, setConfig] = useState((() => { if (isEdit) return payload @@ -73,7 +80,10 @@ const ProviderConfigModal: FC = ({ else if (type === TracingProvider.langfuse) return langFuseConfigTemplate - return opikConfigTemplate + else if (type === TracingProvider.opik) + return opikConfigTemplate + + return weaveConfigTemplate })()) const [isShowRemoveConfirm, { setTrue: showRemoveConfirm, @@ -127,6 +137,14 @@ const ProviderConfigModal: FC = ({ // const postData = config as OpikConfig } + if (type === TracingProvider.weave) { + const postData = config as WeaveConfig + if (!errorMessage && !postData.api_key) + errorMessage = t('common.errorMsg.fieldRequired', { field: 'API Key' }) + if (!errorMessage && !postData.project) + errorMessage = t('common.errorMsg.fieldRequired', { field: t(`${I18N_PREFIX}.project`) }) + } + return errorMessage }, [config, t, type]) const handleSave = useCallback(async () => { @@ -263,6 +281,40 @@ const ProviderConfigModal: FC = ({ /> )} + {type === TracingProvider.weave && ( + <> + + + + + + )}
diff --git a/web/app/(commonLayout)/app/(appDetailLayout)/[appId]/overview/tracing/provider-panel.tsx b/web/app/(commonLayout)/app/(appDetailLayout)/[appId]/overview/tracing/provider-panel.tsx index 36221357a4..6c29c4dde4 100644 --- a/web/app/(commonLayout)/app/(appDetailLayout)/[appId]/overview/tracing/provider-panel.tsx +++ b/web/app/(commonLayout)/app/(appDetailLayout)/[appId]/overview/tracing/provider-panel.tsx @@ -7,7 +7,7 @@ import { import { useTranslation } from 'react-i18next' import { TracingProvider } from './type' import cn from '@/utils/classnames' -import { LangfuseIconBig, LangsmithIconBig, OpikIconBig } from '@/app/components/base/icons/src/public/tracing' +import { LangfuseIconBig, LangsmithIconBig, OpikIconBig, WeaveIconBig } from '@/app/components/base/icons/src/public/tracing' import { Eye as View } from '@/app/components/base/icons/src/vender/solid/general' const I18N_PREFIX = 'app.tracing' @@ -27,6 +27,7 @@ const getIcon = (type: TracingProvider) => { [TracingProvider.langSmith]: LangsmithIconBig, [TracingProvider.langfuse]: LangfuseIconBig, [TracingProvider.opik]: OpikIconBig, + [TracingProvider.weave]: WeaveIconBig, })[type] } diff --git a/web/app/(commonLayout)/app/(appDetailLayout)/[appId]/overview/tracing/type.ts b/web/app/(commonLayout)/app/(appDetailLayout)/[appId]/overview/tracing/type.ts index 982d01ffb3..386c58974e 100644 --- a/web/app/(commonLayout)/app/(appDetailLayout)/[appId]/overview/tracing/type.ts +++ b/web/app/(commonLayout)/app/(appDetailLayout)/[appId]/overview/tracing/type.ts @@ -2,6 +2,7 @@ export enum TracingProvider { langSmith = 'langsmith', langfuse = 'langfuse', opik = 'opik', + weave = 'weave', } export type LangSmithConfig = { @@ -22,3 +23,10 @@ export type OpikConfig = { workspace: string url: string } + +export type WeaveConfig = { + api_key: string + entity: string + project: string + endpoint: string +}