From 0e1e1e7cd120fce59cf9844323444be5e810b002 Mon Sep 17 00:00:00 2001 From: maninhill <41712985+maninhill@users.noreply.github.com> Date: Sun, 24 Aug 2025 11:47:32 +0800 Subject: [PATCH 0001/1125] chore: update README --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index eadda3542..117b845fc 100644 --- a/README.md +++ b/README.md @@ -45,8 +45,7 @@ docker compose up -d 如你有更多问题,可以加入我们的技术交流群与我们交流。 -contact_me_qr - +contact_me_qr ## UI 展示 From 2d181c489241c1c5b63558fa322fa3ff96366403 Mon Sep 17 00:00:00 2001 From: dataeaseShu Date: Mon, 25 Aug 2025 10:36:26 +0800 Subject: [PATCH 0002/1125] fix(System-Appearance Settings): Optimize rounded corners to 6px --- frontend/src/api/embedded.ts | 2 +- .../{assistant.vue => AssistantPreview.vue} | 0 .../views/system/appearance/LoginPreview.vue | 2 +- .../src/views/system/appearance/index.vue | 2 + frontend/src/views/system/embedded/Page.vue | 48 ++++++++++++------- frontend/src/views/system/embedded/SetUi.vue | 2 +- frontend/src/views/system/user/User.vue | 5 +- 7 files changed, 38 insertions(+), 23 deletions(-) rename frontend/src/views/embedded/{assistant.vue => AssistantPreview.vue} (100%) diff --git a/frontend/src/api/embedded.ts b/frontend/src/api/embedded.ts index 20803106a..05ca09a80 100644 --- a/frontend/src/api/embedded.ts +++ b/frontend/src/api/embedded.ts @@ -14,6 +14,6 @@ export const embeddedApi = { }), updateEmbedded: (data: any) => request.put('/system/embedded', data), addEmbedded: (data: any) => request.post('/system/embedded', data), - deleteEmbedded: (data: any) => request.delete('/system/embedded', data), + deleteEmbedded: (params: any) => request.delete('/system/embedded', { data: params }), getOne: (id: any) => request.get(`/system/embedded/${id}`), } diff --git a/frontend/src/views/embedded/assistant.vue b/frontend/src/views/embedded/AssistantPreview.vue similarity index 100% rename from frontend/src/views/embedded/assistant.vue rename to frontend/src/views/embedded/AssistantPreview.vue diff --git a/frontend/src/views/system/appearance/LoginPreview.vue b/frontend/src/views/system/appearance/LoginPreview.vue index 23a829279..a34746c0e 100644 --- a/frontend/src/views/system/appearance/LoginPreview.vue +++ b/frontend/src/views/system/appearance/LoginPreview.vue @@ -232,7 +232,7 @@ onMounted(() => { } .login-container { - height: calc(100% - 24px); + height: calc(100% - 22px); width: 100%; display: flex; .left-img { diff --git a/frontend/src/views/system/appearance/index.vue b/frontend/src/views/system/appearance/index.vue index 0bed44ecf..18e8201e8 100644 --- a/frontend/src/views/system/appearance/index.vue +++ b/frontend/src/views/system/appearance/index.vue @@ -809,6 +809,8 @@ onUnmounted(() => { .navigate-preview { height: calc(100% - 28px); background-color: #fff; + border-radius: 6px; + overflow: hidden; .navigate-head { width: 240px; diff --git a/frontend/src/views/system/embedded/Page.vue b/frontend/src/views/system/embedded/Page.vue index 0387f9519..a1252bbc4 100644 --- a/frontend/src/views/system/embedded/Page.vue +++ b/frontend/src/views/system/embedded/Page.vue @@ -22,6 +22,15 @@ defineProps({ }, }) +interface Form { + id?: string | null + name: string | null + domain: string | null + type: number + configuration?: string | null + description?: string | null +} + const emits = defineEmits(['btnSelectChange']) const { t } = useI18n() const multipleSelectionAll = ref([]) @@ -45,6 +54,19 @@ const pageInfo = reactive({ total: 0, }) +const pwd = '**********' + +const dialogTitle = ref('') +const defaultForm = { + id: null, + name: null, + domain: null, + type: 4, + // configuration: null, + // description: null, +} +const pageForm = ref
(cloneDeep(defaultForm)) + const cancelDelete = () => { handleToggleRowSelection(false) multipleSelectionAll.value = [] @@ -54,7 +76,7 @@ const cancelDelete = () => { const deleteBatchUser = () => { ElMessageBox.confirm(t('embedded.delete_10_apps', { msg: multipleSelectionAll.value.length }), { confirmButtonType: 'danger', - confirmButtonText: t('dashboard.delete_success'), + confirmButtonText: t('dashboard.delete'), cancelButtonText: t('common.cancel'), customClass: 'confirm-no_icon', autofocus: false, @@ -72,7 +94,7 @@ const deleteBatchUser = () => { const deleteHandler = (row: any) => { ElMessageBox.confirm(t('embedded.delete', { msg: row.name }), { confirmButtonType: 'danger', - confirmButtonText: t('dashboard.delete_success'), + confirmButtonText: t('dashboard.delete'), cancelButtonText: t('common.cancel'), customClass: 'confirm-no_icon', autofocus: false, @@ -187,30 +209,22 @@ const rules = { const saveHandler = () => { termFormRef.value.validate((res: any) => { if (res) { - embeddedApi.addEmbedded(unref(pageForm)).then(() => { + const obj = unref(pageForm) + if (obj.id === '') { + delete obj.id + } + embeddedApi.addEmbedded(obj).then(() => { ElMessage({ type: 'success', message: t('common.save_success'), }) search() - dialogFormVisible.value = false + onFormClose() }) } }) } -const pwd = '**********' - -const dialogTitle = ref('') -const defaultForm = { - id: null, - name: null, - domain: null, - type: 0, - configuration: null, - description: null, -} -const pageForm = ref(cloneDeep(defaultForm)) const editHandler = (row: any) => { pageForm.value.id = null if (row) { @@ -505,7 +519,7 @@ const copyCode = (row: any, key: any = 'app_secret') => { {{ $t('datasource.select_all') }} - + {{ $t('user.selected_2_items', { msg: multipleSelectionAll.length }) diff --git a/frontend/src/views/system/embedded/SetUi.vue b/frontend/src/views/system/embedded/SetUi.vue index 35b72beb2..979977532 100644 --- a/frontend/src/views/system/embedded/SetUi.vue +++ b/frontend/src/views/system/embedded/SetUi.vue @@ -1,5 +1,5 @@ + + + + + From 5e591e462de062f85a9d1cd59fcc91a1b74bb9df Mon Sep 17 00:00:00 2001 From: dataeaseShu Date: Mon, 25 Aug 2025 16:23:11 +0800 Subject: [PATCH 0006/1125] feat: Terminology Management --- frontend/src/views/system/professional/index.vue | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/frontend/src/views/system/professional/index.vue b/frontend/src/views/system/professional/index.vue index a8f212753..71bcc470e 100644 --- a/frontend/src/views/system/professional/index.vue +++ b/frontend/src/views/system/professional/index.vue @@ -22,7 +22,8 @@ defineProps({ interface Form { id?: string | null word: string | null - other_words?: string[] | null + other_words: string[] + description: string | null } const { t } = useI18n() @@ -51,6 +52,7 @@ const dialogTitle = ref('') const defaultForm = { id: null, word: null, + description: null, other_words: [], } const pageForm = ref(cloneDeep(defaultForm)) @@ -537,13 +539,7 @@ const deleteHandlerItem = (idx: number) => { :before-close="onRowFormClose" modal-class="professional-term_drawer" > - +
{{ pageForm.word }} From 393fd8c5b5b94604256dc0cc1411b503f521df71 Mon Sep 17 00:00:00 2001 From: ulleo Date: Mon, 25 Aug 2025 16:34:44 +0800 Subject: [PATCH 0007/1125] feat: add terminology management --- backend/alembic/env.py | 3 +- .../versions/039_create_terminology.py | 41 ++++ backend/apps/ai_model/embedding.py | 59 ++++++ backend/apps/api.py | 3 +- backend/apps/terminology/__init__.py | 0 backend/apps/terminology/api/__init__.py | 0 backend/apps/terminology/api/terminology.py | 37 ++++ backend/apps/terminology/curd/__init__.py | 0 backend/apps/terminology/curd/terminology.py | 196 ++++++++++++++++++ backend/apps/terminology/models/__init__.py | 0 .../terminology/models/terminology_model.py | 27 +++ backend/common/core/config.py | 21 +- backend/pyproject.toml | 2 + frontend/src/i18n/en.json | 2 +- frontend/src/i18n/zh-CN.json | 2 +- .../src/views/system/professional/index.vue | 2 +- 16 files changed, 383 insertions(+), 12 deletions(-) create mode 100644 backend/alembic/versions/039_create_terminology.py create mode 100644 backend/apps/ai_model/embedding.py create mode 100644 backend/apps/terminology/__init__.py create mode 100644 backend/apps/terminology/api/__init__.py create mode 100644 backend/apps/terminology/api/terminology.py create mode 100644 backend/apps/terminology/curd/__init__.py create mode 100644 backend/apps/terminology/curd/terminology.py create mode 100644 backend/apps/terminology/models/__init__.py create mode 100644 backend/apps/terminology/models/terminology_model.py diff --git a/backend/alembic/env.py b/backend/alembic/env.py index db6e94130..3f72963ae 100755 --- a/backend/alembic/env.py +++ b/backend/alembic/env.py @@ -24,7 +24,8 @@ # from apps.system.models.user import SQLModel # noqa # from apps.settings.models.setting_models import SQLModel -from apps.chat.models.chat_model import SQLModel +# from apps.chat.models.chat_model import SQLModel +from apps.terminology.models.terminology_model import SQLModel # from apps.dashboard.models.dashboard_model import SQLModel from common.core.config import settings # noqa diff --git a/backend/alembic/versions/039_create_terminology.py b/backend/alembic/versions/039_create_terminology.py new file mode 100644 index 000000000..42ab588b5 --- /dev/null +++ b/backend/alembic/versions/039_create_terminology.py @@ -0,0 +1,41 @@ +"""039_create_terminology + +Revision ID: 25cbc85766fd +Revises: fc23c4f3e755 +Create Date: 2025-08-25 11:38:32.990973 + +""" +from alembic import op +import sqlalchemy as sa +import sqlmodel.sql.sqltypes +import pgvector +from sqlalchemy.dialects import postgresql + +# revision identifiers, used by Alembic. +revision = '25cbc85766fd' +down_revision = 'fc23c4f3e755' +branch_labels = None +depends_on = None + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.execute("CREATE EXTENSION IF NOT EXISTS vector;") + + op.create_table('terminology', + sa.Column('id', sa.BigInteger(), sa.Identity(always=True), nullable=False), + sa.Column('pid', sa.BigInteger(), nullable=True), + sa.Column('create_time', sa.DateTime(), nullable=True), + sa.Column('word', sqlmodel.sql.sqltypes.AutoString(length=255), nullable=True), + sa.Column('description', sa.Text(), nullable=True), + sa.Column('embedding', pgvector.sqlalchemy.vector.VECTOR(), nullable=True), + sa.PrimaryKeyConstraint('id') + ) + + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.drop_table('terminology') + # ### end Alembic commands ### diff --git a/backend/apps/ai_model/embedding.py b/backend/apps/ai_model/embedding.py new file mode 100644 index 000000000..dea3ffbe8 --- /dev/null +++ b/backend/apps/ai_model/embedding.py @@ -0,0 +1,59 @@ +import threading +from typing import Optional + +from langchain_core.embeddings import Embeddings +from langchain_huggingface import HuggingFaceEmbeddings +from pydantic import BaseModel + +from common.core.config import settings + + +class EmbeddingModelInfo(BaseModel): + folder: str + name: str + device: str = 'cpu' + + +local_embedding_model = EmbeddingModelInfo(folder=settings.LOCAL_MODEL_PATH, name=settings.DEFAULT_EMBEDDING_MODEL) + +_lock = threading.Lock() +locks = {} + +_embedding_model: dict[str, Optional[Embeddings]] = {} + + +class EmbeddingModelCache: + + @staticmethod + def _new_instance(config: EmbeddingModelInfo = local_embedding_model): + return HuggingFaceEmbeddings(model_name=config.name, cache_folder=config.folder, + model_kwargs={'device': config.device}, + encode_kwargs={'normalize_embeddings': True} + ) + + @staticmethod + def _get_lock(key: str = settings.DEFAULT_EMBEDDING_MODEL): + lock = locks.get(key) + if lock is None: + with _lock: + lock = locks.get(key) + if lock is None: + lock = threading.Lock() + locks[key] = lock + + return lock + + @staticmethod + def get_model(key: str = settings.DEFAULT_EMBEDDING_MODEL, + config: EmbeddingModelInfo = local_embedding_model) -> Embeddings: + global _embedding_model + model_instance = _embedding_model.get(key) + if model_instance is None: + lock = EmbeddingModelCache._get_lock(key) + with lock: + model_instance = _embedding_model.get(key) + if model_instance is None: + model_instance = EmbeddingModelCache._new_instance(config) + _embedding_model[key] = model_instance + + return model_instance diff --git a/backend/apps/api.py b/backend/apps/api.py index 4f573134b..14b07cea2 100644 --- a/backend/apps/api.py +++ b/backend/apps/api.py @@ -1,9 +1,9 @@ from fastapi import APIRouter +from apps.terminology.api import terminology from apps.chat.api import chat from apps.dashboard.api import dashboard_api from apps.datasource.api import datasource -from apps.settings.api import terminology from apps.system.api import login, user, aimodel, workspace, assistant from apps.mcp import mcp @@ -19,3 +19,4 @@ api_router.include_router(dashboard_api.router) api_router.include_router(mcp.router) + diff --git a/backend/apps/terminology/__init__.py b/backend/apps/terminology/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/backend/apps/terminology/api/__init__.py b/backend/apps/terminology/api/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/backend/apps/terminology/api/terminology.py b/backend/apps/terminology/api/terminology.py new file mode 100644 index 000000000..2467db3aa --- /dev/null +++ b/backend/apps/terminology/api/terminology.py @@ -0,0 +1,37 @@ +from typing import Optional + +from fastapi import APIRouter, Query + +from apps.terminology.curd.terminology import page_terminology, create_terminology, update_terminology, \ + delete_terminology +from apps.terminology.models.terminology_model import TerminologyInfo +from common.core.deps import SessionDep + +router = APIRouter(tags=["Terminology"], prefix="/system/terminology") + + +@router.get("/page/{current_page}/{page_size}") +async def pager(session: SessionDep, current_page: int, page_size: int, + word: Optional[str] = Query(None, description="搜索术语(可选)")): + current_page, page_size, total_count, total_pages, _list = page_terminology(session, current_page, page_size, word) + + return { + "current_page": current_page, + "page_size": page_size, + "total_count": total_count, + "total_pages": total_pages, + "data": _list + } + + +@router.put("") +async def create_or_update(session: SessionDep, info: TerminologyInfo): + if info.id: + return update_terminology(session, info) + else: + return create_terminology(session, info) + + +@router.delete("") +async def delete(session: SessionDep, id_list: list[int]): + delete_terminology(session, id_list) diff --git a/backend/apps/terminology/curd/__init__.py b/backend/apps/terminology/curd/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/backend/apps/terminology/curd/terminology.py b/backend/apps/terminology/curd/terminology.py new file mode 100644 index 000000000..ee1b146c0 --- /dev/null +++ b/backend/apps/terminology/curd/terminology.py @@ -0,0 +1,196 @@ +import datetime +from typing import List, Optional + +from sqlalchemy import and_, or_, select, func, delete, update +from sqlalchemy.dialects.postgresql import JSONB +from sqlalchemy.orm import aliased + +from apps.terminology.models.terminology_model import Terminology, TerminologyInfo +from common.core.deps import SessionDep + + +def page_terminology(session: SessionDep, current_page: int = 1, page_size: int = 10, name: Optional[str] = None): + _list: List[TerminologyInfo] = [] + + child = aliased(Terminology) + + current_page = max(1, current_page) + page_size = max(10, page_size) + + total_count = 0 + total_pages = 0 + + if name and name.strip() != "": + keyword_pattern = f"%{name.strip()}%" + # 步骤1:先找到所有匹配的节点ID(无论是父节点还是子节点) + matched_ids_subquery = ( + select(Terminology.id) + .where(Terminology.name.like(keyword_pattern)) # LIKE查询条件 + .subquery() + ) + + # 步骤2:找到这些匹配节点的所有父节点(包括自身如果是父节点) + parent_ids_subquery = ( + select(Terminology.id) + .where( + (Terminology.id.in_(matched_ids_subquery)) | + (Terminology.id.in_( + select(Terminology.pid) + .where(Terminology.id.in_(matched_ids_subquery)) + .where(Terminology.pid.isnot(None)) + )) + ) + .where(Terminology.pid.is_(None)) # 只取父节点 + ) + + count_stmt = select(func.count()).select_from(parent_ids_subquery.subquery()) + total_count = session.execute(count_stmt).scalar() + total_pages = (total_count + page_size - 1) // page_size + + # 步骤3:获取分页后的父节点ID + paginated_parent_ids = ( + parent_ids_subquery + .order_by(Terminology.create_time.desc()) + .offset((current_page - 1) * page_size) + .limit(page_size) + .subquery() + ) + + # 步骤4:获取这些父节点的childrenNames + children_subquery = ( + select( + child.pid, + func.jsonb_agg(child.name).order_by(child.create_time.desc()).label('children_names') + ) + .where(child.pid.isnot(None)) + .group_by(child.pid) + .subquery() + ) + + # 主查询 + stmt = ( + select( + Terminology.id, + Terminology.word, + Terminology.create_time, + Terminology.description, + func.coalesce( + children_subquery.c.children_names, + func.cast('[]', JSONB) + ).label('other_words') + ) + .outerjoin( + children_subquery, + Terminology.id == children_subquery.c.pid + ) + .where(Terminology.id.in_(paginated_parent_ids)) + .order_by(Terminology.create_time.desc()) + ) + print(str(stmt)) + else: + parent_ids_subquery = ( + select(Terminology.id) + .where(Terminology.pid.is_(None)) # 只取父节点 + ) + count_stmt = select(func.count()).select_from(parent_ids_subquery.subquery()) + total_count = session.execute(count_stmt).scalar() + total_pages = (total_count + page_size - 1) // page_size + + paginated_parent_ids = ( + parent_ids_subquery + .order_by(Terminology.create_time.desc()) + .offset((current_page - 1) * page_size) + .limit(page_size) + .subquery() + ) + + stmt = ( + select( + Terminology.id, + Terminology.word, + Terminology.create_time, + Terminology.description, + func.coalesce( + func.jsonb_agg(child.word), + func.cast('[]', JSONB) + ).label('other_words') + ) + .outerjoin(child, and_(Terminology.id == child.pid)) + .where(Terminology.id.in_(paginated_parent_ids)) + .group_by(Terminology.id, Terminology.word) + .order_by(Terminology.create_time.desc()) + ) + print(str(stmt)) + + result = session.execute(stmt) + + for row in result: + _list.append(TerminologyInfo( + id=row.id, + word=row.word, + create_time=row.create_time, + description=row.description, + other_words=row.other_words, + )) + + return current_page, page_size, total_count, total_pages, _list + + +def create_terminology(session: SessionDep, info: TerminologyInfo): + create_time = datetime.datetime.now() + parent = Terminology(word=info.word, create_time=create_time, description=info.description) + + result = Terminology(**parent.model_dump()) + + session.add(parent) + session.flush() + session.refresh(parent) + + result.id = parent.id + session.commit() + + _list: List[Terminology] = [] + if info.other_words: + for other_word in info.other_words: + _list.append( + Terminology(pid=result.id, word=other_word, create_time=create_time, description=info.description)) + session.bulk_save_objects(_list) + session.flush() + session.commit() + + # todo embedding + + return result.id + + +def update_terminology(session: SessionDep, info: TerminologyInfo): + stmt = update(Terminology).where(and_(Terminology.id == info.id)).values( + word=info.word, + description=info.description, + ) + session.execute(stmt) + session.commit() + + stmt = delete(Terminology).where(and_(Terminology.pid == info.id)) + session.execute(stmt) + session.commit() + + create_time = datetime.datetime.now() + _list: List[Terminology] = [] + if info.other_words: + for other_word in info.other_words: + _list.append( + Terminology(pid=info.id, word=other_word, create_time=create_time, description=info.description)) + session.bulk_save_objects(_list) + session.flush() + session.commit() + + # todo embedding + + return info.id + + +def delete_terminology(session: SessionDep, ids: list[int]): + stmt = delete(Terminology).where(or_(Terminology.id.in_(ids), Terminology.pid.in_(ids))) + session.execute(stmt) + session.commit() diff --git a/backend/apps/terminology/models/__init__.py b/backend/apps/terminology/models/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/backend/apps/terminology/models/terminology_model.py b/backend/apps/terminology/models/terminology_model.py new file mode 100644 index 000000000..d467cc5c1 --- /dev/null +++ b/backend/apps/terminology/models/terminology_model.py @@ -0,0 +1,27 @@ +from datetime import datetime +from typing import List, Optional + +from pgvector.sqlalchemy import VECTOR +from pydantic import BaseModel +from sqlalchemy import Column, Text, BigInteger, DateTime, Identity +from sqlmodel import SQLModel, Field + + +class Terminology(SQLModel, table=True): + __tablename__ = "terminology" + id: Optional[int] = Field(sa_column=Column(BigInteger, Identity(always=True), primary_key=True)) + pid: Optional[int] = Field(sa_column=Column(BigInteger, nullable=True)) + create_time: Optional[datetime] = Field(sa_column=Column(DateTime(timezone=False), nullable=True)) + word: Optional[str] = Field(max_length=255) + description: Optional[str] = Field(sa_column=Column(Text, nullable=True)) + embedding: Optional[List[float]] = Field(sa_column=Column(VECTOR(), nullable=True)) + + +class TerminologyInfo(BaseModel): + id: Optional[int] = None + create_time: Optional[datetime] = None + word: Optional[str] = None + description: Optional[str] = None + other_words: Optional[List[str]] = [] + + diff --git a/backend/common/core/config.py b/backend/common/core/config.py index f32dad35a..793bd0bee 100644 --- a/backend/common/core/config.py +++ b/backend/common/core/config.py @@ -50,20 +50,20 @@ def all_cors_origins(self) -> list[str]: POSTGRES_PASSWORD: str = "123456" POSTGRES_DB: str = "sqlbot" SQLBOT_DB_URL: str = '' - #SQLBOT_DB_URL: str = 'mysql+pymysql://root:Password123%40mysql@127.0.0.1:3306/sqlbot' - - TOKEN_KEY: str = "X-SQLBOT-TOKEN" + # SQLBOT_DB_URL: str = 'mysql+pymysql://root:Password123%40mysql@127.0.0.1:3306/sqlbot' + + TOKEN_KEY: str = "X-SQLBOT-TOKEN" DEFAULT_PWD: str = "SQLBot@123456" ASSISTANT_TOKEN_KEY: str = "X-SQLBOT-ASSISTANT-TOKEN" - + CACHE_TYPE: Literal["redis", "memory", "None"] = "memory" - CACHE_REDIS_URL: str | None = None # Redis URL, e.g., "redis://[[username]:[password]]@localhost:6379/0" - + CACHE_REDIS_URL: str | None = None # Redis URL, e.g., "redis://[[username]:[password]]@localhost:6379/0" + LOG_LEVEL: str = "INFO" # DEBUG, INFO, WARNING, ERROR LOG_DIR: str = "logs" LOG_FORMAT: str = "%(asctime)s - %(name)s - %(levelname)s:%(lineno)d - %(message)s" SQL_DEBUG: bool = False - + UPLOAD_DIR: str = "/opt/sqlbot/data/file" SQLBOT_KEY_EXPIRED: int = 100 # License key expiration timestamp, 0 means no expiration @@ -86,4 +86,11 @@ def SQLALCHEMY_DATABASE_URI(self) -> PostgresDsn | str: MCP_IMAGE_HOST: str = 'http://localhost:3000' SERVER_IMAGE_HOST: str = '' + LOCAL_MODEL_PATH: str = '/opt/sqlbot/models' + DEFAULT_EMBEDDING_MODEL: str = 'shibing624/text2vec-base-chinese' + + EMBEDDING_SIMILARITY: float = 0.6 + EMBEDDING_TOP_COUNT: int = 3 + + settings = Settings() # type: ignore diff --git a/backend/pyproject.toml b/backend/pyproject.toml index ef216ab33..5f6273e73 100644 --- a/backend/pyproject.toml +++ b/backend/pyproject.toml @@ -23,7 +23,9 @@ dependencies = [ "langchain-core>=0.3,<0.4", "langchain-openai>=0.3,<0.4", "langchain-community>=0.3,<0.4", + "langchain-huggingface>=0.2.0", "langgraph>=0.3,<0.4", + "pgvector>=0.4.1", "dashscope>=1.14.0,<2.0.0", "pymysql (>=1.1.1,<2.0.0)", "cryptography (>=44.0.3,<45.0.0)", diff --git a/frontend/src/i18n/en.json b/frontend/src/i18n/en.json index 4a96e4994..a72014ee8 100644 --- a/frontend/src/i18n/en.json +++ b/frontend/src/i18n/en.json @@ -644,4 +644,4 @@ "setting_successfully": "Setting Successfully", "customize_theme_color": "Customize theme color" } -} \ No newline at end of file +} diff --git a/frontend/src/i18n/zh-CN.json b/frontend/src/i18n/zh-CN.json index fedf5dd51..0dfae875c 100644 --- a/frontend/src/i18n/zh-CN.json +++ b/frontend/src/i18n/zh-CN.json @@ -644,4 +644,4 @@ "setting_successfully": "设置成功", "customize_theme_color": "自定义主题色" } -} \ No newline at end of file +} diff --git a/frontend/src/views/system/professional/index.vue b/frontend/src/views/system/professional/index.vue index 71bcc470e..8f57beee0 100644 --- a/frontend/src/views/system/professional/index.vue +++ b/frontend/src/views/system/professional/index.vue @@ -321,7 +321,7 @@ const deleteHandlerItem = (idx: number) => {