diff --git a/aperag/api/components/schemas/model.yaml b/aperag/api/components/schemas/model.yaml index e30e205cd..e1ab830ba 100644 --- a/aperag/api/components/schemas/model.yaml +++ b/aperag/api/components/schemas/model.yaml @@ -114,4 +114,19 @@ availableEmbeddingList: type: array items: $ref: '#/availableEmbedding' - \ No newline at end of file + +availableModel: + type: object + properties: + model_service_provider: + type: string + model_name: + type: string + +availableModelList: + type: object + properties: + items: + type: array + items: + $ref: '#/availableModel' diff --git a/aperag/api/openapi.yaml b/aperag/api/openapi.yaml index 574eef4f3..16a244e0b 100644 --- a/aperag/api/openapi.yaml +++ b/aperag/api/openapi.yaml @@ -71,6 +71,8 @@ paths: $ref: './paths/models.yaml#/modelServiceProvider' /available_embeddings: $ref: './paths/models.yaml#/availableEmbeddings' + /available_models: + $ref: './paths/models.yaml#/availableModels' # config diff --git a/aperag/api/paths/models.yaml b/aperag/api/paths/models.yaml index d04b33653..b74f7d701 100644 --- a/aperag/api/paths/models.yaml +++ b/aperag/api/paths/models.yaml @@ -34,6 +34,24 @@ availableEmbeddings: schema: $ref: '../components/schemas/common.yaml#/failResponse' +availableModels: + get: + summary: Get available models + description: Get available models + responses: + '200': + description: Available models + content: + application/json: + schema: + $ref: '../components/schemas/model.yaml#/availableModelList' + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: '../components/schemas/common.yaml#/failResponse' + modelServiceProvider: put: summary: Update model service provider diff --git a/aperag/embed/base_embedding.py b/aperag/embed/base_embedding.py index 2aa33ba09..2311ba56c 100644 --- a/aperag/embed/base_embedding.py +++ b/aperag/embed/base_embedding.py @@ -28,7 +28,6 @@ def wrapper(*args, **kwargs): return wrapper - _dimension_cache: dict[tuple[str, str], int] = {} diff --git a/aperag/embed/embedding_service.py b/aperag/embed/embedding_service.py index c4e33cf1b..ca7510c5f 100644 --- a/aperag/embed/embedding_service.py +++ b/aperag/embed/embedding_service.py @@ -57,9 +57,6 @@ def embed_query(self, text: str) -> List[float]: reraise=True, ) def _embed_batch(self, batch: Sequence[str]) -> List[List[float]]: - """ - 单个 batch 的真正请求;加 tenacity 保证稳一点。 - """ response = litellm.embedding( model=self.model, api_base=self.api_base, diff --git a/aperag/graph/lightrag_holder.py b/aperag/graph/lightrag_holder.py index 120bdd25e..020165abf 100644 --- a/aperag/graph/lightrag_holder.py +++ b/aperag/graph/lightrag_holder.py @@ -2,6 +2,7 @@ import logging from typing import Optional, List, Dict, Callable, Awaitable, Tuple, AsyncIterator, Any +import json import numpy from lightrag import LightRAG, QueryParam from lightrag.kg.shared_storage import initialize_pipeline_status @@ -10,6 +11,9 @@ from lightrag.base import DocStatus from aperag.db.models import Collection +from aperag.db.ops import ( + query_msp_dict, +) from aperag.embed.base_embedding import get_collection_embedding_model from aperag.utils.utils import generate_lightrag_namespace_prefix from config.settings import ( @@ -72,24 +76,40 @@ async def adelete_by_doc_id(self, doc_id: str) -> None: # ---------- Default llm_func & embed_impl ---------- # -async def _default_llm_func( - prompt: str, - system_prompt: Optional[str] = None, - history_messages: List = [], - **kwargs, -) -> str: - merged_kwargs = { - "api_key": LLM_API_KEY, - "base_url": LLM_BASE_URL, - "model": LLM_MODEL, - **kwargs, - } - return await openai_complete_if_cache( - prompt=prompt, - system_prompt=system_prompt, - history_messages=history_messages, - **merged_kwargs, - ) +async def gen_lightrag_llm_func(collection: Collection) -> Callable[..., Awaitable[str]]: + config = json.loads(collection.config) + lightrag_backend = config.get("lightrag_model_service_provider", "") + lightrag_model_name = config.get("lightrag_model_name", "") + logging.info("gen_lightrag_llm_func %s %s", lightrag_backend, lightrag_model_name) + + msp_dict = await query_msp_dict(collection.user) + if lightrag_backend in msp_dict: + msp = msp_dict[lightrag_backend] + lightrag_model_service_url = msp.base_url + lightrag_model_service_api_key = msp.api_key + logging.info("gen_lightrag_llm_func %s %s", lightrag_model_service_url, lightrag_model_service_api_key) + + async def lightrag_llm_func( + prompt: str, + system_prompt: Optional[str] = None, + history_messages: List = [], + **kwargs, + ) -> str: + merged_kwargs = { + "api_key": lightrag_model_service_api_key, + "base_url": lightrag_model_service_url, + "model": lightrag_model_name, + **kwargs, + } + return await openai_complete_if_cache( + prompt=prompt, + system_prompt=system_prompt, + history_messages=history_messages, + **merged_kwargs, + ) + return lightrag_llm_func + + return None # Module-level cache _lightrag_instances: Dict[str, LightRagHolder] = {} @@ -145,9 +165,9 @@ async def lightrag_embed_func(texts: list[str]) -> numpy.ndarray: return lightrag_embed_func, dim async def get_lightrag_holder( - collection: Collection, - llm_func: Callable[..., Awaitable[str]] = _default_llm_func, + collection: Collection ) -> LightRagHolder: + # Fixme: if lightrag_model changes, we need to re-initialize the lightrag instance namespace_prefix: str = generate_lightrag_namespace_prefix(collection.id) if not namespace_prefix or not isinstance(namespace_prefix, str): raise ValueError("A valid namespace_prefix string must be provided.") @@ -162,6 +182,7 @@ async def get_lightrag_holder( logger.info(f"Initializing LightRAG instance for namespace '{namespace_prefix}' (lazy loading)...") try: embed_func, dim = await gen_lightrag_embed_func(collection=collection) + llm_func = await gen_lightrag_llm_func(collection=collection) client = await _create_and_initialize_lightrag(namespace_prefix, llm_func, embed_func, embed_dim=dim) _lightrag_instances[namespace_prefix] = client logger.info(f"LightRAG instance for namespace '{namespace_prefix}' initialized successfully.") diff --git a/aperag/tasks/index.py b/aperag/tasks/index.py index 70578f53b..e1f7be1c4 100644 --- a/aperag/tasks/index.py +++ b/aperag/tasks/index.py @@ -243,8 +243,8 @@ def add_index_for_document(self, document_id): } document.relate_ids = json.dumps(relate_ids) - enable_light_rag = config.get("enable_light_rag", True) - if enable_light_rag: + enable_lightrag = config.get("enable_lightrag", True) + if enable_lightrag: add_lightrag_index(content, document, local_doc) except FeishuNoPermission: @@ -355,8 +355,8 @@ def update_index_for_document(self, document_id): document.relate_ids = json.dumps(relate_ids) logger.info(f"update qdrant points: {document.relate_ids} for document {local_doc.path}") - enable_light_rag = config.get("enable_light_rag", True) - if enable_light_rag: + enable_lightrag = config.get("enable_lightrag", True) + if enable_lightrag: add_lightrag_index(content, document, local_doc) except FeishuNoPermission: diff --git a/aperag/views/main.py b/aperag/views/main.py index 4e658bc73..57359765e 100644 --- a/aperag/views/main.py +++ b/aperag/views/main.py @@ -1157,6 +1157,25 @@ async def list_available_embeddings(request) -> view_models.AvailableEmbeddingLi return success(view_models.AvailableEmbeddingList( items=response,)) + +@router.get("/available_models") +async def list_available_models(request) -> view_models.AvailableModelList: + user = get_user(request) + supported_msp_dict = {supported_msp["name"]: supported_msp for supported_msp in settings.SUPPORTED_MODEL_SERVICE_PROVIDERS} + msp_list = await query_msp_list(user) + logger.info(msp_list) + response = [] + for msp in msp_list: + if msp.name in supported_msp_dict: + supported_msp = supported_msp_dict[msp.name] + for model in supported_msp.get("models", []): + response.append(view_models.AvailableModel( + model_service_provider=msp.name, + model_name=model, + )) + return success(view_models.AvailableModelList( items=response,)) + + def default_page(request, exception): return render(request, '404.html') diff --git a/aperag/views/models.py b/aperag/views/models.py index 34d29a61b..19d7eafe5 100644 --- a/aperag/views/models.py +++ b/aperag/views/models.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: openapi.merged.yaml -# timestamp: 2025-04-26T07:25:07+00:00 +# timestamp: 2025-04-27T06:17:52+00:00 from __future__ import annotations @@ -391,6 +391,15 @@ class AvailableEmbeddingList(BaseModel): items: Optional[list[AvailableEmbedding]] = None +class AvailableModel(BaseModel): + model_service_provider: Optional[str] = None + model_name: Optional[str] = None + + +class AvailableModelList(BaseModel): + items: Optional[list[AvailableModel]] = None + + class Auth0(BaseModel): auth_domain: Optional[str] = None auth_app_id: Optional[str] = None diff --git a/config/settings.py b/config/settings.py index 8e98cc453..9bb803aec 100644 --- a/config/settings.py +++ b/config/settings.py @@ -258,6 +258,18 @@ "text-embedding-3-small", "text-embedding-3-large", "text-embedding-ada-002", + ], + "models": [ + "gpt-3.5-turbo", + "gpt-4", + "gpt-4-turbo", + "gpt-4o-mini", + "gpt-4o", + "o1", + "o1-mini", + "o3", + "o3-mini", + "o4-mini", ] }, { @@ -269,13 +281,31 @@ "text-embedding-v1", "text-embedding-v2", "text-embedding-v3", + ], + "models": [ + "deepseek-r1", + "deepseek-v3", + "qwen-max", + "qwen-long", + "qwen-plus", + "qwen-plus-latest", + "qwen-turbo", + "qwq-32b", + "qwq-plus", + "qwq-plus-latest", + "qwen-vl-max", + "qwen-vl-plus" ] }, { "name": "deepseek", "label": "DeepSeek", "allow_custom_base_url": False, - "base_url": "https://api.deepseek.com/v1" + "base_url": "https://api.deepseek.com/v1", + "models": [ + "deepseek-r1", + "deepseek-v3" + ] }, { "name": "siliconflow", @@ -286,6 +316,11 @@ "BAAI/bge-large-en-v1.5", "BAAI/bge-large-zh-v1.5", "BAAI/bge-m3", + ], + "models": [ + "Qwen/QwQ-32B", + "deepseek-ai/Deepseek-R1", + "deepseek-ai/Deepseek-V3", ] }, ] diff --git a/envs/env.template b/envs/env.template index 13730ed8e..1a5918d66 100644 --- a/envs/env.template +++ b/envs/env.template @@ -72,11 +72,7 @@ CHAT_CONSUMER_IMPLEMENTATION=document-qa # RETRIEVE_MODE is one of: classic, graph, mix RETRIEVE_MODE=classic -# --- LLM Settings --- -LIGHT_RAG_LLM_API_KEY= -LIGHT_RAG_LLM_BASE_URL= -LIGHT_RAG_LLM_MODEL= -# --- General Settings --- +# --- LIGHT RAG General Settings --- LIGHT_RAG_WORKING_DIR= LIGHT_RAG_ENABLE_LLM_CACHE= LIGHT_RAG_MAX_PARALLEL_INSERT= diff --git a/frontend/src/api/apis/default-api.ts b/frontend/src/api/apis/default-api.ts index afd922de3..11363e633 100644 --- a/frontend/src/api/apis/default-api.ts +++ b/frontend/src/api/apis/default-api.ts @@ -28,6 +28,8 @@ import type { ApiKeyList } from '../models'; // @ts-ignore import type { AvailableEmbeddingList } from '../models'; // @ts-ignore +import type { AvailableModelList } from '../models'; +// @ts-ignore import type { Bot } from '../models'; // @ts-ignore import type { BotCreate } from '../models'; @@ -228,6 +230,36 @@ export const DefaultApiAxiosParamCreator = function (configuration?: Configurati + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * Get available models + * @summary Get available models + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + availableModelsGet: async (options: RawAxiosRequestConfig = {}): Promise => { + const localVarPath = `/available_models`; + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + + setSearchParams(localVarUrlObj, localVarQueryParameter); let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; @@ -2134,6 +2166,18 @@ export const DefaultApiFp = function(configuration?: Configuration) { const localVarOperationServerBasePath = operationServerMap['DefaultApi.availableEmbeddingsGet']?.[localVarOperationServerIndex]?.url; return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); }, + /** + * Get available models + * @summary Get available models + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async availableModelsGet(options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.availableModelsGet(options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['DefaultApi.availableModelsGet']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, /** * Delete a chat * @summary Delete a chat @@ -2816,6 +2860,15 @@ export const DefaultApiFactory = function (configuration?: Configuration, basePa availableEmbeddingsGet(options?: RawAxiosRequestConfig): AxiosPromise { return localVarFp.availableEmbeddingsGet(options).then((request) => request(axios, basePath)); }, + /** + * Get available models + * @summary Get available models + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + availableModelsGet(options?: RawAxiosRequestConfig): AxiosPromise { + return localVarFp.availableModelsGet(options).then((request) => request(axios, basePath)); + }, /** * Delete a chat * @summary Delete a chat @@ -3323,6 +3376,15 @@ export interface DefaultApiInterface { */ availableEmbeddingsGet(options?: RawAxiosRequestConfig): AxiosPromise; + /** + * Get available models + * @summary Get available models + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof DefaultApiInterface + */ + availableModelsGet(options?: RawAxiosRequestConfig): AxiosPromise; + /** * Delete a chat * @summary Delete a chat @@ -4615,6 +4677,17 @@ export class DefaultApi extends BaseAPI implements DefaultApiInterface { return DefaultApiFp(this.configuration).availableEmbeddingsGet(options).then((request) => request(this.axios, this.basePath)); } + /** + * Get available models + * @summary Get available models + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof DefaultApi + */ + public availableModelsGet(options?: RawAxiosRequestConfig) { + return DefaultApiFp(this.configuration).availableModelsGet(options).then((request) => request(this.axios, this.basePath)); + } + /** * Delete a chat * @summary Delete a chat diff --git a/frontend/src/api/models/available-model-list.ts b/frontend/src/api/models/available-model-list.ts new file mode 100644 index 000000000..2478eafee --- /dev/null +++ b/frontend/src/api/models/available-model-list.ts @@ -0,0 +1,33 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * ApeRAG API + * ApeRAG API Documentation + * + * The version of the OpenAPI document: 1.0.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +// May contain unused imports in some cases +// @ts-ignore +import type { AvailableModel } from './available-model'; + +/** + * + * @export + * @interface AvailableModelList + */ +export interface AvailableModelList { + /** + * + * @type {Array} + * @memberof AvailableModelList + */ + 'items'?: Array; +} + diff --git a/frontend/src/api/models/available-model.ts b/frontend/src/api/models/available-model.ts new file mode 100644 index 000000000..7b10d2d1c --- /dev/null +++ b/frontend/src/api/models/available-model.ts @@ -0,0 +1,36 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * ApeRAG API + * ApeRAG API Documentation + * + * The version of the OpenAPI document: 1.0.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + + +/** + * + * @export + * @interface AvailableModel + */ +export interface AvailableModel { + /** + * + * @type {string} + * @memberof AvailableModel + */ + 'model_service_provider'?: string; + /** + * + * @type {string} + * @memberof AvailableModel + */ + 'model_name'?: string; +} + diff --git a/frontend/src/api/models/index.ts b/frontend/src/api/models/index.ts index 129f9c039..a4c241187 100644 --- a/frontend/src/api/models/index.ts +++ b/frontend/src/api/models/index.ts @@ -2,6 +2,8 @@ export * from './api-key'; export * from './api-key-list'; export * from './available-embedding'; export * from './available-embedding-list'; +export * from './available-model'; +export * from './available-model-list'; export * from './bot'; export * from './bot-create'; export * from './bot-list'; diff --git a/frontend/src/api/openapi.merged.yaml b/frontend/src/api/openapi.merged.yaml index 562d00953..df49bdea4 100644 --- a/frontend/src/api/openapi.merged.yaml +++ b/frontend/src/api/openapi.merged.yaml @@ -1052,6 +1052,23 @@ paths: application/json: schema: $ref: '#/components/schemas/failResponse' + /available_models: + get: + summary: Get available models + description: Get available models + responses: + '200': + description: Available models + content: + application/json: + schema: + $ref: '#/components/schemas/availableModelList' + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/failResponse' /config: get: summary: Get system configuration @@ -1894,6 +1911,20 @@ components: type: array items: $ref: '#/components/schemas/availableEmbedding' + availableModel: + type: object + properties: + model_service_provider: + type: string + model_name: + type: string + availableModelList: + type: object + properties: + items: + type: array + items: + $ref: '#/components/schemas/availableModel' config: type: object properties: diff --git a/frontend/src/locales/en-US/collection.ts b/frontend/src/locales/en-US/collection.ts index 2aff02f0d..dbb4c439d 100644 --- a/frontend/src/locales/en-US/collection.ts +++ b/frontend/src/locales/en-US/collection.ts @@ -35,9 +35,13 @@ export const collection = { 'collection.delete': 'Delete collection', 'collection.delete.confirm': 'The collection "{name}" will be deleted, confirm the current operation.', - 'collection.enable_light_rag': 'Enable Light RAG', + 'collection.enable_lightrag': 'Enable Light RAG', 'collection.embedding_model': 'Embedding Model', 'collection.embedding_model_not_found': 'Please set the API Key in Settings -> Model Provider', 'collection.embedding_model.required': 'Embedding Model is required', + 'collection.lightrag_model': 'Light RAG Model', + 'collection.lightrag_model_not_found': + 'Please set the API Key in Settings -> Model Provider', + 'collection.lightrag_model.required': 'Light RAG Model is required', }; diff --git a/frontend/src/locales/zh-CN/collection.ts b/frontend/src/locales/zh-CN/collection.ts index 20fff099b..ad46cff28 100644 --- a/frontend/src/locales/zh-CN/collection.ts +++ b/frontend/src/locales/zh-CN/collection.ts @@ -32,8 +32,11 @@ export const collection = { 'collection.status.DELETING': '删除中', 'collection.delete': '删除知识库', 'collection.delete.confirm': '知识库 "{name}" 将会被删除,确定此操作吗?', - 'collection.enable_light_rag': '启用Light RAG', + 'collection.enable_lightrag': '启用Light RAG', 'collection.embedding_model': '嵌入模型', 'collection.embedding_model_not_found': '请在设置 -> 模型服务商中设置API Key', 'collection.embedding_model.required': '请选择嵌入模型', + 'collection.lightrag_model': 'Light RAG模型', + 'collection.lightrag_model_not_found': '请在设置 -> 模型服务商中设置API Key', + 'collection.lightrag_model.required': '请选择Light RAG模型', }; diff --git a/frontend/src/pages/collections/_form/index.tsx b/frontend/src/pages/collections/_form/index.tsx index 69aedd3da..8e28c9e1c 100644 --- a/frontend/src/pages/collections/_form/index.tsx +++ b/frontend/src/pages/collections/_form/index.tsx @@ -1,4 +1,4 @@ -import { AvailableEmbedding, SupportedModelServiceProvider } from '@/api'; +import { AvailableEmbedding, AvailableModel, SupportedModelServiceProvider } from '@/api'; import { ApeMarkdown, CheckCard } from '@/components'; import { COLLECTION_SOURCE, @@ -56,6 +56,8 @@ export default ({ onSubmit, action, values, form }: Props) => { const [availableEmbeddings, setAvailableEmbeddings] = useState(); + const [availableModels, setAvailableModels] = + useState(); const [supportedModelServiceProviders, setSupportedModelServiceProviders] = useState(); @@ -66,16 +68,20 @@ export default ({ onSubmit, action, values, form }: Props) => { ); const sensitiveProtect = Form.useWatch(['config', 'sensitive_protect'], form); const embeddingModel = Form.useWatch(['config', 'embedding_model'], form); + const enableLightRAG = Form.useWatch(['config', 'enable_lightrag'], form); + const lightRAGModel = Form.useWatch(['config', 'lightrag_model'], form); - const getEmbeddings = async () => { + const getEmbeddingsAndModels = async () => { setLoading(true); - const [availableEmbeddingsRes, supportedModelServiceProvidersRes] = + const [availableEmbeddingsRes, availableModelsRes, supportedModelServiceProvidersRes] = await Promise.all([ api.availableEmbeddingsGet(), + api.availableModelsGet(), api.supportedModelServiceProvidersGet(), ]); setLoading(false); setAvailableEmbeddings(availableEmbeddingsRes.data.items); + setAvailableModels(availableModelsRes.data.items); setSupportedModelServiceProviders( supportedModelServiceProvidersRes.data.items, ); @@ -112,6 +118,38 @@ export default ({ onSubmit, action, values, form }: Props) => { [availableEmbeddings, supportedModelServiceProviders], ); + + const modelsOptions = useMemo( + () => + _.map( + _.groupBy(availableModels, 'model_service_provider'), + (aebs, providerName) => { + const provider = supportedModelServiceProviders?.find( + (smp) => smp.name === providerName, + ); + return { + label: ( + + + {provider?.label || providerName} + + ), + options: aebs.map((aeb) => { + return { + label: aeb.model_name, + value: `${providerName}:${aeb.model_name}`, + }; + }), + }; + }, + ), + [availableModels, supportedModelServiceProviders], + ); + const onFinish = async () => { const data = await form.validateFields(); onSubmit(data); @@ -129,6 +167,18 @@ export default ({ onSubmit, action, values, form }: Props) => { } }, [embeddingModel]); + + useEffect(() => { + if (lightRAGModel) { + const [model_service_provider, model_name] = lightRAGModel.split(':'); + form.setFieldValue( + ['config', 'lightrag_model_service_provider'], + model_service_provider, + ); + form.setFieldValue(['config', 'lightrag_model_name'], model_name); + } + }, [lightRAGModel]); + useEffect(() => { if (source === 'ftp') { form.setFieldValue(['config', 'port'], 21); @@ -150,7 +200,7 @@ export default ({ onSubmit, action, values, form }: Props) => { }, [source, emailSource]); useEffect(() => { - getEmbeddings(); + getEmbeddingsAndModels(); }, []); return ( @@ -208,6 +258,7 @@ export default ({ onSubmit, action, values, form }: Props) => { > { + const [model_service_provider, model_name] = ( + value as string + ).split(':'); + return ( + + + {label || model_name} + + ); + }} + notFoundContent={ + + + + + + + } + /> + + + + + ) : null } +