diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 2613255c1f7..e902bb73be2 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -55,28 +55,29 @@ jobs: with: version: ">=0.8.2" - - name: Build ragflow:dev-slim + - name: Build ragflow:nightly-slim run: | RUNNER_WORKSPACE_PREFIX=${RUNNER_WORKSPACE_PREFIX:-$HOME} sudo docker pull ubuntu:22.04 - sudo docker build --progress=plain --build-arg LIGHTEN=1 --build-arg NEED_MIRROR=1 -f Dockerfile -t infiniflow/ragflow:dev-slim . + sudo docker build --progress=plain --build-arg LIGHTEN=1 --build-arg NEED_MIRROR=1 -f Dockerfile -t infiniflow/ragflow:nightly-slim . - - name: Build ragflow:dev + - name: Build ragflow:nightly run: | - sudo docker build --progress=plain --build-arg NEED_MIRROR=1 -f Dockerfile -t infiniflow/ragflow:dev . + sudo docker build --progress=plain --build-arg NEED_MIRROR=1 -f Dockerfile -t infiniflow/ragflow:nightly . - - name: Start ragflow:dev-slim + - name: Start ragflow:nightly-slim run: | + echo "RAGFLOW_IMAGE=infiniflow/ragflow:nightly-slim" >> docker/.env sudo docker compose -f docker/docker-compose.yml up -d - - name: Stop ragflow:dev-slim + - name: Stop ragflow:nightly-slim if: always() # always run this step even if previous steps failed run: | sudo docker compose -f docker/docker-compose.yml down -v - - name: Start ragflow:dev + - name: Start ragflow:nightly run: | - echo "RAGFLOW_IMAGE=infiniflow/ragflow:dev" >> docker/.env + echo "RAGFLOW_IMAGE=infiniflow/ragflow:nightly" >> docker/.env sudo docker compose -f docker/docker-compose.yml up -d - name: Run sdk tests against Elasticsearch @@ -100,12 +101,12 @@ jobs: cd sdk/python && poetry install && source .venv/bin/activate && cd test/test_frontend_api && pytest -s --tb=short get_email.py test_dataset.py - - name: Stop ragflow:dev + - name: Stop ragflow:nightly if: always() # always run this step even if previous steps failed run: | sudo docker compose -f docker/docker-compose.yml down -v - - name: Start ragflow:dev + - name: Start ragflow:nightly run: | sudo DOC_ENGINE=infinity docker compose -f docker/docker-compose.yml up -d @@ -129,7 +130,7 @@ jobs: done cd sdk/python && poetry install && source .venv/bin/activate && cd test/test_frontend_api && pytest -s --tb=short get_email.py test_dataset.py - - name: Stop ragflow:dev + - name: Stop ragflow:nightly if: always() # always run this step even if previous steps failed run: | sudo DOC_ENGINE=infinity docker compose -f docker/docker-compose.yml down -v diff --git a/Dockerfile b/Dockerfile index f00ef060c8d..3e316e87a1b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -43,6 +43,7 @@ RUN --mount=type=cache,id=ragflow_apt,target=/var/cache/apt,sharing=locked \ fi; \ rm -f /etc/apt/apt.conf.d/docker-clean && \ echo 'Binary::apt::APT::Keep-Downloaded-Packages "true";' > /etc/apt/apt.conf.d/keep-cache && \ + chmod 1777 /tmp && \ apt update && \ apt --no-install-recommends install -y ca-certificates && \ apt update && \ diff --git a/Dockerfile.deps b/Dockerfile.deps index 438ab5ce9fe..c16ad446201 100644 --- a/Dockerfile.deps +++ b/Dockerfile.deps @@ -1,6 +1,6 @@ # This builds an image that contains the resources needed by Dockerfile # -FROM ubuntu:22.04 +FROM scratch # Copy resources downloaded via download_deps.py COPY chromedriver-linux64-121-0-6167-85 chrome-linux64-121-0-6167-85 cl100k_base.tiktoken libssl1.1_1.1.1f-1ubuntu2_amd64.deb libssl1.1_1.1.1f-1ubuntu2_arm64.deb tika-server-standard-3.0.0.jar tika-server-standard-3.0.0.jar.md5 libssl*.deb / diff --git a/README.md b/README.md index 8be1526b35e..ed3681da905 100644 --- a/README.md +++ b/README.md @@ -165,29 +165,25 @@ releases! 🌟 $ git clone https://github.com/infiniflow/ragflow.git ``` -3. Build the pre-built Docker images and start up the server: +3. Start up the server using the pre-built Docker images: - > The command below downloads the dev version Docker image for RAGFlow slim (`dev-slim`). Note that RAGFlow slim - Docker images do not include embedding models or Python libraries and hence are approximately 1GB in size. + > The command below downloads the v0.14.1 version Docker image for RAGFlow slim (`v0.14.1-slim`). Note that RAGFlow slim + Docker images do not include embedding models or Python libraries and hence are approximately 2 GB in size. ```bash $ cd ragflow/docker $ docker compose -f docker-compose.yml up -d ``` - > - To download a RAGFlow slim Docker image of a specific version, update the `RAGFLOW_IMAGE` variable in * - *docker/.env** to your desired version. For example, `RAGFLOW_IMAGE=infiniflow/ragflow:v0.14.1-slim`. After - making this change, rerun the command above to initiate the download. - > - To download the dev version of RAGFlow Docker image *including* embedding models and Python libraries, update the - `RAGFLOW_IMAGE` variable in **docker/.env** to `RAGFLOW_IMAGE=infiniflow/ragflow:dev`. After making this change, - rerun the command above to initiate the download. - > - To download a specific version of RAGFlow Docker image *including* embedding models and Python libraries, update - the `RAGFLOW_IMAGE` variable in **docker/.env** to your desired version. For example, - `RAGFLOW_IMAGE=infiniflow/ragflow:v0.14.1`. After making this change, rerun the command above to initiate the - download. + | RAGFLOW_IMAGE tag in docker/.env | size | Including embedding models and related Python packages? | comments | + | -------------------------------- | ----- | ------------------------------------------------------- | ---------------------- | + | v0.14.1 | ~9 GB | YES | stable release | + | v0.14.1-slim | ~2 GB | NO | stable release | + | v0.15.0-dev1 | ~9 GB | YES | unstable beta release | + | v0.15.0-dev1-slim | ~2 GB | NO | unstable beta release | + | nightly | ~9 GB | YES | unstable nightly build | + | nightly-slim | ~2 GB | NO | unstable nightly build | - > **NOTE:** A RAGFlow Docker image that includes embedding models and Python libraries is approximately 9GB in size - and may take significantly longer time to load. 4. Check the server status after having the server up and running: @@ -267,12 +263,12 @@ RAGFlow uses Elasticsearch by default for storing full text and vectors. To swit ## 🔧 Build a Docker image without embedding models -This image is approximately 1 GB in size and relies on external LLM and embedding services. +This image is approximately 2 GB in size and relies on external LLM and embedding services. ```bash git clone https://github.com/infiniflow/ragflow.git cd ragflow/ -docker build --build-arg LIGHTEN=1 -f Dockerfile -t infiniflow/ragflow:dev-slim . +docker build --build-arg LIGHTEN=1 -f Dockerfile -t infiniflow/ragflow:nightly-slim . ``` ## 🔧 Build a Docker image including embedding models @@ -282,7 +278,7 @@ This image is approximately 9 GB in size. As it includes embedding models, it re ```bash git clone https://github.com/infiniflow/ragflow.git cd ragflow/ -docker build -f Dockerfile -t infiniflow/ragflow:dev . +docker build -f Dockerfile -t infiniflow/ragflow:nightly . ``` ## 🔨 Launch service from source for development diff --git a/README_id.md b/README_id.md index fd06d63b8cb..a48a5005e4c 100644 --- a/README_id.md +++ b/README_id.md @@ -160,7 +160,7 @@ Coba demo kami di [https://demo.ragflow.io](https://demo.ragflow.io). 3. Bangun image Docker pre-built dan jalankan server: - > Perintah di bawah ini akan mengunduh versi dev dari Docker image RAGFlow slim (`dev-slim`). Image RAGFlow slim + > Perintah di bawah ini akan mengunduh versi v0.14.1 dari Docker image RAGFlow slim (`v0.14.1-slim`). Image RAGFlow slim tidak termasuk model embedding atau library Python dan berukuran sekitar 1GB. ```bash @@ -168,18 +168,16 @@ Coba demo kami di [https://demo.ragflow.io](https://demo.ragflow.io). $ docker compose -f docker-compose.yml up -d ``` - > - Untuk mengunduh versi tertentu dari image Docker RAGFlow slim, perbarui variabel `RAGFlow_IMAGE` di * - *docker/.env** sesuai dengan versi yang diinginkan. Misalnya, `RAGFLOW_IMAGE=infiniflow/ragflow:v0.14.1-slim`. - Setelah mengubah ini, jalankan ulang perintah di atas untuk memulai unduhan. - > - Untuk mengunduh versi dev dari image Docker RAGFlow *termasuk* model embedding dan library Python, perbarui - variabel `RAGFlow_IMAGE` di **docker/.env** menjadi `RAGFLOW_IMAGE=infiniflow/ragflow:dev`. Setelah mengubah ini, - jalankan ulang perintah di atas untuk memulai unduhan. - > - Untuk mengunduh versi tertentu dari image Docker RAGFlow *termasuk* model embedding dan library Python, perbarui - variabel `RAGFlow_IMAGE` di **docker/.env** sesuai dengan versi yang diinginkan. Misalnya, - `RAGFLOW_IMAGE=infiniflow/ragflow:v0.14.1`. Setelah mengubah ini, jalankan ulang perintah di atas untuk memulai unduhan. + | RAGFLOW_IMAGE tag in docker/.env | size | Including embedding models and related Python packages? | comments | + | -------------------------------- | ----- | ------------------------------------------------------- | ---------------------- | + | v0.14.1 | ~9 GB | YES | stable release | + | v0.14.1-slim | ~2 GB | NO | stable release | + | v0.15.0-dev1 | ~9 GB | YES | unstable beta release | + | v0.15.0-dev1-slim | ~2 GB | NO | unstable beta release | + | nightly | ~9 GB | YES | unstable nightly build | + | nightly-slim | ~2 GB | NO | unstable nightly build | + - > **CATATAN:** Image Docker RAGFlow yang mencakup model embedding dan library Python berukuran sekitar 9GB - dan mungkin memerlukan waktu lebih lama untuk dimuat. 4. Periksa status server setelah server aktif dan berjalan: @@ -242,12 +240,12 @@ Pembaruan konfigurasi ini memerlukan reboot semua kontainer agar efektif: ## 🔧 Membangun Docker Image tanpa Model Embedding -Image ini berukuran sekitar 1 GB dan bergantung pada aplikasi LLM eksternal dan embedding. +Image ini berukuran sekitar 2 GB dan bergantung pada aplikasi LLM eksternal dan embedding. ```bash git clone https://github.com/infiniflow/ragflow.git cd ragflow/ -docker build --build-arg LIGHTEN=1 -f Dockerfile -t infiniflow/ragflow:dev-slim . +docker build --build-arg LIGHTEN=1 -f Dockerfile -t infiniflow/ragflow:nightly-slim . ``` ## 🔧 Membangun Docker Image Termasuk Model Embedding @@ -257,7 +255,7 @@ Image ini berukuran sekitar 9 GB. Karena sudah termasuk model embedding, ia hany ```bash git clone https://github.com/infiniflow/ragflow.git cd ragflow/ -docker build -f Dockerfile -t infiniflow/ragflow:dev . +docker build -f Dockerfile -t infiniflow/ragflow:nightly . ``` ## 🔨 Menjalankan Aplikasi dari untuk Pengembangan diff --git a/README_ja.md b/README_ja.md index 22135c88e39..94369c95ce5 100644 --- a/README_ja.md +++ b/README_ja.md @@ -141,18 +141,22 @@ 3. ビルド済みの Docker イメージをビルドし、サーバーを起動する: - > 以下のコマンドは、RAGFlow slim(`dev-slim`)の開発版Dockerイメージをダウンロードします。RAGFlow slimのDockerイメージには、埋め込みモデルやPythonライブラリが含まれていないため、サイズは約1GBです。 + > 以下のコマンドは、RAGFlow slim(`v0.14.1-slim`)の開発版Dockerイメージをダウンロードします。RAGFlow slimのDockerイメージには、埋め込みモデルやPythonライブラリが含まれていないため、サイズは約1GBです。 ```bash $ cd ragflow/docker $ docker compose -f docker-compose.yml up -d ``` - > - 特定のバージョンのRAGFlow slim Dockerイメージをダウンロードするには、**docker/.env**内の`RAGFlow_IMAGE`変数を希望のバージョンに更新します。例えば、`RAGFLOW_IMAGE=infiniflow/ragflow:v0.14.1`とします。この変更を行った後、上記のコマンドを再実行してダウンロードを開始してください。 - > - RAGFlowの埋め込みモデルとPythonライブラリを含む開発版Dockerイメージをダウンロードするには、**docker/.env**内の`RAGFlow_IMAGE`変数を`RAGFLOW_IMAGE=infiniflow/ragflow:dev`に更新します。この変更を行った後、上記のコマンドを再実行してダウンロードを開始してください。 - > - 特定のバージョンのRAGFlow Dockerイメージ(埋め込みモデルとPythonライブラリを含む)をダウンロードするには、**docker/.env**内の`RAGFlow_IMAGE`変数を希望のバージョンに更新します。例えば、`RAGFLOW_IMAGE=infiniflow/ragflow:v0.14.1`とします。この変更を行った後、上記のコマンドを再実行してダウンロードを開始してください。 - - > **NOTE:** 埋め込みモデルとPythonライブラリを含むRAGFlow Dockerイメージのサイズは約9GBであり、読み込みにかなりの時間がかかる場合があります。 + | RAGFLOW_IMAGE tag in docker/.env | size | Including embedding models and related Python packages? | comments | + | -------------------------------- | ----- | ------------------------------------------------------- | ---------------------- | + | v0.14.1 | ~9 GB | YES | stable release | + | v0.14.1-slim | ~2 GB | NO | stable release | + | v0.15.0-dev1 | ~9 GB | YES | unstable beta release | + | v0.15.0-dev1-slim | ~2 GB | NO | unstable beta release | + | nightly | ~9 GB | YES | unstable nightly build | + | nightly-slim | ~2 GB | NO | unstable nightly build | + 4. サーバーを立ち上げた後、サーバーの状態を確認する: @@ -228,7 +232,7 @@ RAGFlow はデフォルトで Elasticsearch を使用して全文とベクトル ```bash git clone https://github.com/infiniflow/ragflow.git cd ragflow/ -docker build --build-arg LIGHTEN=1 -f Dockerfile -t infiniflow/ragflow:dev-slim . +docker build --build-arg LIGHTEN=1 -f Dockerfile -t infiniflow/ragflow:nightly-slim . ``` ## 🔧 ソースコードをコンパイルしたDockerイメージ(埋め込みモデルを含む) @@ -238,7 +242,7 @@ docker build --build-arg LIGHTEN=1 -f Dockerfile -t infiniflow/ragflow:dev-slim ```bash git clone https://github.com/infiniflow/ragflow.git cd ragflow/ -docker build -f Dockerfile -t infiniflow/ragflow:dev . +docker build -f Dockerfile -t infiniflow/ragflow:nightly . ``` ## 🔨 ソースコードからサービスを起動する方法 diff --git a/README_ko.md b/README_ko.md index 87cde3d4ec0..d3769a9a19a 100644 --- a/README_ko.md +++ b/README_ko.md @@ -145,18 +145,24 @@ 3. 미리 빌드된 Docker 이미지를 생성하고 서버를 시작하세요: - > 아래의 명령은 RAGFlow slim(dev-slim)의 개발 버전 Docker 이미지를 다운로드합니다. RAGFlow slim Docker 이미지에는 임베딩 모델이나 Python 라이브러리가 포함되어 있지 않으므로 크기는 약 1GB입니다. + > 아래의 명령은 RAGFlow slim(v0.14.1-slim)의 개발 버전 Docker 이미지를 다운로드합니다. RAGFlow slim Docker 이미지에는 임베딩 모델이나 Python 라이브러리가 포함되어 있지 않으므로 크기는 약 1GB입니다. ```bash $ cd ragflow/docker $ docker compose -f docker-compose.yml up -d ``` - > - 특정 버전의 RAGFlow slim Docker 이미지를 다운로드하려면, **docker/.env**에서 `RAGFlow_IMAGE` 변수를 원하는 버전으로 업데이트하세요. 예를 들어, `RAGFLOW_IMAGE=infiniflow/ragflow:v0.14.1-slim`으로 설정합니다. 이 변경을 완료한 후, 위의 명령을 다시 실행하여 다운로드를 시작하세요. - > - RAGFlow의 임베딩 모델과 Python 라이브러리를 포함한 개발 버전 Docker 이미지를 다운로드하려면, **docker/.env**에서 `RAGFlow_IMAGE` 변수를 `RAGFLOW_IMAGE=infiniflow/ragflow:dev`로 업데이트하세요. 이 변경을 완료한 후, 위의 명령을 다시 실행하여 다운로드를 시작하세요. - > - 특정 버전의 RAGFlow Docker 이미지를 임베딩 모델과 Python 라이브러리를 포함하여 다운로드하려면, **docker/.env**에서 `RAGFlow_IMAGE` 변수를 원하는 버전으로 업데이트하세요. 예를 들어, `RAGFLOW_IMAGE=infiniflow/ragflow:v0.14.1` 로 설정합니다. 이 변경을 완료한 후, 위의 명령을 다시 실행하여 다운로드를 시작하세요. - - > **NOTE:** 임베딩 모델과 Python 라이브러리를 포함한 RAGFlow Docker 이미지의 크기는 약 9GB이며, 로드하는 데 상당히 오랜 시간이 걸릴 수 있습니다. + + | RAGFLOW_IMAGE tag in docker/.env | size | Including embedding models and related Python packages? | comments | + | -------------------------------- | ----- | ------------------------------------------------------- | ---------------------- | + | v0.14.1 | ~9 GB | YES | stable release | + | v0.14.1-slim | ~2 GB | NO | stable release | + | v0.15.0-dev1 | ~9 GB | YES | unstable beta release | + | v0.15.0-dev1-slim | ~2 GB | NO | unstable beta release | + | nightly | ~9 GB | YES | unstable nightly build | + | nightly-slim | ~2 GB | NO | unstable nightly build | + + 4. 서버가 시작된 후 서버 상태를 확인하세요: @@ -230,7 +236,7 @@ RAGFlow 는 기본적으로 Elasticsearch 를 사용하여 전체 텍스트 및 ```bash git clone https://github.com/infiniflow/ragflow.git cd ragflow/ -docker build --build-arg LIGHTEN=1 -f Dockerfile -t infiniflow/ragflow:dev-slim . +docker build --build-arg LIGHTEN=1 -f Dockerfile -t infiniflow/ragflow:nightly-slim . ``` ## 🔧 소스 코드로 Docker 이미지를 컴파일합니다(임베딩 모델 포함) @@ -240,7 +246,7 @@ docker build --build-arg LIGHTEN=1 -f Dockerfile -t infiniflow/ragflow:dev-slim ```bash git clone https://github.com/infiniflow/ragflow.git cd ragflow/ -docker build -f Dockerfile -t infiniflow/ragflow:dev . +docker build -f Dockerfile -t infiniflow/ragflow:nightly . ``` ## 🔨 소스 코드로 서비스를 시작합니다. diff --git a/README_zh.md b/README_zh.md index f7a5b1b25a4..0d9e7ddc9a5 100644 --- a/README_zh.md +++ b/README_zh.md @@ -142,18 +142,23 @@ 3. 进入 **docker** 文件夹,利用提前编译好的 Docker 镜像启动服务器: - > 运行以下命令会自动下载 dev 版的 RAGFlow slim Docker 镜像(`dev-slim`),该镜像并不包含 embedding 模型以及一些 Python 库,因此镜像大小约 1GB。 + > 运行以下命令会自动下载 v0.14.1 版的 RAGFlow slim Docker 镜像(`v0.14.1-slim`),该镜像并不包含 embedding 模型以及一些 Python 库,因此镜像大小约 1GB。 ```bash $ cd ragflow/docker $ docker compose -f docker-compose.yml up -d ``` - > - 如果你想下载并运行特定版本的 RAGFlow slim Docker 镜像,请在 **docker/.env** 文件中找到 `RAGFLOW_IMAGE` 变量,将其改为对应版本。例如 `RAGFLOW_IMAGE=infiniflow/ragflow:v0.14.1-slim`,然后再运行上述命令。 - > - 如果您想安装内置 embedding 模型和 Python 库的 dev 版本的 Docker 镜像,需要将 **docker/.env** 文件中的 `RAGFLOW_IMAGE` 变量修改为: `RAGFLOW_IMAGE=infiniflow/ragflow:dev`。 - > - 如果您想安装内置 embedding 模型和 Python 库的指定版本的 RAGFlow Docker 镜像,需要将 **docker/.env** 文件中的 `RAGFLOW_IMAGE` 变量修改为: `RAGFLOW_IMAGE=infiniflow/ragflow:v0.14.1`。修改后,再运行上面的命令。 - > **注意:** 安装内置 embedding 模型和 Python 库的指定版本的 RAGFlow Docker 镜像大小约 9 GB,可能需要更长时间下载,请耐心等待。 - + | RAGFLOW_IMAGE tag in docker/.env | 尺寸 | 内置 embedding 模型和相关 Python 库? | 描述 | + | -------------------------------- | ----- | ------------------------------------------------------- | ---------------------- | + | v0.14.1 | ~9 GB | YES | stable release | + | v0.14.1-slim | ~2 GB | NO | stable release | + | v0.15.0-dev1 | ~9 GB | YES | unstable beta release | + | v0.15.0-dev1-slim | ~2 GB | NO | unstable beta release | + | nightly | ~9 GB | YES | unstable nightly build | + | nightly-slim | ~2 GB | NO | unstable nightly build | + + 4. 服务器启动成功后再次确认服务器状态: ```bash @@ -230,12 +235,12 @@ RAGFlow 默认使用 Elasticsearch 存储文本和向量数据. 如果要切换 ## 🔧 源码编译 Docker 镜像(不含 embedding 模型) -本 Docker 镜像大小约 1 GB 左右并且依赖外部的大模型和 embedding 服务。 +本 Docker 镜像大小约 2 GB 左右并且依赖外部的大模型和 embedding 服务。 ```bash git clone https://github.com/infiniflow/ragflow.git cd ragflow/ -docker build --build-arg LIGHTEN=1 --build-arg NEED_MIRROR=1 -f Dockerfile -t infiniflow/ragflow:dev-slim . +docker build --build-arg LIGHTEN=1 --build-arg NEED_MIRROR=1 -f Dockerfile -t infiniflow/ragflow:nightly-slim . ``` ## 🔧 源码编译 Docker 镜像(包含 embedding 模型) @@ -245,7 +250,7 @@ docker build --build-arg LIGHTEN=1 --build-arg NEED_MIRROR=1 -f Dockerfile -t in ```bash git clone https://github.com/infiniflow/ragflow.git cd ragflow/ -docker build --build-arg NEED_MIRROR=1 -f Dockerfile -t infiniflow/ragflow:dev . +docker build --build-arg NEED_MIRROR=1 -f Dockerfile -t infiniflow/ragflow:nightly . ``` ## 🔨 以源代码启动服务 diff --git a/agent/canvas.py b/agent/canvas.py index bfffabd59ce..d8b04a9835b 100644 --- a/agent/canvas.py +++ b/agent/canvas.py @@ -21,6 +21,7 @@ from agent.component import component_class from agent.component.base import ComponentBase + class Canvas(ABC): """ dsl = { @@ -320,3 +321,13 @@ def _find_loop(self, max_loops=6): def get_prologue(self): return self.components["begin"]["obj"]._param.prologue + + def set_global_param(self, **kwargs): + for k, v in kwargs.items(): + for q in self.components["begin"]["obj"]._param.query: + if k != q["key"]: + continue + q["value"] = v + + def get_preset_param(self): + return self.components["begin"]["obj"]._param.query \ No newline at end of file diff --git a/agent/component/base.py b/agent/component/base.py index 2660be7d373..2dc0cd49beb 100644 --- a/agent/component/base.py +++ b/agent/component/base.py @@ -383,9 +383,6 @@ def __str__(self): "params": {} } """ - out = json.loads(str(self._param)).get("output", {}) - if isinstance(out, dict) and "vector" in out: - del out["vector"] return """{{ "component_name": "{}", "params": {}, @@ -393,7 +390,7 @@ def __str__(self): "inputs": {} }}""".format(self.component_name, self._param, - json.dumps(out, ensure_ascii=False), + json.dumps(json.loads(str(self._param)).get("output", {}), ensure_ascii=False), json.dumps(json.loads(str(self._param)).get("inputs", []), ensure_ascii=False) ) @@ -462,7 +459,7 @@ def get_input(self): self._param.inputs = [] outs = [] for q in self._param.query: - if q["component_id"]: + if q.get("component_id"): if q["component_id"].split("@")[0].lower().find("begin") >= 0: cpn_id, key = q["component_id"].split("@") for p in self._canvas.get_component(cpn_id)["obj"]._param.query: diff --git a/agent/component/begin.py b/agent/component/begin.py index 037a8a057c2..766c0c66719 100644 --- a/agent/component/begin.py +++ b/agent/component/begin.py @@ -26,6 +26,7 @@ class BeginParam(ComponentParamBase): def __init__(self): super().__init__() self.prologue = "Hi! I'm your smart assistant. What can I do for you?" + self.query = [] def check(self): return True diff --git a/agent/templates/customer_service.json b/agent/templates/customer_service.json index edc9931c188..e8aa89b6303 100644 --- a/agent/templates/customer_service.json +++ b/agent/templates/customer_service.json @@ -336,7 +336,7 @@ "parameters": [], "presencePenaltyEnabled": true, "presence_penalty": 0.4, - "prompt": "Role: You are a customer support. \n\nTask: Please answer the question based on content of knowledge base. \n\nRequirements & restrictions:\n - DO NOT make things up when all knowledge base content is irrelevant to the question. \n - Answers need to consider chat history.\n - Request about customer's contact information like, Wechat number, LINE number, twitter, discord, etc,. , when knowledge base content can't answer his question. So, product expert could contact him soon to solve his problem.\n\n Knowledge base content is as following:\n {input}\n The above is the content of knowledge base.", + "prompt": "Role: You are a customer support. \n\nTask: Please answer the question based on content of knowledge base. \n\nReuirements & restrictions:\n - DO NOT make things up when all knowledge base content is irrelevant to the question. \n - Answers need to consider chat history.\n - Request about customer's contact information like, Wechat number, LINE number, twitter, discord, etc,. , when knowlegebase content can't answer his question. So, product expert could contact him soon to solve his problem.\n\n Knowledge base content is as following:\n {input}\n The above is the content of knowledge base.", "temperature": 0.1, "temperatureEnabled": true, "topPEnabled": true, @@ -603,7 +603,7 @@ { "data": { "form": { - "text": "Static messages.\nDefine response after receive user's contact information." + "text": "Static messages.\nDefine replys after recieve user's contact information." }, "label": "Note", "name": "N: What else?" @@ -691,7 +691,7 @@ { "data": { "form": { - "text": "Complete questions by conversation history.\nUser: What's RAGFlow?\nAssistant: RAGFlow is xxx.\nUser: How to deploy it?\n\nRefine it: How to deploy RAGFlow?" + "text": "Complete questions by conversation history.\nUser: What's RAGFlow?\nAssistant: RAGFlow is xxx.\nUser: How to deloy it?\n\nRefine it: How to deploy RAGFlow?" }, "label": "Note", "name": "N: Refine Question" diff --git a/api/apps/conversation_app.py b/api/apps/conversation_app.py index cce87c337e8..d787e5f1f65 100644 --- a/api/apps/conversation_app.py +++ b/api/apps/conversation_app.py @@ -17,12 +17,14 @@ import re import traceback from copy import deepcopy + +from api.db.services.conversation_service import ConversationService from api.db.services.user_service import UserTenantService from flask import request, Response from flask_login import login_required, current_user from api.db import LLMType -from api.db.services.dialog_service import DialogService, ConversationService, chat, ask +from api.db.services.dialog_service import DialogService, chat, ask from api.db.services.knowledgebase_service import KnowledgebaseService from api.db.services.llm_service import LLMBundle, TenantService, TenantLLMService from api import settings diff --git a/api/apps/sdk/session.py b/api/apps/sdk/session.py index 54851f984d9..ff458000229 100644 --- a/api/apps/sdk/session.py +++ b/api/apps/sdk/session.py @@ -16,17 +16,19 @@ import logging import re import json -from copy import deepcopy -from uuid import uuid4 from api.db import LLMType from flask import request, Response + +from api.db.services.conversation_service import ConversationService, iframe_completion +from api.db.services.conversation_service import completion as rag_completion +from api.db.services.canvas_service import completion as agent_completion from api.db.services.dialog_service import ask from agent.canvas import Canvas from api.db import StatusEnum -from api.db.db_models import API4Conversation +from api.db.db_models import APIToken from api.db.services.api_service import API4ConversationService from api.db.services.canvas_service import UserCanvasService -from api.db.services.dialog_service import DialogService, ConversationService, chat +from api.db.services.dialog_service import DialogService from api.db.services.knowledgebase_service import KnowledgebaseService from api.utils import get_uuid from api.utils.api_utils import get_error_data_result @@ -67,8 +69,6 @@ def create_agent_session(tenant_id, agent_id): e, cvs = UserCanvasService.get_by_id(agent_id) if not e: return get_error_data_result("Agent not found.") - if cvs.user_id != tenant_id: - return get_error_data_result(message="You do not own the agent.") if not isinstance(cvs.dsl, str): cvs.dsl = json.dumps(cvs.dsl, ensure_ascii=False) @@ -111,98 +111,10 @@ def update(tenant_id, chat_id, session_id): @manager.route('/chats//completions', methods=['POST']) # noqa: F821 @token_required -def completion(tenant_id, chat_id): - dia = DialogService.query(id=chat_id, tenant_id=tenant_id, status=StatusEnum.VALID.value) - if not dia: - return get_error_data_result(message="You do not own the chat") +def chat_completion(tenant_id, chat_id): req = request.json - if not req.get("session_id"): - conv = { - "id": get_uuid(), - "dialog_id": chat_id, - "name": req.get("name", "New session"), - "message": [{"role": "assistant", "content": dia[0].prompt_config.get("prologue")}] - } - if not conv.get("name"): - return get_error_data_result(message="`name` can not be empty.") - ConversationService.save(**conv) - e, conv = ConversationService.get_by_id(conv["id"]) - session_id = conv.id - else: - session_id = req.get("session_id") - if not req.get("question"): - return get_error_data_result(message="Please input your question.") - conv = ConversationService.query(id=session_id, dialog_id=chat_id) - if not conv: - return get_error_data_result(message="Session does not exist") - conv = conv[0] - msg = [] - question = { - "content": req.get("question"), - "role": "user", - "id": str(uuid4()) - } - conv.message.append(question) - for m in conv.message: - if m["role"] == "system": - continue - if m["role"] == "assistant" and not msg: - continue - msg.append(m) - message_id = msg[-1].get("id") - e, dia = DialogService.get_by_id(conv.dialog_id) - - if not conv.reference: - conv.reference = [] - conv.message.append({"role": "assistant", "content": "", "id": message_id}) - conv.reference.append({"chunks": [], "doc_aggs": []}) - - def fillin_conv(ans): - reference = ans["reference"] - temp_reference = deepcopy(ans["reference"]) - nonlocal conv, message_id - if not conv.reference: - conv.reference.append(temp_reference) - else: - conv.reference[-1] = temp_reference - conv.message[-1] = {"role": "assistant", "content": ans["answer"], - "id": message_id, "prompt": ans.get("prompt", "")} - if "chunks" in reference: - chunks = reference.get("chunks") - chunk_list = [] - for chunk in chunks: - new_chunk = { - "id": chunk["chunk_id"], - "content": chunk["content_with_weight"], - "document_id": chunk["doc_id"], - "document_name": chunk["docnm_kwd"], - "dataset_id": chunk["kb_id"], - "image_id": chunk.get("image_id", ""), - "similarity": chunk["similarity"], - "vector_similarity": chunk["vector_similarity"], - "term_similarity": chunk["term_similarity"], - "positions": chunk.get("positions", []), - } - chunk_list.append(new_chunk) - reference["chunks"] = chunk_list - ans["id"] = message_id - ans["session_id"] = session_id - - def stream(): - nonlocal dia, msg, req, conv - try: - for ans in chat(dia, msg, **req): - fillin_conv(ans) - yield "data:" + json.dumps({"code": 0, "data": ans}, ensure_ascii=False) + "\n\n" - ConversationService.update_by_id(conv.id, conv.to_dict()) - except Exception as e: - yield "data:" + json.dumps({"code": 500, "message": str(e), - "data": {"answer": "**ERROR**: " + str(e), "reference": []}}, - ensure_ascii=False) + "\n\n" - yield "data:" + json.dumps({"code": 0, "data": True}, ensure_ascii=False) + "\n\n" - if req.get("stream", True): - resp = Response(stream(), mimetype="text/event-stream") + resp = Response(rag_completion(tenant_id, chat_id, **req), mimetype="text/event-stream") resp.headers.add_header("Cache-control", "no-cache") resp.headers.add_header("Connection", "keep-alive") resp.headers.add_header("X-Accel-Buffering", "no") @@ -212,172 +124,26 @@ def stream(): else: answer = None - for ans in chat(dia, msg, **req): + for ans in rag_completion(tenant_id, chat_id, **req): answer = ans - fillin_conv(ans) - ConversationService.update_by_id(conv.id, conv.to_dict()) break return get_result(data=answer) @manager.route('/agents//completions', methods=['POST']) # noqa: F821 @token_required -def agent_completion(tenant_id, agent_id): +def agent_completions(tenant_id, agent_id): req = request.json - - e, cvs = UserCanvasService.get_by_id(agent_id) - if not e: - return get_error_data_result("Agent not found.") - if cvs.user_id != tenant_id: - return get_error_data_result(message="You do not own the agent.") - if not isinstance(cvs.dsl, str): - cvs.dsl = json.dumps(cvs.dsl, ensure_ascii=False) - canvas = Canvas(cvs.dsl, tenant_id) - - if not req.get("session_id"): - session_id = get_uuid() - conv = { - "id": session_id, - "dialog_id": cvs.id, - "user_id": req.get("user_id", ""), - "message": [{"role": "assistant", "content": canvas.get_prologue()}], - "source": "agent", - "dsl": json.loads(cvs.dsl) - } - API4ConversationService.save(**conv) - conv = API4Conversation(**conv) - else: - session_id = req.get("session_id") - e, conv = API4ConversationService.get_by_id(req["session_id"]) - if not e: - return get_error_data_result(message="Session not found!") - canvas = Canvas(json.dumps(conv.dsl), tenant_id) - - messages = conv.message - question = req.get("question") - if not question: - return get_error_data_result("`question` is required.") - question = { - "role": "user", - "content": question, - "id": str(uuid4()) - } - messages.append(question) - msg = [] - for m in messages: - if m["role"] == "system": - continue - if m["role"] == "assistant" and not msg: - continue - msg.append(m) - if not msg[-1].get("id"): - msg[-1]["id"] = get_uuid() - message_id = msg[-1]["id"] - - stream = req.get("stream", True) - - def fillin_conv(ans): - reference = ans["reference"] - temp_reference = deepcopy(ans["reference"]) - nonlocal conv, message_id - if not conv.reference: - conv.reference.append(temp_reference) - else: - conv.reference[-1] = temp_reference - conv.message[-1] = {"role": "assistant", "content": ans["answer"], "id": message_id} - if "chunks" in reference: - chunks = reference.get("chunks") - chunk_list = [] - for chunk in chunks: - new_chunk = { - "id": chunk["chunk_id"], - "content": chunk["content"], - "document_id": chunk["doc_id"], - "document_name": chunk["docnm_kwd"], - "dataset_id": chunk["kb_id"], - "image_id": chunk["image_id"], - "similarity": chunk["similarity"], - "vector_similarity": chunk["vector_similarity"], - "term_similarity": chunk["term_similarity"], - "positions": chunk["positions"], - } - chunk_list.append(new_chunk) - reference["chunks"] = chunk_list - ans["id"] = message_id - ans["session_id"] = session_id - - def rename_field(ans): - reference = ans['reference'] - if not isinstance(reference, dict): - return - for chunk_i in reference.get('chunks', []): - if 'docnm_kwd' in chunk_i: - chunk_i['doc_name'] = chunk_i['docnm_kwd'] - chunk_i.pop('docnm_kwd') - - if not conv.reference: - conv.reference = [] - conv.message.append({"role": "assistant", "content": "", "id": message_id}) - conv.reference.append({"chunks": [], "doc_aggs": []}) - - final_ans = {"reference": [], "content": ""} - - canvas.add_user_input(msg[-1]["content"]) - - if stream: - def sse(): - nonlocal answer, cvs - try: - for ans in canvas.run(stream=stream): - if ans.get("running_status"): - yield "data:" + json.dumps({"code": 0, "message": "", - "data": {"answer": ans["content"], - "running_status": True}}, - ensure_ascii=False) + "\n\n" - continue - for k in ans.keys(): - final_ans[k] = ans[k] - ans = {"answer": ans["content"], "reference": ans.get("reference", [])} - fillin_conv(ans) - rename_field(ans) - yield "data:" + json.dumps({"code": 0, "message": "", "data": ans}, - ensure_ascii=False) + "\n\n" - - canvas.messages.append({"role": "assistant", "content": final_ans["content"], "id": message_id}) - canvas.history.append(("assistant", final_ans["content"])) - if final_ans.get("reference"): - canvas.reference.append(final_ans["reference"]) - conv.dsl = json.loads(str(canvas)) - API4ConversationService.append_message(conv.id, conv.to_dict()) - except Exception as e: - conv.dsl = json.loads(str(canvas)) - API4ConversationService.append_message(conv.id, conv.to_dict()) - yield "data:" + json.dumps({"code": 500, "message": str(e), - "data": {"answer": "**ERROR**: " + str(e), "reference": []}}, - ensure_ascii=False) + "\n\n" - yield "data:" + json.dumps({"code": 0, "message": "", "data": True}, ensure_ascii=False) + "\n\n" - - resp = Response(sse(), mimetype="text/event-stream") + if req.get("stream", True): + resp = Response(agent_completion(tenant_id, agent_id, **req), mimetype="text/event-stream") resp.headers.add_header("Cache-control", "no-cache") resp.headers.add_header("Connection", "keep-alive") resp.headers.add_header("X-Accel-Buffering", "no") resp.headers.add_header("Content-Type", "text/event-stream; charset=utf-8") return resp - for answer in canvas.run(stream=False): - if answer.get("running_status"): - continue - final_ans["content"] = "\n".join(answer["content"]) if "content" in answer else "" - canvas.messages.append({"role": "assistant", "content": final_ans["content"], "id": message_id}) - if final_ans.get("reference"): - canvas.reference.append(final_ans["reference"]) - conv.dsl = json.loads(str(canvas)) - - result = {"answer": final_ans["content"], "reference": final_ans.get("reference", [])} - fillin_conv(result) - API4ConversationService.append_message(conv.id, conv.to_dict()) - rename_field(result) - return get_result(data=result) + for answer in agent_completion(tenant_id, agent_id, **req): + return get_result(data=answer) @manager.route('/chats//sessions', methods=['GET']) # noqa: F821 @@ -591,3 +357,57 @@ def related_questions(tenant_id): Related search terms: """}], {"temperature": 0.9}) return get_result(data=[re.sub(r"^[0-9]\. ", "", a) for a in ans.split("\n") if re.match(r"^[0-9]\. ", a)]) + + +@manager.route('/chatbots//completions', methods=['POST']) # noqa: F821 +def chatbot_completions(dialog_id): + req = request.json + + token = request.headers.get('Authorization').split() + if len(token) != 2: + return get_error_data_result(message='Authorization is not valid!"') + token = token[1] + objs = APIToken.query(beta=token) + if not objs: + return get_error_data_result(message='Token is not valid!"') + + if "quote" not in req: + req["quote"] = False + + if req.get("stream", True): + resp = Response(iframe_completion(objs[0].tenant_id, dialog_id, **req), mimetype="text/event-stream") + resp.headers.add_header("Cache-control", "no-cache") + resp.headers.add_header("Connection", "keep-alive") + resp.headers.add_header("X-Accel-Buffering", "no") + resp.headers.add_header("Content-Type", "text/event-stream; charset=utf-8") + return resp + + for answer in agent_completion(objs[0].tenant_id, dialog_id, **req): + return get_result(data=answer) + + +@manager.route('/agentbots//completions', methods=['POST']) # noqa: F821 +def agent_bot_completions(agent_id): + req = request.json + + token = request.headers.get('Authorization').split() + if len(token) != 2: + return get_error_data_result(message='Authorization is not valid!"') + token = token[1] + objs = APIToken.query(beta=token) + if not objs: + return get_error_data_result(message='Token is not valid!"') + + if "quote" not in req: + req["quote"] = False + + if req.get("stream", True): + resp = Response(agent_completion(objs[0].tenant_id, agent_id, **req), mimetype="text/event-stream") + resp.headers.add_header("Cache-control", "no-cache") + resp.headers.add_header("Connection", "keep-alive") + resp.headers.add_header("X-Accel-Buffering", "no") + resp.headers.add_header("Content-Type", "text/event-stream; charset=utf-8") + return resp + + for answer in agent_completion(objs[0].tenant_id, agent_id, **req): + return get_result(data=answer) diff --git a/api/apps/system_app.py b/api/apps/system_app.py index 7b715f14b1c..28b74d65820 100644 --- a/api/apps/system_app.py +++ b/api/apps/system_app.py @@ -205,6 +205,7 @@ def new_token(): obj = { "tenant_id": tenant_id, "token": generate_confirmation_token(tenant_id), + "beta": generate_confirmation_token(generate_confirmation_token(tenant_id)).replace("ragflow-", "")[:32], "create_time": current_timestamp(), "create_date": datetime_format(datetime.now()), "update_time": None, diff --git a/api/db/db_models.py b/api/db/db_models.py index 0c052ca18a4..0c4d12c034c 100644 --- a/api/db/db_models.py +++ b/api/db/db_models.py @@ -934,6 +934,7 @@ class APIToken(DataBaseModel): token = CharField(max_length=255, null=False, index=True) dialog_id = CharField(max_length=32, null=False, index=True) source = CharField(max_length=16, null=True, help_text="none|agent|dialog", index=True) + beta = CharField(max_length=255, null=True, index=True) class Meta: db_table = "api_token" @@ -1083,4 +1084,10 @@ def migrate_db(): ) except Exception: pass + try: + migrate( + migrator.add_column("api_token", "beta", CharField(max_length=255, null=True, index=True)) + ) + except Exception: + pass diff --git a/api/db/services/canvas_service.py b/api/db/services/canvas_service.py index 0fac2f24850..e7aada1fdef 100644 --- a/api/db/services/canvas_service.py +++ b/api/db/services/canvas_service.py @@ -13,8 +13,14 @@ # See the License for the specific language governing permissions and # limitations under the License. # +import json +from uuid import uuid4 +from agent.canvas import Canvas from api.db.db_models import DB, CanvasTemplate, UserCanvas +from api.db.services.api_service import API4ConversationService from api.db.services.common_service import CommonService +from api.db.services.conversation_service import structure_answer +from api.utils import get_uuid class CanvasTemplateService(CommonService): @@ -42,3 +48,115 @@ def get_list(cls, tenant_id, agents = agents.paginate(page_number, items_per_page) return list(agents.dicts()) + + +def completion(tenant_id, agent_id, question, session_id=None, stream=True, **kwargs): + e, cvs = UserCanvasService.get_by_id(agent_id) + assert e, "Agent not found." + assert cvs.user_id == tenant_id, "You do not own the agent." + + if not isinstance(cvs.dsl, str): + cvs.dsl = json.dumps(cvs.dsl, ensure_ascii=False) + canvas = Canvas(cvs.dsl, tenant_id) + + if not session_id: + session_id = get_uuid() + conv = { + "id": session_id, + "dialog_id": cvs.id, + "user_id": kwargs.get("user_id", ""), + "message": [{"role": "assistant", "content": canvas.get_prologue()}], + "source": "agent", + "dsl": json.loads(cvs.dsl) + } + API4ConversationService.save(**conv) + yield "data:" + json.dumps({"code": 0, + "message": "", + "data": { + "session_id": session_id, + "answer": canvas.get_prologue(), + "reference": [], + "param": canvas.get_preset_param() + } + }, + ensure_ascii=False) + "\n\n" + yield "data:" + json.dumps({"code": 0, "message": "", "data": True}, ensure_ascii=False) + "\n\n" + return + else: + session_id = session_id + e, conv = API4ConversationService.get_by_id(session_id) + assert e, "Session not found!" + canvas = Canvas(json.dumps(conv.dsl), tenant_id) + + messages = conv.message + question = { + "role": "user", + "content": question, + "id": str(uuid4()) + } + messages.append(question) + msg = [] + for m in messages: + if m["role"] == "system": + continue + if m["role"] == "assistant" and not msg: + continue + msg.append(m) + if not msg[-1].get("id"): + msg[-1]["id"] = get_uuid() + message_id = msg[-1]["id"] + + if not conv.reference: + conv.reference = [] + conv.message.append({"role": "assistant", "content": "", "id": message_id}) + conv.reference.append({"chunks": [], "doc_aggs": []}) + + final_ans = {"reference": [], "content": ""} + + canvas.add_user_input(msg[-1]["content"]) + + if stream: + try: + for ans in canvas.run(stream=stream): + if ans.get("running_status"): + yield "data:" + json.dumps({"code": 0, "message": "", + "data": {"answer": ans["content"], + "running_status": True}}, + ensure_ascii=False) + "\n\n" + continue + for k in ans.keys(): + final_ans[k] = ans[k] + ans = {"answer": ans["content"], "reference": ans.get("reference", [])} + ans = structure_answer(conv, ans, message_id, session_id) + yield "data:" + json.dumps({"code": 0, "message": "", "data": ans}, + ensure_ascii=False) + "\n\n" + + canvas.messages.append({"role": "assistant", "content": final_ans["content"], "id": message_id}) + canvas.history.append(("assistant", final_ans["content"])) + if final_ans.get("reference"): + canvas.reference.append(final_ans["reference"]) + conv.dsl = json.loads(str(canvas)) + API4ConversationService.append_message(conv.id, conv.to_dict()) + except Exception as e: + conv.dsl = json.loads(str(canvas)) + API4ConversationService.append_message(conv.id, conv.to_dict()) + yield "data:" + json.dumps({"code": 500, "message": str(e), + "data": {"answer": "**ERROR**: " + str(e), "reference": []}}, + ensure_ascii=False) + "\n\n" + yield "data:" + json.dumps({"code": 0, "message": "", "data": True}, ensure_ascii=False) + "\n\n" + + else: + for answer in canvas.run(stream=False): + if answer.get("running_status"): + continue + final_ans["content"] = "\n".join(answer["content"]) if "content" in answer else "" + canvas.messages.append({"role": "assistant", "content": final_ans["content"], "id": message_id}) + if final_ans.get("reference"): + canvas.reference.append(final_ans["reference"]) + conv.dsl = json.loads(str(canvas)) + + result = {"answer": final_ans["content"], "reference": final_ans.get("reference", [])} + result = structure_answer(conv, result, message_id, session_id) + API4ConversationService.append_message(conv.id, conv.to_dict()) + yield result + break \ No newline at end of file diff --git a/api/db/services/conversation_service.py b/api/db/services/conversation_service.py new file mode 100644 index 00000000000..7844bcc6a87 --- /dev/null +++ b/api/db/services/conversation_service.py @@ -0,0 +1,221 @@ +# +# Copyright 2024 The InfiniFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +from uuid import uuid4 +from api.db import StatusEnum +from api.db.db_models import Conversation, DB +from api.db.services.api_service import API4ConversationService +from api.db.services.common_service import CommonService +from api.db.services.dialog_service import DialogService, chat +from api.utils import get_uuid +import json +from copy import deepcopy + + +class ConversationService(CommonService): + model = Conversation + + @classmethod + @DB.connection_context() + def get_list(cls,dialog_id,page_number, items_per_page, orderby, desc, id , name): + sessions = cls.model.select().where(cls.model.dialog_id ==dialog_id) + if id: + sessions = sessions.where(cls.model.id == id) + if name: + sessions = sessions.where(cls.model.name == name) + if desc: + sessions = sessions.order_by(cls.model.getter_by(orderby).desc()) + else: + sessions = sessions.order_by(cls.model.getter_by(orderby).asc()) + + sessions = sessions.paginate(page_number, items_per_page) + + return list(sessions.dicts()) + + +def structure_answer(conv, ans, message_id, session_id): + reference = ans["reference"] + temp_reference = deepcopy(ans["reference"]) + if not conv.reference: + conv.reference.append(temp_reference) + else: + conv.reference[-1] = temp_reference + conv.message[-1] = {"role": "assistant", "content": ans["answer"], "id": message_id} + + chunk_list = [{ + "id": chunk["chunk_id"], + "content": chunk["content"], + "document_id": chunk["doc_id"], + "document_name": chunk["docnm_kwd"], + "dataset_id": chunk["kb_id"], + "image_id": chunk["image_id"], + "similarity": chunk["similarity"], + "vector_similarity": chunk["vector_similarity"], + "term_similarity": chunk["term_similarity"], + "positions": chunk["positions"], + } for chunk in reference.get("chunks", [])] + + reference["chunks"] = chunk_list + ans["id"] = message_id + ans["session_id"] = session_id + + return ans + + +def completion(tenant_id, chat_id, question, name="New session", session_id=None, stream=True, **kwargs): + assert name, "`name` can not be empty." + dia = DialogService.query(id=chat_id, tenant_id=tenant_id, status=StatusEnum.VALID.value) + assert dia, "You do not own the chat." + + if not session_id: + conv = { + "id": get_uuid(), + "dialog_id": chat_id, + "name": name, + "message": [{"role": "assistant", "content": dia[0].prompt_config.get("prologue")}] + } + ConversationService.save(**conv) + yield "data:" + json.dumps({"code": 0, "message": "", + "data": { + "answer": conv["message"][0]["content"], + "reference": {}, + "audio_binary": None, + "id": None, + "session_id": session_id + }}, + ensure_ascii=False) + "\n\n" + yield "data:" + json.dumps({"code": 0, "message": "", "data": True}, ensure_ascii=False) + "\n\n" + return + + conv = ConversationService.query(id=session_id, dialog_id=chat_id) + if not conv: + raise LookupError("Session does not exist") + + conv = conv[0] + msg = [] + question = { + "content": question, + "role": "user", + "id": str(uuid4()) + } + conv.message.append(question) + for m in conv.message: + if m["role"] == "system": + continue + if m["role"] == "assistant" and not msg: + continue + msg.append(m) + message_id = msg[-1].get("id") + e, dia = DialogService.get_by_id(conv.dialog_id) + + if not conv.reference: + conv.reference = [] + conv.message.append({"role": "assistant", "content": "", "id": message_id}) + conv.reference.append({"chunks": [], "doc_aggs": []}) + + if stream: + try: + for ans in chat(dia, msg, True, **kwargs): + ans = structure_answer(conv, ans, message_id, session_id) + yield "data:" + json.dumps({"code": 0, "data": ans}, ensure_ascii=False) + "\n\n" + ConversationService.update_by_id(conv.id, conv.to_dict()) + except Exception as e: + yield "data:" + json.dumps({"code": 500, "message": str(e), + "data": {"answer": "**ERROR**: " + str(e), "reference": []}}, + ensure_ascii=False) + "\n\n" + yield "data:" + json.dumps({"code": 0, "data": True}, ensure_ascii=False) + "\n\n" + + else: + answer = None + for ans in chat(dia, msg, False, **kwargs): + answer = structure_answer(conv, ans, message_id, session_id) + ConversationService.update_by_id(conv.id, conv.to_dict()) + break + yield answer + + +def iframe_completion(dialog_id, question, session_id=None, stream=True, **kwargs): + e, dia = DialogService.get_by_id(dialog_id) + assert e, "Dialog not found" + if not session_id: + session_id = get_uuid() + conv = { + "id": session_id, + "dialog_id": dialog_id, + "user_id": kwargs.get("user_id", ""), + "message": [{"role": "assistant", "content": dia.prompt_config["prologue"]}] + } + API4ConversationService.save(**conv) + yield "data:" + json.dumps({"code": 0, "message": "", + "data": { + "answer": conv["message"][0]["content"], + "reference": {}, + "audio_binary": None, + "id": None, + "session_id": session_id + }}, + ensure_ascii=False) + "\n\n" + yield "data:" + json.dumps({"code": 0, "message": "", "data": True}, ensure_ascii=False) + "\n\n" + return + else: + session_id = session_id + e, conv = API4ConversationService.get_by_id(session_id) + assert e, "Session not found!" + + messages = conv.message + question = { + "role": "user", + "content": question, + "id": str(uuid4()) + } + messages.append(question) + + msg = [] + for m in messages: + if m["role"] == "system": + continue + if m["role"] == "assistant" and not msg: + continue + msg.append(m) + if not msg[-1].get("id"): + msg[-1]["id"] = get_uuid() + message_id = msg[-1]["id"] + + if not conv.reference: + conv.reference = [] + conv.message.append({"role": "assistant", "content": "", "id": message_id}) + conv.reference.append({"chunks": [], "doc_aggs": []}) + + if stream: + try: + for ans in chat(dia, msg, True, **kwargs): + ans = structure_answer(conv, ans, message_id, session_id) + yield "data:" + json.dumps({"code": 0, "message": "", "data": ans}, + ensure_ascii=False) + "\n\n" + API4ConversationService.append_message(conv.id, conv.to_dict()) + except Exception as e: + yield "data:" + json.dumps({"code": 500, "message": str(e), + "data": {"answer": "**ERROR**: " + str(e), "reference": []}}, + ensure_ascii=False) + "\n\n" + yield "data:" + json.dumps({"code": 0, "message": "", "data": True}, ensure_ascii=False) + "\n\n" + + else: + answer = None + for ans in chat(dia, msg, False, **kwargs): + answer = structure_answer(conv, ans, message_id, session_id) + API4ConversationService.append_message(conv.id, conv.to_dict()) + break + yield answer + diff --git a/api/db/services/dialog_service.py b/api/db/services/dialog_service.py index a092a50cad7..cd22fdc26c4 100644 --- a/api/db/services/dialog_service.py +++ b/api/db/services/dialog_service.py @@ -23,7 +23,7 @@ import datetime from datetime import timedelta from api.db import LLMType, ParserType,StatusEnum -from api.db.db_models import Dialog, Conversation,DB +from api.db.db_models import Dialog, DB from api.db.services.common_service import CommonService from api.db.services.knowledgebase_service import KnowledgebaseService from api.db.services.llm_service import LLMService, TenantLLMService, LLMBundle @@ -61,27 +61,6 @@ def get_list(cls, tenant_id, return list(chats.dicts()) -class ConversationService(CommonService): - model = Conversation - - @classmethod - @DB.connection_context() - def get_list(cls,dialog_id,page_number, items_per_page, orderby, desc, id , name): - sessions = cls.model.select().where(cls.model.dialog_id ==dialog_id) - if id: - sessions = sessions.where(cls.model.id == id) - if name: - sessions = sessions.where(cls.model.name == name) - if desc: - sessions = sessions.order_by(cls.model.getter_by(orderby).desc()) - else: - sessions = sessions.order_by(cls.model.getter_by(orderby).asc()) - - sessions = sessions.paginate(page_number, items_per_page) - - return list(sessions.dicts()) - - def message_fit_in(msg, max_length=4000): def count(): nonlocal msg diff --git a/api/db/services/document_service.py b/api/db/services/document_service.py index aea4931ebf3..f4b6f6874b8 100644 --- a/api/db/services/document_service.py +++ b/api/db/services/document_service.py @@ -425,11 +425,12 @@ def new_task(): def doc_upload_and_parse(conversation_id, file_objs, user_id): from rag.app import presentation, picture, naive, audio, email - from api.db.services.dialog_service import ConversationService, DialogService + from api.db.services.dialog_service import DialogService from api.db.services.file_service import FileService from api.db.services.llm_service import LLMBundle from api.db.services.user_service import TenantService from api.db.services.api_service import API4ConversationService + from api.db.services.conversation_service import ConversationService e, conv = ConversationService.get_by_id(conversation_id) if not e: diff --git a/docker/.env b/docker/.env index 7a8eb62d339..f8ad038a181 100644 --- a/docker/.env +++ b/docker/.env @@ -80,13 +80,13 @@ REDIS_PASSWORD=infini_rag_flow SVR_HTTP_PORT=9380 # The RAGFlow Docker image to download. -# Defaults to the dev-slim edition, which is the RAGFlow Docker image without embedding models. -RAGFLOW_IMAGE=infiniflow/ragflow:dev +# Defaults to the v0.14.1-slim edition, which is the RAGFlow Docker image without embedding models. +RAGFLOW_IMAGE=infiniflow/ragflow:v0.14.1-slim # # To download the RAGFlow Docker image with embedding models, uncomment the following line instead: -# RAGFLOW_IMAGE=infiniflow/ragflow:dev +# RAGFLOW_IMAGE=infiniflow/ragflow:v0.14.1 # -# The Docker image of the dev edition includes: +# The Docker image of the v0.14.1 edition includes: # - Built-in embedding models: # - BAAI/bge-large-zh-v1.5 # - BAAI/bge-reranker-v2-m3 @@ -107,13 +107,13 @@ RAGFLOW_IMAGE=infiniflow/ragflow:dev # If you cannot download the RAGFlow Docker image: # -# - For the `dev-slim` edition, uncomment either of the following: -# RAGFLOW_IMAGE=swr.cn-north-4.myhuaweicloud.com/infiniflow/ragflow:dev-slim -# RAGFLOW_IMAGE=registry.cn-hangzhou.aliyuncs.com/infiniflow/ragflow:dev-slim +# - For the `nightly-slim` edition, uncomment either of the following: +# RAGFLOW_IMAGE=swr.cn-north-4.myhuaweicloud.com/infiniflow/ragflow:nightly-slim +# RAGFLOW_IMAGE=registry.cn-hangzhou.aliyuncs.com/infiniflow/ragflow:nightly-slim # -# - For the `dev` edition, uncomment either of the following: -# RAGFLOW_IMAGE=swr.cn-north-4.myhuaweicloud.com/infiniflow/ragflow:dev -# RAGFLOW_IMAGE=registry.cn-hangzhou.aliyuncs.com/infiniflow/ragflow:dev +# - For the `nightly` edition, uncomment either of the following: +# RAGFLOW_IMAGE=swr.cn-north-4.myhuaweicloud.com/infiniflow/ragflow:nightly +# RAGFLOW_IMAGE=registry.cn-hangzhou.aliyuncs.com/infiniflow/ragflow:nightly # The local time zone. TIMEZONE='Asia/Shanghai' diff --git a/docker/README.md b/docker/README.md index 1813d2f5e81..5b95803fb0d 100644 --- a/docker/README.md +++ b/docker/README.md @@ -75,8 +75,8 @@ The [.env](./.env) file contains important environment variables for Docker. - `RAGFLOW-IMAGE` The Docker image edition. Available editions: - - `infiniflow/ragflow:dev-slim` (default): The RAGFlow Docker image without embedding models. - - `infiniflow/ragflow:dev`: The RAGFlow Docker image with embedding models including: + - `infiniflow/ragflow:v0.14.1-slim` (default): The RAGFlow Docker image without embedding models. + - `infiniflow/ragflow:v0.14.1`: The RAGFlow Docker image with embedding models including: - Built-in embedding models: - `BAAI/bge-large-zh-v1.5` - `BAAI/bge-reranker-v2-m3` @@ -95,12 +95,12 @@ The [.env](./.env) file contains important environment variables for Docker. > [!TIP] > If you cannot download the RAGFlow Docker image, try the following mirrors. > -> - For the `dev-slim` edition: -> - `RAGFLOW_IMAGE=swr.cn-north-4.myhuaweicloud.com/infiniflow/ragflow:dev-slim` or, -> - `RAGFLOW_IMAGE=registry.cn-hangzhou.aliyuncs.com/infiniflow/ragflow:dev-slim`. -> - For the `dev` edition: -> - `RAGFLOW_IMAGE=swr.cn-north-4.myhuaweicloud.com/infiniflow/ragflow:dev` or, -> - `RAGFLOW_IMAGE=registry.cn-hangzhou.aliyuncs.com/infiniflow/ragflow:dev`. +> - For the `nightly-slim` edition: +> - `RAGFLOW_IMAGE=swr.cn-north-4.myhuaweicloud.com/infiniflow/ragflow:nightly-slim` or, +> - `RAGFLOW_IMAGE=registry.cn-hangzhou.aliyuncs.com/infiniflow/ragflow:nightly-slim`. +> - For the `nightly` edition: +> - `RAGFLOW_IMAGE=swr.cn-north-4.myhuaweicloud.com/infiniflow/ragflow:nightly` or, +> - `RAGFLOW_IMAGE=registry.cn-hangzhou.aliyuncs.com/infiniflow/ragflow:nightly`. ### Timezone diff --git a/docs/configurations.md b/docs/configurations.md index 1ccb0d74bed..84c8388db89 100644 --- a/docs/configurations.md +++ b/docs/configurations.md @@ -93,8 +93,8 @@ The [.env](https://github.com/infiniflow/ragflow/blob/main/docker/.env) file con - `RAGFLOW-IMAGE` The Docker image edition. Available editions: - - `infiniflow/ragflow:dev-slim` (default): The RAGFlow Docker image without embedding models. - - `infiniflow/ragflow:dev`: The RAGFlow Docker image with embedding models including: + - `infiniflow/ragflow:v0.14.1-slim` (default): The RAGFlow Docker image without embedding models. + - `infiniflow/ragflow:v0.14.1`: The RAGFlow Docker image with embedding models including: - Built-in embedding models: - `BAAI/bge-large-zh-v1.5` - `BAAI/bge-reranker-v2-m3` @@ -113,12 +113,12 @@ The [.env](https://github.com/infiniflow/ragflow/blob/main/docker/.env) file con :::tip NOTE If you cannot download the RAGFlow Docker image, try the following mirrors. -- For the `dev-slim` edition: - - `RAGFLOW_IMAGE=swr.cn-north-4.myhuaweicloud.com/infiniflow/ragflow:dev-slim` or, - - `RAGFLOW_IMAGE=registry.cn-hangzhou.aliyuncs.com/infiniflow/ragflow:dev-slim`. -- For the `dev` edition: - - `RAGFLOW_IMAGE=swr.cn-north-4.myhuaweicloud.com/infiniflow/ragflow:dev` or, - - `RAGFLOW_IMAGE=registry.cn-hangzhou.aliyuncs.com/infiniflow/ragflow:dev`. +- For the `nightly-slim` edition: + - `RAGFLOW_IMAGE=swr.cn-north-4.myhuaweicloud.com/infiniflow/ragflow:nightly-slim` or, + - `RAGFLOW_IMAGE=registry.cn-hangzhou.aliyuncs.com/infiniflow/ragflow:nightly-slim`. +- For the `nightly` edition: + - `RAGFLOW_IMAGE=swr.cn-north-4.myhuaweicloud.com/infiniflow/ragflow:nightly` or, + - `RAGFLOW_IMAGE=registry.cn-hangzhou.aliyuncs.com/infiniflow/ragflow:nightly`. ::: ### Timezone diff --git a/docs/guides/develop/build_docker_image.mdx b/docs/guides/develop/build_docker_image.mdx index 3cfc1666fee..a653ca91fa5 100644 --- a/docs/guides/develop/build_docker_image.mdx +++ b/docs/guides/develop/build_docker_image.mdx @@ -31,7 +31,7 @@ A guide explaining how to build a RAGFlow Docker image from its source code. By ]}> -This image is approximately 1 GB in size and relies on external LLM and embedding services. +This image is approximately 2 GB in size and relies on external LLM and embedding services. :::tip NOTE While we also test RAGFlow on ARM64 platforms, we do not plan to maintain RAGFlow Docker images for ARM. However, you can build an image yourself on a `linux/arm64` or `darwin/arm64` host machine as well. @@ -40,7 +40,7 @@ While we also test RAGFlow on ARM64 platforms, we do not plan to maintain RAGFlo ```bash git clone https://github.com/infiniflow/ragflow.git cd ragflow/ -docker build --build-arg LIGHTEN=1 -f Dockerfile -t infiniflow/ragflow:dev-slim . +docker build --build-arg LIGHTEN=1 -f Dockerfile -t infiniflow/ragflow:nightly-slim . ``` @@ -56,7 +56,7 @@ While we also test RAGFlow on ARM64 platforms, we do not plan to maintain RAGFlo ```bash git clone https://github.com/infiniflow/ragflow.git cd ragflow/ -docker build -f Dockerfile -t infiniflow/ragflow:dev . +docker build -f Dockerfile -t infiniflow/ragflow:nightly . ``` diff --git a/docs/guides/upgrade_ragflow.mdx b/docs/guides/upgrade_ragflow.mdx index e329e579a3b..306cd7d0199 100644 --- a/docs/guides/upgrade_ragflow.mdx +++ b/docs/guides/upgrade_ragflow.mdx @@ -7,11 +7,11 @@ slug: /upgrade_ragflow import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; -Upgrade RAGFlow to `dev-slim`/`dev` or the latest, published release. +Upgrade RAGFlow to `nightly-slim`/`nightly` or the latest, published release. -## Upgrade RAGFlow to `dev-slim`/`dev`, the most recent, tested Docker image +## Upgrade RAGFlow to `nightly-slim`/`nightly`, the most recent, tested Docker image -`dev-slim` refers to the RAGFlow Docker image *without* embedding models, while `dev` refers to the RAGFlow Docker image with embedding models. For details on their differences, see [ragflow/docker/.env](https://github.com/infiniflow/ragflow/blob/main/docker/.env). +`nightly-slim` refers to the RAGFlow Docker image *without* embedding models, while `nightly` refers to the RAGFlow Docker image with embedding models. For details on their differences, see [ragflow/docker/.env](https://github.com/infiniflow/ragflow/blob/main/docker/.env). To upgrade RAGFlow, you must upgrade **both** your code **and** your Docker image: @@ -24,22 +24,22 @@ To upgrade RAGFlow, you must upgrade **both** your code **and** your Docker imag 2. Update **ragflow/docker/.env**: - + ```bash -RAGFLOW_IMAGE=infiniflow/ragflow:dev-slim +RAGFLOW_IMAGE=infiniflow/ragflow:nightly-slim ``` - + ```bash -RAGFLOW_IMAGE=infiniflow/ragflow:dev +RAGFLOW_IMAGE=infiniflow/ragflow:nightly ``` @@ -65,7 +65,7 @@ To upgrade RAGFlow, you must upgrade **both** your code **and** your Docker imag 2. Switch to the latest, officially published release, e.g., `v0.14.1`: ```bash - git checkout v0.14.1 + git checkout -f v0.14.1 ``` 3. Update **ragflow/docker/.env** as follows: diff --git a/docs/quickstart.mdx b/docs/quickstart.mdx index efa7c07cf40..6ee8f5d77db 100644 --- a/docs/quickstart.mdx +++ b/docs/quickstart.mdx @@ -177,20 +177,27 @@ This section provides instructions on setting up the RAGFlow server on Linux. If ```bash $ git clone https://github.com/infiniflow/ragflow.git + $ cd ragflow + $ git checkout -f v0.14.1 ``` -3. Build the pre-built Docker images and start up the server: +3. Use the pre-built Docker images and start up the server: - > The command below downloads the dev version Docker image for RAGFlow slim (`dev-slim`). Note that RAGFlow slim Docker images do not include embedding models or Python libraries and hence are approximately 1GB in size. + > The command below downloads the v0.14.1 version Docker image for RAGFlow slim (`v0.14.1-slim`). Note that RAGFlow slim Docker images do not include embedding models or Python libraries and hence are approximately 2 GB in size. ```bash - $ cd ragflow/docker - $ docker compose -f docker-compose.yml up -d + $ docker compose -f docker/docker-compose.yml up -d ``` - > - To download a RAGFlow slim Docker image of a specific version, update the `RAGFlOW_IMAGE` variable in **docker/.env** to your desired version. For example, `RAGFLOW_IMAGE=infiniflow/ragflow:v0.14.1-slim`. After making this change, rerun the command above to initiate the download. - > - To download the dev version of RAGFlow Docker image *including* embedding models and Python libraries, update the `RAGFlOW_IMAGE` variable in **docker/.env** to `RAGFLOW_IMAGE=infiniflow/ragflow:dev`. After making this change, rerun the command above to initiate the download. - > - To download a specific version of RAGFlow Docker image *including* embedding models and Python libraries, update the `RAGFlOW_IMAGE` variable in **docker/.env** to your desired version. For example, `RAGFLOW_IMAGE=infiniflow/ragflow:v0.14.1`. After making this change, rerun the command above to initiate the download. + | RAGFLOW_IMAGE tag in docker/.env | size | Including embedding models and related Python packages? | comments | + | -------------------------------- | ----- | ------------------------------------------------------- | ---------------------- | + | v0.14.1 | ~9 GB | YES | stable release | + | v0.14.1-slim | ~2 GB | NO | stable release | + | v0.15.0-dev1 | ~9 GB | YES | unstable beta release | + | v0.15.0-dev1-slim | ~2 GB | NO | unstable beta release | + | nightly | ~9 GB | YES | unstable nightly build | + | nightly-slim | ~2 GB | NO | unstable nightly build | + :::tip NOTE A RAGFlow Docker image that includes embedding models and Python libraries is approximately 9GB in size and may take significantly longer time to load. diff --git a/docs/references/faq.md b/docs/references/faq.md index 60d38280d3f..842a6185ab7 100644 --- a/docs/references/faq.md +++ b/docs/references/faq.md @@ -42,10 +42,10 @@ We officially support x86 CPU and nvidia GPU. While we also test RAGFlow on ARM6 ### Which embedding models can be deployed locally? -RAGFlow offers two Docker image editions, `dev-slim` and `dev`: +RAGFlow offers two Docker image editions, `v0.14.1-slim` and `v0.14.1`: -- `infiniflow/ragflow:dev-slim` (default): The RAGFlow Docker image without embedding models. -- `infiniflow/ragflow:dev`: The RAGFlow Docker image with embedding models including: +- `infiniflow/ragflow:v0.14.1-slim` (default): The RAGFlow Docker image without embedding models. +- `infiniflow/ragflow:v0.14.1`: The RAGFlow Docker image with embedding models including: - Built-in embedding models: - `BAAI/bge-large-zh-v1.5` - `BAAI/bge-reranker-v2-m3` diff --git a/docs/release_notes.md b/docs/release_notes.md index a5463015e13..91f3a9e7195 100644 --- a/docs/release_notes.md +++ b/docs/release_notes.md @@ -102,11 +102,11 @@ Released on September 30, 2024. As of this release, RAGFlow offers slim editions of its Docker images to improve the experience for users with limited Internet access. A slim edition of RAGFlow's Docker image does not include built-in BGE/BCE embedding models and has a size of about 1GB; a full edition of RAGFlow is approximately 9GB and includes both built-in embedding models and embedding models that will be downloaded once you select them in the RAGFlow UI. -The default Docker image edition is `dev-slim`. The following list clarifies the differences between various editions: +The default Docker image edition is `nightly-slim`. The following list clarifies the differences between various editions: -- `dev-slim`: The slim edition of the most recent tested Docker image. +- `nightly-slim`: The slim edition of the most recent tested Docker image. - `v0.12.0-slim`: The slim edition of the most recent **officially released** Docker image. -- `dev`: The full edition of the most recent tested Docker image. +- `nightly`: The full edition of the most recent tested Docker image. - `v0.12.0`: The full edition of the most recent **officially released** Docker image. See [Upgrade RAGFlow](https://ragflow.io/docs/dev/upgrade_ragflow) for instructions on upgrading. diff --git a/helm/values.yaml b/helm/values.yaml index 66f94c004b6..3eaafc48e79 100644 --- a/helm/values.yaml +++ b/helm/values.yaml @@ -27,13 +27,13 @@ env: REDIS_PASSWORD: infini_rag_flow_helm # The RAGFlow Docker image to download. - # Defaults to the dev-slim edition, which is the RAGFlow Docker image without embedding models. - RAGFLOW_IMAGE: infiniflow/ragflow:dev-slim + # Defaults to the v0.14.1-slim edition, which is the RAGFlow Docker image without embedding models. + RAGFLOW_IMAGE: infiniflow/ragflow:v0.14.1-slim # # To download the RAGFlow Docker image with embedding models, uncomment the following line instead: - # RAGFLOW_IMAGE=infiniflow/ragflow:dev + # RAGFLOW_IMAGE=infiniflow/ragflow:v0.14.1 # - # The Docker image of the dev edition includes: + # The Docker image of the v0.14.1 edition includes: # - Built-in embedding models: # - BAAI/bge-large-zh-v1.5 # - BAAI/bge-reranker-v2-m3 diff --git a/rag/llm/cv_model.py b/rag/llm/cv_model.py index 33d8a79704e..11df9660a78 100644 --- a/rag/llm/cv_model.py +++ b/rag/llm/cv_model.py @@ -25,7 +25,6 @@ from io import BytesIO import json import requests -from transformers import GenerationConfig from rag.nlp import is_english from api.utils import get_uuid @@ -513,6 +512,7 @@ def describe(self, image, max_tokens=2048): return res.text,res.usage_metadata.total_token_count def chat(self, system, history, gen_conf, image=""): + from transformers import GenerationConfig if system: history[-1]["content"] = system + history[-1]["content"] + "user query: " + history[-1]["content"] try: @@ -536,6 +536,7 @@ def chat(self, system, history, gen_conf, image=""): return "**ERROR**: " + str(e), 0 def chat_streamly(self, system, history, gen_conf, image=""): + from transformers import GenerationConfig if system: history[-1]["content"] = system + history[-1]["content"] + "user query: " + history[-1]["content"] diff --git a/rag/svr/task_executor.py b/rag/svr/task_executor.py index aed8b7fa4a3..a8061a817f1 100644 --- a/rag/svr/task_executor.py +++ b/rag/svr/task_executor.py @@ -273,7 +273,7 @@ def embedding(docs, mdl, parser_config=None, callback=None): batch_size = 16 tts, cnts = [], [] for d in docs: - tts.append(rmSpace(d["title_tks"])) + tts.append(rmSpace(d.get("docnm_kwd", "Title"))) c = "\n".join(d.get("question_kwd", [])) if not c: c = d["content_with_weight"]