From 0d238a3e20081f89ed72e028887b4e7db98bbafc Mon Sep 17 00:00:00 2001 From: twwu Date: Mon, 25 May 2026 14:54:41 +0800 Subject: [PATCH] refactor: Remove Serpapi plugin integration and related tests --- .../plugin-page/SerpapiPlugin.tsx | 69 ------ .../__tests__/SerpapiPlugin.spec.tsx | 213 ------------------ .../plugin-page/__tests__/index.spec.tsx | 120 ---------- .../plugin-page/__tests__/utils.spec.ts | 73 ------ .../account-setting/plugin-page/index.tsx | 38 ---- .../account-setting/plugin-page/utils.ts | 34 --- web/app/components/header/assets/serpapi.png | Bin 3043 -> 0 bytes web/i18n/ar-TN/common.json | 3 - web/i18n/de-DE/common.json | 3 - web/i18n/en-US/common.json | 3 - web/i18n/es-ES/common.json | 3 - web/i18n/fa-IR/common.json | 3 - web/i18n/fr-FR/common.json | 3 - web/i18n/hi-IN/common.json | 3 - web/i18n/id-ID/common.json | 3 - web/i18n/it-IT/common.json | 3 - web/i18n/ja-JP/common.json | 3 - web/i18n/ko-KR/common.json | 3 - web/i18n/nl-NL/common.json | 3 - web/i18n/pl-PL/common.json | 3 - web/i18n/pt-BR/common.json | 3 - web/i18n/ro-RO/common.json | 3 - web/i18n/ru-RU/common.json | 3 - web/i18n/sl-SI/common.json | 3 - web/i18n/th-TH/common.json | 3 - web/i18n/tr-TR/common.json | 3 - web/i18n/uk-UA/common.json | 3 - web/i18n/vi-VN/common.json | 3 - web/i18n/zh-Hans/common.json | 3 - web/i18n/zh-Hant/common.json | 3 - web/models/common.ts | 8 - web/service/common.ts | 12 - web/service/use-common.ts | 9 - 33 files changed, 645 deletions(-) delete mode 100644 web/app/components/header/account-setting/plugin-page/SerpapiPlugin.tsx delete mode 100644 web/app/components/header/account-setting/plugin-page/__tests__/SerpapiPlugin.spec.tsx delete mode 100644 web/app/components/header/account-setting/plugin-page/__tests__/index.spec.tsx delete mode 100644 web/app/components/header/account-setting/plugin-page/__tests__/utils.spec.ts delete mode 100644 web/app/components/header/account-setting/plugin-page/index.tsx delete mode 100644 web/app/components/header/account-setting/plugin-page/utils.ts delete mode 100644 web/app/components/header/assets/serpapi.png diff --git a/web/app/components/header/account-setting/plugin-page/SerpapiPlugin.tsx b/web/app/components/header/account-setting/plugin-page/SerpapiPlugin.tsx deleted file mode 100644 index 31c4ce2c3a..0000000000 --- a/web/app/components/header/account-setting/plugin-page/SerpapiPlugin.tsx +++ /dev/null @@ -1,69 +0,0 @@ -import type { Form, ValidateValue } from '../key-validator/declarations' -import type { PluginProvider } from '@/models/common' -import { toast } from '@langgenius/dify-ui/toast' -import { useTranslation } from 'react-i18next' -import { useAppContext } from '@/context/app-context' -import SerpapiLogo from '../../assets/serpapi.png' -import KeyValidator from '../key-validator' -import { updatePluginKey, validatePluginKey } from './utils' - -type SerpapiPluginProps = { - plugin: PluginProvider - onUpdate: () => void -} -const SerpapiPlugin = ({ plugin, onUpdate }: SerpapiPluginProps) => { - const { t } = useTranslation() - const { isCurrentWorkspaceManager } = useAppContext() - const forms: Form[] = [{ - key: 'api_key', - title: t('plugin.serpapi.apiKey', { ns: 'common' }), - placeholder: t('plugin.serpapi.apiKeyPlaceholder', { ns: 'common' }), - value: plugin.credentials?.api_key, - validate: { - before: (v) => { - if (v?.api_key) - return true - }, - run: async (v) => { - return validatePluginKey('serpapi', { - credentials: { - api_key: v?.api_key, - }, - }) - }, - }, - handleFocus: (v, dispatch) => { - if (v.api_key === plugin.credentials?.api_key) - dispatch({ ...v, api_key: '' }) - }, - }] - const handleSave = async (v: ValidateValue) => { - if (!v?.api_key || v?.api_key === plugin.credentials?.api_key) - return - const res = await updatePluginKey('serpapi', { - credentials: { - api_key: v?.api_key, - }, - }) - if (res.status === 'success') { - toast.success(t('actionMsg.modifiedSuccessfully', { ns: 'common' })) - onUpdate() - return true - } - } - return ( - } - status={plugin.credentials?.api_key ? 'success' : 'add'} - forms={forms} - keyFrom={{ - text: t('plugin.serpapi.keyFrom', { ns: 'common' }), - link: 'https://serpapi.com/manage-api-key', - }} - onSave={handleSave} - disabled={!isCurrentWorkspaceManager} - /> - ) -} -export default SerpapiPlugin diff --git a/web/app/components/header/account-setting/plugin-page/__tests__/SerpapiPlugin.spec.tsx b/web/app/components/header/account-setting/plugin-page/__tests__/SerpapiPlugin.spec.tsx deleted file mode 100644 index 2055c0725d..0000000000 --- a/web/app/components/header/account-setting/plugin-page/__tests__/SerpapiPlugin.spec.tsx +++ /dev/null @@ -1,213 +0,0 @@ -import type { PluginProvider } from '@/models/common' -import { act, fireEvent, render, screen, waitFor } from '@testing-library/react' -import { useAppContext } from '@/context/app-context' -import SerpapiPlugin from '../SerpapiPlugin' -import { updatePluginKey, validatePluginKey } from '../utils' - -const mockEventEmitter = vi.hoisted(() => { - let subscriber: ((value: string) => void) | undefined - return { - useSubscription: vi.fn((callback: (value: string) => void) => { - subscriber = callback - }), - emit: vi.fn((value: string) => { - subscriber?.(value) - }), - reset: () => { - subscriber = undefined - }, - } -}) - -const { mockToast } = vi.hoisted(() => { - const mockToast = Object.assign(vi.fn(), { - success: vi.fn(), - error: vi.fn(), - warning: vi.fn(), - info: vi.fn(), - dismiss: vi.fn(), - update: vi.fn(), - promise: vi.fn(), - }) - return { mockToast } -}) - -vi.mock('@langgenius/dify-ui/toast', () => ({ - toast: mockToast, -})) - -vi.mock('@/context/app-context', () => ({ - useAppContext: vi.fn(), -})) - -vi.mock('../utils', () => ({ - updatePluginKey: vi.fn(), - validatePluginKey: vi.fn(), -})) - -vi.mock('@/context/event-emitter', () => ({ - useEventEmitterContextContext: vi.fn(() => ({ - eventEmitter: mockEventEmitter, - })), -})) - -describe('SerpapiPlugin', () => { - const mockOnUpdate = vi.fn() - const mockUpdatePluginKey = updatePluginKey as ReturnType - const mockValidatePluginKey = validatePluginKey as ReturnType - - beforeEach(() => { - vi.clearAllMocks() - mockEventEmitter.reset() - const mockUseAppContext = useAppContext as ReturnType - mockUseAppContext.mockReturnValue({ - isCurrentWorkspaceManager: true, - }) - mockValidatePluginKey.mockResolvedValue({ status: 'success' }) - mockUpdatePluginKey.mockResolvedValue({ status: 'success' }) - }) - - it('should show key input when manager clicks edit key', () => { - const mockPlugin: PluginProvider = { - tool_name: 'serpapi', - credentials: { - api_key: 'existing-key', - }, - } as PluginProvider - - render() - - fireEvent.click(screen.getByText('common.provider.editKey')) - expect(screen.getByPlaceholderText('common.plugin.serpapi.apiKeyPlaceholder')).toBeInTheDocument() - }) - - it('should clear existing key on focus and show validation error for invalid key', async () => { - vi.useFakeTimers() - try { - mockValidatePluginKey.mockResolvedValue({ status: 'error', message: 'Invalid API key' }) - - const mockPlugin: PluginProvider = { - tool_name: 'serpapi', - credentials: { - api_key: 'existing-key', - }, - } as PluginProvider - - render() - - fireEvent.click(screen.getByText('common.provider.editKey')) - const input = screen.getByPlaceholderText('common.plugin.serpapi.apiKeyPlaceholder') - - expect(input).toHaveValue('existing-key') - fireEvent.focus(input) - expect(input).toHaveValue('') - - fireEvent.change(input, { - target: { value: 'invalid-key' }, - }) - - await act(async () => { - await vi.advanceTimersByTimeAsync(1000) - }) - - expect(screen.getByText(/Invalid API key/)).toBeInTheDocument() - - fireEvent.focus(input) - expect(input).toHaveValue('invalid-key') - - fireEvent.change(input, { - target: { value: '' }, - }) - - await act(async () => { - await vi.advanceTimersByTimeAsync(1000) - }) - - expect(screen.queryByText(/Invalid API key/)).toBeNull() - } - finally { - vi.useRealTimers() - } - }) - - it('should not open key input when user is not workspace manager', () => { - const mockUseAppContext = useAppContext as ReturnType - mockUseAppContext.mockReturnValue({ - isCurrentWorkspaceManager: false, - }) - - const mockPlugin = { - tool_name: 'serpapi', - is_enabled: true, - credentials: null, - } satisfies PluginProvider - - render() - - fireEvent.click(screen.getByText('common.provider.addKey')) - - expect(screen.queryByPlaceholderText('common.plugin.serpapi.apiKeyPlaceholder')).toBeNull() - }) - - it('should save changed key and trigger success feedback', async () => { - const mockPlugin: PluginProvider = { - tool_name: 'serpapi', - credentials: { - api_key: 'existing-key', - }, - } as PluginProvider - - render() - - fireEvent.click(screen.getByText('common.provider.editKey')) - fireEvent.change(screen.getByPlaceholderText('common.plugin.serpapi.apiKeyPlaceholder'), { - target: { value: 'new-key' }, - }) - fireEvent.click(screen.getByText('common.operation.save')) - - await waitFor(() => { - expect(screen.queryByPlaceholderText('common.plugin.serpapi.apiKeyPlaceholder')).toBeNull() - }) - }) - - it('should keep editor open when save request fails', async () => { - mockUpdatePluginKey.mockResolvedValue({ status: 'error', message: 'update failed' }) - - const mockPlugin: PluginProvider = { - tool_name: 'serpapi', - credentials: { - api_key: 'existing-key', - }, - } as PluginProvider - - render() - - fireEvent.click(screen.getByText('common.provider.editKey')) - fireEvent.change(screen.getByPlaceholderText('common.plugin.serpapi.apiKeyPlaceholder'), { - target: { value: 'new-key' }, - }) - fireEvent.click(screen.getByText('common.operation.save')) - - await waitFor(() => { - expect(screen.getByPlaceholderText('common.plugin.serpapi.apiKeyPlaceholder')).toBeInTheDocument() - }) - }) - - it('should keep editor open when key value is unchanged', async () => { - const mockPlugin: PluginProvider = { - tool_name: 'serpapi', - credentials: { - api_key: 'existing-key', - }, - } as PluginProvider - - render() - - fireEvent.click(screen.getByText('common.provider.editKey')) - fireEvent.click(screen.getByText('common.operation.save')) - - await waitFor(() => { - expect(screen.getByPlaceholderText('common.plugin.serpapi.apiKeyPlaceholder')).toBeInTheDocument() - }) - }) -}) diff --git a/web/app/components/header/account-setting/plugin-page/__tests__/index.spec.tsx b/web/app/components/header/account-setting/plugin-page/__tests__/index.spec.tsx deleted file mode 100644 index ca0c41a83b..0000000000 --- a/web/app/components/header/account-setting/plugin-page/__tests__/index.spec.tsx +++ /dev/null @@ -1,120 +0,0 @@ -import { fireEvent, render, screen, waitFor } from '@testing-library/react' -import { useState } from 'react' -import { useAppContext } from '@/context/app-context' -import PluginPage from '../index' -import { updatePluginKey, validatePluginKey } from '../utils' - -const mockUsePluginProviders = vi.hoisted(() => vi.fn()) - -vi.mock('@/service/use-common', () => ({ - usePluginProviders: mockUsePluginProviders, -})) - -vi.mock('@/context/app-context', () => ({ - useAppContext: vi.fn(), -})) - -vi.mock('@langgenius/dify-ui/toast', async (importOriginal) => { - const actual = await importOriginal() - return { - ...actual, - - } -}) - -vi.mock('@/context/event-emitter', () => ({ - useEventEmitterContextContext: () => ({ - eventEmitter: { - emit: vi.fn(), - useSubscription: vi.fn(), - }, - }), -})) - -vi.mock('../utils', () => ({ - updatePluginKey: vi.fn(), - validatePluginKey: vi.fn(), -})) - -describe('PluginPage', () => { - const mockUpdatePluginKey = updatePluginKey as ReturnType - const mockValidatePluginKey = validatePluginKey as ReturnType - - beforeEach(() => { - vi.clearAllMocks() - const mockUseAppContext = useAppContext as ReturnType - mockUseAppContext.mockReturnValue({ - isCurrentWorkspaceManager: true, - }) - mockValidatePluginKey.mockResolvedValue({ status: 'success' }) - mockUpdatePluginKey.mockResolvedValue({ status: 'success' }) - }) - - it('should render plugin settings with edit action when serpapi key exists', () => { - mockUsePluginProviders.mockReturnValue({ - data: [ - { tool_name: 'serpapi', credentials: { api_key: 'test-key' } }, - ], - refetch: vi.fn(), - }) - - render() - expect(screen.getByText('common.provider.editKey')).toBeInTheDocument() - }) - - it('should render plugin settings with add action when serpapi key is missing', () => { - mockUsePluginProviders.mockReturnValue({ - data: [ - { tool_name: 'serpapi', credentials: null }, - ], - refetch: vi.fn(), - }) - - render() - expect(screen.getByText('common.provider.addKey')).toBeInTheDocument() - }) - - it('should display encryption notice with PKCS1_OAEP link', () => { - mockUsePluginProviders.mockReturnValue({ - data: [], - refetch: vi.fn(), - }) - - render() - expect(screen.getByText(/common\.provider\.encrypted\.front/)).toBeInTheDocument() - expect(screen.getByText(/common\.provider\.encrypted\.back/)).toBeInTheDocument() - const link = screen.getByRole('link', { name: 'PKCS1_OAEP' }) - expect(link).toHaveAttribute('target', '_blank') - expect(link).toHaveAttribute('href', 'https://pycryptodome.readthedocs.io/en/latest/src/cipher/oaep.html') - }) - - it('should show reload state after saving key', async () => { - let showReloadedState = () => {} - const Wrapper = () => { - const [reloaded, setReloaded] = useState(false) - showReloadedState = () => setReloaded(true) - return ( - <> - - {reloaded &&
providers-reloaded
} - - ) - } - mockUsePluginProviders.mockImplementation(() => ({ - data: [{ tool_name: 'serpapi', credentials: { api_key: 'existing-key' } }], - refetch: () => showReloadedState(), - })) - - render() - - fireEvent.click(screen.getByText('common.provider.editKey')) - fireEvent.change(screen.getByPlaceholderText('common.plugin.serpapi.apiKeyPlaceholder'), { - target: { value: 'new-key' }, - }) - fireEvent.click(screen.getByText('common.operation.save')) - - await waitFor(() => { - expect(screen.getByText('providers-reloaded')).toBeInTheDocument() - }) - }) -}) diff --git a/web/app/components/header/account-setting/plugin-page/__tests__/utils.spec.ts b/web/app/components/header/account-setting/plugin-page/__tests__/utils.spec.ts deleted file mode 100644 index e49a9f41c9..0000000000 --- a/web/app/components/header/account-setting/plugin-page/__tests__/utils.spec.ts +++ /dev/null @@ -1,73 +0,0 @@ -import { updatePluginProviderAIKey, validatePluginProviderKey } from '@/service/common' -import { ValidatedStatus } from '../../key-validator/declarations' -import { updatePluginKey, validatePluginKey } from '../utils' - -vi.mock('@/service/common', () => ({ - validatePluginProviderKey: vi.fn(), - updatePluginProviderAIKey: vi.fn(), -})) - -const mockValidatePluginProviderKey = validatePluginProviderKey as ReturnType -const mockUpdatePluginProviderAIKey = updatePluginProviderAIKey as ReturnType - -describe('Plugin Utils', () => { - beforeEach(() => { - vi.clearAllMocks() - }) - - describe.each([ - { - name: 'validatePluginKey', - utilFn: validatePluginKey, - serviceMock: mockValidatePluginProviderKey, - successBody: { credentials: { api_key: 'test-key' } }, - failureBody: { credentials: { api_key: 'invalid' } }, - exceptionBody: { credentials: { api_key: 'test' } }, - serviceErrorMessage: 'Invalid API key', - thrownErrorMessage: 'Network error', - }, - { - name: 'updatePluginKey', - utilFn: updatePluginKey, - serviceMock: mockUpdatePluginProviderAIKey, - successBody: { credentials: { api_key: 'new-key' } }, - failureBody: { credentials: { api_key: 'test' } }, - exceptionBody: { credentials: { api_key: 'test' } }, - serviceErrorMessage: 'Update failed', - thrownErrorMessage: 'Request failed', - }, - ])('$name', ({ utilFn, serviceMock, successBody, failureBody, exceptionBody, serviceErrorMessage, thrownErrorMessage }) => { - it('should return success status when service succeeds', async () => { - serviceMock.mockResolvedValue({ result: 'success' }) - - const result = await utilFn('serpapi', successBody) - - expect(result.status).toBe(ValidatedStatus.Success) - }) - - it('should return error status with message when service returns an error', async () => { - serviceMock.mockResolvedValue({ - result: 'error', - error: serviceErrorMessage, - }) - - const result = await utilFn('serpapi', failureBody) - - expect(result).toMatchObject({ - status: ValidatedStatus.Error, - message: serviceErrorMessage, - }) - }) - - it('should return error status when service throws exception', async () => { - serviceMock.mockRejectedValue(new Error(thrownErrorMessage)) - - const result = await utilFn('serpapi', exceptionBody) - - expect(result).toMatchObject({ - status: ValidatedStatus.Error, - message: thrownErrorMessage, - }) - }) - }) -}) diff --git a/web/app/components/header/account-setting/plugin-page/index.tsx b/web/app/components/header/account-setting/plugin-page/index.tsx deleted file mode 100644 index 15d8302874..0000000000 --- a/web/app/components/header/account-setting/plugin-page/index.tsx +++ /dev/null @@ -1,38 +0,0 @@ -import type { PluginProvider } from '@/models/common' -import { LockClosedIcon } from '@heroicons/react/24/solid' -import { useTranslation } from 'react-i18next' -import Link from '@/next/link' -import { usePluginProviders } from '@/service/use-common' -import SerpapiPlugin from './SerpapiPlugin' - -const PluginPage = () => { - const { t } = useTranslation() - const { data: plugins, refetch: mutate } = usePluginProviders() - - const Plugin_MAP: Record React.JSX.Element> = { - serpapi: (plugin: PluginProvider) => mutate()} />, - } - - return ( -
-
- {plugins?.map(plugin => Plugin_MAP[plugin.tool_name]!(plugin))} -
-
- - {t('provider.encrypted.front', { ns: 'common' })} - - PKCS1_OAEP - - {t('provider.encrypted.back', { ns: 'common' })} -
-
- ) -} - -export default PluginPage diff --git a/web/app/components/header/account-setting/plugin-page/utils.ts b/web/app/components/header/account-setting/plugin-page/utils.ts deleted file mode 100644 index 385ef31cab..0000000000 --- a/web/app/components/header/account-setting/plugin-page/utils.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { updatePluginProviderAIKey, validatePluginProviderKey } from '@/service/common' -import { ValidatedStatus } from '../key-validator/declarations' - -export const validatePluginKey = async (pluginType: string, body: any) => { - try { - const res = await validatePluginProviderKey({ - url: `/workspaces/current/tool-providers/${pluginType}/credentials-validate`, - body, - }) - if (res.result === 'success') - return Promise.resolve({ status: ValidatedStatus.Success }) - else - return Promise.resolve({ status: ValidatedStatus.Error, message: res.error }) - } - catch (e: any) { - return Promise.resolve({ status: ValidatedStatus.Error, message: e.message }) - } -} - -export const updatePluginKey = async (pluginType: string, body: any) => { - try { - const res = await updatePluginProviderAIKey({ - url: `/workspaces/current/tool-providers/${pluginType}/credentials`, - body, - }) - if (res.result === 'success') - return Promise.resolve({ status: ValidatedStatus.Success }) - else - return Promise.resolve({ status: ValidatedStatus.Error, message: res.error }) - } - catch (e: any) { - return Promise.resolve({ status: ValidatedStatus.Error, message: e.message }) - } -} diff --git a/web/app/components/header/assets/serpapi.png b/web/app/components/header/assets/serpapi.png deleted file mode 100644 index 9650453ed5faa1f271619ad78fda21019771144d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3043 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 diff --git a/web/i18n/ar-TN/common.json b/web/i18n/ar-TN/common.json index ea4508ac3e..01a5aeafbc 100644 --- a/web/i18n/ar-TN/common.json +++ b/web/i18n/ar-TN/common.json @@ -538,9 +538,6 @@ "placeholder.input": "يرجى الإدخال", "placeholder.search": "بحث...", "placeholder.select": "يرجى التحديد", - "plugin.serpapi.apiKey": "مفتاح API", - "plugin.serpapi.apiKeyPlaceholder": "أدخل مفتاح API الخاص بك", - "plugin.serpapi.keyFrom": "احصل على مفتاح SerpAPI الخاص بك من صفحة حساب SerpAPI", "promptEditor.context.item.desc": "إدراج قالب السياق", "promptEditor.context.item.title": "السياق", "promptEditor.context.modal.add": "إضافة سياق ", diff --git a/web/i18n/de-DE/common.json b/web/i18n/de-DE/common.json index ab53317f20..e858e4a31d 100644 --- a/web/i18n/de-DE/common.json +++ b/web/i18n/de-DE/common.json @@ -538,9 +538,6 @@ "placeholder.input": "Bitte eingeben", "placeholder.search": "Suchen...", "placeholder.select": "Bitte auswählen", - "plugin.serpapi.apiKey": "API-Schlüssel", - "plugin.serpapi.apiKeyPlaceholder": "Geben Sie Ihren API-Schlüssel ein", - "plugin.serpapi.keyFrom": "Holen Sie Ihren SerpAPI-Schlüssel von der SerpAPI-Kontoseite", "promptEditor.context.item.desc": "Kontextvorlage einfügen", "promptEditor.context.item.title": "Kontext", "promptEditor.context.modal.add": "Kontext hinzufügen", diff --git a/web/i18n/en-US/common.json b/web/i18n/en-US/common.json index 9b262695de..846769ec2a 100644 --- a/web/i18n/en-US/common.json +++ b/web/i18n/en-US/common.json @@ -569,9 +569,6 @@ "placeholder.input": "Please enter", "placeholder.search": "Search...", "placeholder.select": "Please select", - "plugin.serpapi.apiKey": "API Key", - "plugin.serpapi.apiKeyPlaceholder": "Enter your API key", - "plugin.serpapi.keyFrom": "Get your SerpAPI key from SerpAPI Account Page", "promptEditor.context.item.desc": "Insert context template", "promptEditor.context.item.title": "Context", "promptEditor.context.modal.add": "Add Context ", diff --git a/web/i18n/es-ES/common.json b/web/i18n/es-ES/common.json index 9f2836d457..e9a621016d 100644 --- a/web/i18n/es-ES/common.json +++ b/web/i18n/es-ES/common.json @@ -538,9 +538,6 @@ "placeholder.input": "Por favor ingresa", "placeholder.search": "Buscar...", "placeholder.select": "Por favor selecciona", - "plugin.serpapi.apiKey": "Clave API", - "plugin.serpapi.apiKeyPlaceholder": "Ingresa tu clave API", - "plugin.serpapi.keyFrom": "Obtén tu clave API de SerpAPI en la página de cuenta de SerpAPI", "promptEditor.context.item.desc": "Insertar plantilla de contexto", "promptEditor.context.item.title": "Contexto", "promptEditor.context.modal.add": "Agregar Contexto ", diff --git a/web/i18n/fa-IR/common.json b/web/i18n/fa-IR/common.json index 0a0e067d59..553700e028 100644 --- a/web/i18n/fa-IR/common.json +++ b/web/i18n/fa-IR/common.json @@ -538,9 +538,6 @@ "placeholder.input": "لطفا وارد کنید", "placeholder.search": "جستجو...", "placeholder.select": "لطفا انتخاب کنید", - "plugin.serpapi.apiKey": "کلید API", - "plugin.serpapi.apiKeyPlaceholder": "کلید API خود را وارد کنید", - "plugin.serpapi.keyFrom": "کلید SerpAPI خود را از صفحه حساب SerpAPI دریافت کنید", "promptEditor.context.item.desc": "درج الگوی زمینه", "promptEditor.context.item.title": "زمینه", "promptEditor.context.modal.add": "افزودن زمینه", diff --git a/web/i18n/fr-FR/common.json b/web/i18n/fr-FR/common.json index 8972aae8ae..a1feb65395 100644 --- a/web/i18n/fr-FR/common.json +++ b/web/i18n/fr-FR/common.json @@ -538,9 +538,6 @@ "placeholder.input": "Veuillez entrer", "placeholder.search": "Rechercher...", "placeholder.select": "Veuillez sélectionner", - "plugin.serpapi.apiKey": "Clé API", - "plugin.serpapi.apiKeyPlaceholder": "Entrez votre clé API", - "plugin.serpapi.keyFrom": "Obtenez votre clé SerpAPI depuis la page de compte SerpAPI", "promptEditor.context.item.desc": "Insérez le modèle de contexte", "promptEditor.context.item.title": "Contexte", "promptEditor.context.modal.add": "Ajouter Contexte", diff --git a/web/i18n/hi-IN/common.json b/web/i18n/hi-IN/common.json index 62f73213c4..bfb8b69891 100644 --- a/web/i18n/hi-IN/common.json +++ b/web/i18n/hi-IN/common.json @@ -538,9 +538,6 @@ "placeholder.input": "कृपया दर्ज करें", "placeholder.search": "खोजें...", "placeholder.select": "कृपया चयन करें", - "plugin.serpapi.apiKey": "एपीआई कुंजी", - "plugin.serpapi.apiKeyPlaceholder": "अपनी एपीआई कुंजी दर्ज करें", - "plugin.serpapi.keyFrom": "SerpAPI खाता पृष्ठ से अपनी SerpAPI कुंजी प्राप्त करें", "promptEditor.context.item.desc": "संदर्भ टेम्पलेट डालें", "promptEditor.context.item.title": "संदर्भ", "promptEditor.context.modal.add": "संदर्भ जोड़ें", diff --git a/web/i18n/id-ID/common.json b/web/i18n/id-ID/common.json index 1f52c7a42c..faeb51f7c6 100644 --- a/web/i18n/id-ID/common.json +++ b/web/i18n/id-ID/common.json @@ -538,9 +538,6 @@ "placeholder.input": "Silakan masuk", "placeholder.search": "Cari...", "placeholder.select": "Silakan pilih", - "plugin.serpapi.apiKey": "Kunci API", - "plugin.serpapi.apiKeyPlaceholder": "Masukkan kunci API Anda", - "plugin.serpapi.keyFrom": "Dapatkan kunci SerpAPI Anda dari Halaman Akun SerpAPI", "promptEditor.context.item.desc": "Sisipkan templat konteks", "promptEditor.context.item.title": "Konteks", "promptEditor.context.modal.add": "Tambahkan Konteks", diff --git a/web/i18n/it-IT/common.json b/web/i18n/it-IT/common.json index bd920e5067..ba4b5c53b3 100644 --- a/web/i18n/it-IT/common.json +++ b/web/i18n/it-IT/common.json @@ -538,9 +538,6 @@ "placeholder.input": "Per favore inserisci", "placeholder.search": "Cerca...", "placeholder.select": "Per favore seleziona", - "plugin.serpapi.apiKey": "API Key", - "plugin.serpapi.apiKeyPlaceholder": "Inserisci la tua API key", - "plugin.serpapi.keyFrom": "Ottieni la tua API key dalla pagina dell'account SerpAPI", "promptEditor.context.item.desc": "Inserisci modello di contesto", "promptEditor.context.item.title": "Contesto", "promptEditor.context.modal.add": "Aggiungi Contesto ", diff --git a/web/i18n/ja-JP/common.json b/web/i18n/ja-JP/common.json index f7da994da2..e3edd2ad9a 100644 --- a/web/i18n/ja-JP/common.json +++ b/web/i18n/ja-JP/common.json @@ -569,9 +569,6 @@ "placeholder.input": "入力してください", "placeholder.search": "検索...", "placeholder.select": "選択してください", - "plugin.serpapi.apiKey": "API キー", - "plugin.serpapi.apiKeyPlaceholder": "API キーを入力してください", - "plugin.serpapi.keyFrom": "SerpAPI アカウントページから SerpAPI キーを取得してください", "promptEditor.context.item.desc": "コンテキストテンプレートを挿入", "promptEditor.context.item.title": "コンテキスト", "promptEditor.context.modal.add": "コンテキストを追加", diff --git a/web/i18n/ko-KR/common.json b/web/i18n/ko-KR/common.json index 7aed2e3831..9ee449dccc 100644 --- a/web/i18n/ko-KR/common.json +++ b/web/i18n/ko-KR/common.json @@ -538,9 +538,6 @@ "placeholder.input": "입력해주세요", "placeholder.search": "검색...", "placeholder.select": "선택해주세요", - "plugin.serpapi.apiKey": "API 키", - "plugin.serpapi.apiKeyPlaceholder": "API 키를 입력하세요", - "plugin.serpapi.keyFrom": "SerpAPI 계정 페이지에서 SerpAPI 키를 가져오세요", "promptEditor.context.item.desc": "컨텍스트 템플릿을 삽입합니다.", "promptEditor.context.item.title": "컨텍스트", "promptEditor.context.modal.add": "컨텍스트 추가", diff --git a/web/i18n/nl-NL/common.json b/web/i18n/nl-NL/common.json index 969232bf25..b37f0c41b1 100644 --- a/web/i18n/nl-NL/common.json +++ b/web/i18n/nl-NL/common.json @@ -538,9 +538,6 @@ "placeholder.input": "Please enter", "placeholder.search": "Search...", "placeholder.select": "Please select", - "plugin.serpapi.apiKey": "API Key", - "plugin.serpapi.apiKeyPlaceholder": "Enter your API key", - "plugin.serpapi.keyFrom": "Get your SerpAPI key from SerpAPI Account Page", "promptEditor.context.item.desc": "Insert context template", "promptEditor.context.item.title": "Context", "promptEditor.context.modal.add": "Add Context ", diff --git a/web/i18n/pl-PL/common.json b/web/i18n/pl-PL/common.json index 98a134b5f0..b07a58aed2 100644 --- a/web/i18n/pl-PL/common.json +++ b/web/i18n/pl-PL/common.json @@ -538,9 +538,6 @@ "placeholder.input": "Proszę wprowadzić", "placeholder.search": "Szukaj...", "placeholder.select": "Proszę wybrać", - "plugin.serpapi.apiKey": "Klucz API", - "plugin.serpapi.apiKeyPlaceholder": "Wprowadź swój klucz API", - "plugin.serpapi.keyFrom": "Pobierz swój klucz SerpAPI ze strony konta SerpAPI", "promptEditor.context.item.desc": "Wstaw szablon kontekstu", "promptEditor.context.item.title": "Kontekst", "promptEditor.context.modal.add": "Dodaj Kontekst ", diff --git a/web/i18n/pt-BR/common.json b/web/i18n/pt-BR/common.json index f6db3ca7af..7eb244891d 100644 --- a/web/i18n/pt-BR/common.json +++ b/web/i18n/pt-BR/common.json @@ -538,9 +538,6 @@ "placeholder.input": "Por favor, insira", "placeholder.search": "Pesquisar...", "placeholder.select": "Por favor, selecione", - "plugin.serpapi.apiKey": "Chave da API", - "plugin.serpapi.apiKeyPlaceholder": "Insira sua chave da API", - "plugin.serpapi.keyFrom": "Obtenha sua chave da SerpAPI na página da conta da SerpAPI", "promptEditor.context.item.desc": "Inserir modelo de contexto", "promptEditor.context.item.title": "Contexto", "promptEditor.context.modal.add": "Adicionar Contexto", diff --git a/web/i18n/ro-RO/common.json b/web/i18n/ro-RO/common.json index 3c2b94abcc..8b01a04a4e 100644 --- a/web/i18n/ro-RO/common.json +++ b/web/i18n/ro-RO/common.json @@ -538,9 +538,6 @@ "placeholder.input": "Vă rugăm să introduceți", "placeholder.search": "Caută...", "placeholder.select": "Vă rugăm să selectați", - "plugin.serpapi.apiKey": "Cheie API", - "plugin.serpapi.apiKeyPlaceholder": "Introduceți cheia dvs. API", - "plugin.serpapi.keyFrom": "Obțineți cheia dvs. SerpAPI din pagina contului SerpAPI", "promptEditor.context.item.desc": "Inserați șablon de context", "promptEditor.context.item.title": "Context", "promptEditor.context.modal.add": "Adăugați context ", diff --git a/web/i18n/ru-RU/common.json b/web/i18n/ru-RU/common.json index 045e4172e2..c3397212d4 100644 --- a/web/i18n/ru-RU/common.json +++ b/web/i18n/ru-RU/common.json @@ -538,9 +538,6 @@ "placeholder.input": "Пожалуйста, введите", "placeholder.search": "Поиск...", "placeholder.select": "Пожалуйста, выберите", - "plugin.serpapi.apiKey": "Ключ API", - "plugin.serpapi.apiKeyPlaceholder": "Введите свой ключ API", - "plugin.serpapi.keyFrom": "Получите свой ключ SerpAPI на странице учетной записи SerpAPI", "promptEditor.context.item.desc": "Вставить шаблон контекста", "promptEditor.context.item.title": "Контекст", "promptEditor.context.modal.add": "Добавить контекст ", diff --git a/web/i18n/sl-SI/common.json b/web/i18n/sl-SI/common.json index ff9e530be5..5e909b7ac7 100644 --- a/web/i18n/sl-SI/common.json +++ b/web/i18n/sl-SI/common.json @@ -538,9 +538,6 @@ "placeholder.input": "Vnesite prosim", "placeholder.search": "Išči...", "placeholder.select": "Izberite prosim", - "plugin.serpapi.apiKey": "API ključ", - "plugin.serpapi.apiKeyPlaceholder": "Vnesite ključ API", - "plugin.serpapi.keyFrom": "Pridobite svoj ključ SerpAPI na strani računa SerpAPI", "promptEditor.context.item.desc": "Vstavljanje predloge konteksta", "promptEditor.context.item.title": "Kontekstu", "promptEditor.context.modal.add": "Dodajanje konteksta", diff --git a/web/i18n/th-TH/common.json b/web/i18n/th-TH/common.json index 16e59dc046..de38841fa0 100644 --- a/web/i18n/th-TH/common.json +++ b/web/i18n/th-TH/common.json @@ -538,9 +538,6 @@ "placeholder.input": "กรุณากรอก", "placeholder.search": "ค้นหา...", "placeholder.select": "กรุณาเลือก", - "plugin.serpapi.apiKey": "คีย์ API", - "plugin.serpapi.apiKeyPlaceholder": "ป้อนคีย์ API ของคุณ", - "plugin.serpapi.keyFrom": "รับคีย์ SerpAPI ของคุณจากหน้าบัญชี SerpAPI", "promptEditor.context.item.desc": "แทรกเทมเพลตบริบท", "promptEditor.context.item.title": "บริบท", "promptEditor.context.modal.add": "เพิ่มบริบท", diff --git a/web/i18n/tr-TR/common.json b/web/i18n/tr-TR/common.json index 13c54be22d..7f630cc3f5 100644 --- a/web/i18n/tr-TR/common.json +++ b/web/i18n/tr-TR/common.json @@ -538,9 +538,6 @@ "placeholder.input": "Lütfen girin", "placeholder.search": "Ara...", "placeholder.select": "Lütfen seçin", - "plugin.serpapi.apiKey": "API Anahtarı", - "plugin.serpapi.apiKeyPlaceholder": "API anahtarınızı girin", - "plugin.serpapi.keyFrom": "SerpAPI Hesap Sayfasından SerpAPI anahtarınızı alın", "promptEditor.context.item.desc": "Bağlam şablonunu ekle", "promptEditor.context.item.title": "Bağlam", "promptEditor.context.modal.add": "Bağlam Ekle", diff --git a/web/i18n/uk-UA/common.json b/web/i18n/uk-UA/common.json index abaaa070d8..999319a95b 100644 --- a/web/i18n/uk-UA/common.json +++ b/web/i18n/uk-UA/common.json @@ -538,9 +538,6 @@ "placeholder.input": "Будь ласка, введіть текст", "placeholder.search": "Пошук...", "placeholder.select": "Будь ласка, оберіть параметр", - "plugin.serpapi.apiKey": "Ключ API", - "plugin.serpapi.apiKeyPlaceholder": "Введіть свій ключ API", - "plugin.serpapi.keyFrom": "Отримайте свій ключ SerpAPI зі сторінки облікового запису SerpAPI", "promptEditor.context.item.desc": "Вставити шаблон контексту", "promptEditor.context.item.title": "Контекст", "promptEditor.context.modal.add": "Додати контекст", diff --git a/web/i18n/vi-VN/common.json b/web/i18n/vi-VN/common.json index 7c5d232237..324b3c23ec 100644 --- a/web/i18n/vi-VN/common.json +++ b/web/i18n/vi-VN/common.json @@ -538,9 +538,6 @@ "placeholder.input": "Vui lòng nhập", "placeholder.search": "Tìm kiếm...", "placeholder.select": "Vui lòng chọn", - "plugin.serpapi.apiKey": "Khóa API", - "plugin.serpapi.apiKeyPlaceholder": "Nhập khóa API của bạn", - "plugin.serpapi.keyFrom": "Nhận khóa SerpAPI của bạn từ Trang tài khoản SerpAPI", "promptEditor.context.item.desc": "Chèn mẫu bối cảnh", "promptEditor.context.item.title": "Bối cảnh", "promptEditor.context.modal.add": "Thêm Bối cảnh", diff --git a/web/i18n/zh-Hans/common.json b/web/i18n/zh-Hans/common.json index a14422ba99..3b824db82f 100644 --- a/web/i18n/zh-Hans/common.json +++ b/web/i18n/zh-Hans/common.json @@ -569,9 +569,6 @@ "placeholder.input": "请输入", "placeholder.search": "搜索...", "placeholder.select": "请选择", - "plugin.serpapi.apiKey": "API Key", - "plugin.serpapi.apiKeyPlaceholder": "输入你的 API 密钥", - "plugin.serpapi.keyFrom": "从 SerpAPI 帐户页面获取您的 SerpAPI 密钥", "promptEditor.context.item.desc": "插入上下文模板", "promptEditor.context.item.title": "上下文", "promptEditor.context.modal.add": "添加上下文", diff --git a/web/i18n/zh-Hant/common.json b/web/i18n/zh-Hant/common.json index 5013c34cf7..a9835f6d14 100644 --- a/web/i18n/zh-Hant/common.json +++ b/web/i18n/zh-Hant/common.json @@ -538,9 +538,6 @@ "placeholder.input": "請輸入", "placeholder.search": "搜尋...", "placeholder.select": "請選擇", - "plugin.serpapi.apiKey": "API Key", - "plugin.serpapi.apiKeyPlaceholder": "輸入你的 API 金鑰", - "plugin.serpapi.keyFrom": "從 SerpAPI 帳戶頁面獲取您的 SerpAPI 金鑰", "promptEditor.context.item.desc": "插入上下文模板", "promptEditor.context.item.title": "上下文", "promptEditor.context.modal.add": "新增上下文", diff --git a/web/models/common.ts b/web/models/common.ts index 38105968b9..efcebcce56 100644 --- a/web/models/common.ts +++ b/web/models/common.ts @@ -159,14 +159,6 @@ export enum DataSourceProvider { waterCrawl = 'watercrawl', } -export type PluginProvider = { - tool_name: string - is_enabled: boolean - credentials: { - api_key: string - } | null -} - export type FileUploadConfigResponse = { batch_count_limit: number image_file_size_limit?: number | string // default is 10MB diff --git a/web/service/common.ts b/web/service/common.ts index 3f0ae66a9b..962d716147 100644 --- a/web/service/common.ts +++ b/web/service/common.ts @@ -25,7 +25,6 @@ import type { Member, ModerateResponse, OauthResponse, - PluginProvider, Provider, ProviderAnthropicToken, ProviderAzureToken, @@ -165,17 +164,6 @@ export const updateDataSourceNotionAction = ({ url }: { url: string }): Promise< return patch(url) } -export const fetchPluginProviders = (url: string): Promise => { - return get(url) -} - -export const validatePluginProviderKey = ({ url, body }: { url: string, body: { credentials: any } }): Promise => { - return post(url, { body }) -} -export const updatePluginProviderAIKey = ({ url, body }: { url: string, body: { credentials: any } }): Promise => { - return post(url, { body }) -} - export const invitationCheck = ({ url, params }: { url: string, params: { workspace_id?: string, email?: string, token: string } }): Promise => { return get(url, { params }) } diff --git a/web/service/use-common.ts b/web/service/use-common.ts index 503bfa7a62..73193f4d77 100644 --- a/web/service/use-common.ts +++ b/web/service/use-common.ts @@ -14,7 +14,6 @@ import type { IWorkspace, LangGeniusVersionResponse, Member, - PluginProvider, StructuredOutputRulesRequestBody, StructuredOutputRulesResponse, UserProfileResponse, @@ -49,7 +48,6 @@ export const commonQueryKeys = { defaultModel: (type: ModelTypeEnum) => [NAME_SPACE, 'default-model', type] as const, retrievalMethods: [NAME_SPACE, 'support-retrieval-methods'] as const, accountIntegrates: [NAME_SPACE, 'account-integrates'] as const, - pluginProviders: [NAME_SPACE, 'plugin-providers'] as const, notionConnection: [NAME_SPACE, 'notion-connection'] as const, codeBasedExtensions: (module?: string) => [NAME_SPACE, 'code-based-extensions', module] as const, invitationCheck: (params?: { workspace_id?: string, email?: string, token?: string }) => [ @@ -303,13 +301,6 @@ export const useAccountIntegrates = () => { }) } -export const usePluginProviders = () => { - return useQuery({ - queryKey: commonQueryKeys.pluginProviders, - queryFn: () => get('/workspaces/current/tool-providers'), - }) -} - export const useCodeBasedExtensions = (module: string) => { return useQuery({ queryKey: commonQueryKeys.codeBasedExtensions(module),