From a3391c4d550d9d8899feffe30be1399ea2b6a6fe Mon Sep 17 00:00:00 2001 From: balibabu Date: Mon, 20 Jan 2025 16:49:45 +0800 Subject: [PATCH 1/9] Feat: Rename document name #3221 (#4544) ### What problem does this PR solve? Feat: Rename document name #3221 ### Type of change - [x] New Feature (non-breaking change which adds functionality) --- web/src/components/rename-dialog/index.tsx | 56 ++++++------- .../components/rename-dialog/rename-form.tsx | 79 +++++++++++++++++++ web/src/pages/files/action-cell.tsx | 43 ++++++++-- web/src/pages/files/files-table.tsx | 24 +++++- web/src/pages/files/hooks.ts | 4 + 5 files changed, 164 insertions(+), 42 deletions(-) create mode 100644 web/src/components/rename-dialog/rename-form.tsx diff --git a/web/src/components/rename-dialog/index.tsx b/web/src/components/rename-dialog/index.tsx index 369b726fa87..97c48f0e685 100644 --- a/web/src/components/rename-dialog/index.tsx +++ b/web/src/components/rename-dialog/index.tsx @@ -1,49 +1,39 @@ -import { Button } from '@/components/ui/button'; import { Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle, - DialogTrigger, } from '@/components/ui/dialog'; -import { Input } from '@/components/ui/input'; -import { Label } from '@/components/ui/label'; +import { LoadingButton } from '@/components/ui/loading-button'; +import { IModalProps } from '@/interfaces/common'; +import { TagRenameId } from '@/pages/add-knowledge/constant'; +import { useTranslation } from 'react-i18next'; +import { RenameForm } from './rename-form'; + +export function RenameDialog({ + hideModal, + initialName, + onOk, + loading, +}: IModalProps & { initialName: string }) { + const { t } = useTranslation(); -export function RenameDialog() { return ( - - - - + - Edit profile + {t('common.rename')} -
-
- - -
-
- - -
-
+ - + + {t('common.save')} +
diff --git a/web/src/components/rename-dialog/rename-form.tsx b/web/src/components/rename-dialog/rename-form.tsx new file mode 100644 index 00000000000..27af77bd9db --- /dev/null +++ b/web/src/components/rename-dialog/rename-form.tsx @@ -0,0 +1,79 @@ +'use client'; + +import { zodResolver } from '@hookform/resolvers/zod'; +import { useForm } from 'react-hook-form'; +import { z } from 'zod'; + +import { + Form, + FormControl, + FormField, + FormItem, + FormLabel, + FormMessage, +} from '@/components/ui/form'; +import { Input } from '@/components/ui/input'; +import { IModalProps } from '@/interfaces/common'; +import { TagRenameId } from '@/pages/add-knowledge/constant'; +import { useEffect } from 'react'; +import { useTranslation } from 'react-i18next'; + +export function RenameForm({ + initialName, + hideModal, + onOk, +}: IModalProps & { initialName: string }) { + const { t } = useTranslation(); + const FormSchema = z.object({ + name: z + .string() + .min(1, { + message: t('common.namePlaceholder'), + }) + .trim(), + }); + + const form = useForm>({ + resolver: zodResolver(FormSchema), + defaultValues: { name: '' }, + }); + + async function onSubmit(data: z.infer) { + const ret = await onOk?.(data.name); + if (ret) { + hideModal?.(); + } + } + + useEffect(() => { + form.setValue('name', initialName); + }, [form, initialName]); + + return ( +
+ + ( + + {t('common.name')} + + + + + + )} + /> + + + ); +} diff --git a/web/src/pages/files/action-cell.tsx b/web/src/pages/files/action-cell.tsx index f56d596e606..d91422fe264 100644 --- a/web/src/pages/files/action-cell.tsx +++ b/web/src/pages/files/action-cell.tsx @@ -4,26 +4,49 @@ import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, - DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger, } from '@/components/ui/dropdown-menu'; +import { useDownloadFile } from '@/hooks/file-manager-hooks'; import { IFile } from '@/interfaces/database/file-manager'; import { CellContext } from '@tanstack/react-table'; import { EllipsisVertical, Link2, Trash2 } from 'lucide-react'; import { useCallback } from 'react'; -import { UseHandleConnectToKnowledgeReturnType } from './hooks'; +import { useTranslation } from 'react-i18next'; +import { + UseHandleConnectToKnowledgeReturnType, + UseRenameCurrentFileReturnType, +} from './hooks'; type IProps = Pick, 'row'> & - Pick; + Pick & + Pick; -export function ActionCell({ row, showConnectToKnowledgeModal }: IProps) { +export function ActionCell({ + row, + showConnectToKnowledgeModal, + showFileRenameModal, +}: IProps) { + const { t } = useTranslation(); const record = row.original; + const documentId = record.id; + const { downloadFile } = useDownloadFile(); const handleShowConnectToKnowledgeModal = useCallback(() => { showConnectToKnowledgeModal(record); }, [record, showConnectToKnowledgeModal]); + const onDownloadDocument = useCallback(() => { + downloadFile({ + id: documentId, + filename: record.name, + }); + }, [documentId, downloadFile, record.name]); + + const handleShowFileRenameModal = useCallback(() => { + showFileRenameModal(record); + }, [record, showFileRenameModal]); + return (
diff --git a/web/src/pages/files/files-table.tsx b/web/src/pages/files/files-table.tsx index d22420eb1e3..ed3f7643956 100644 --- a/web/src/pages/files/files-table.tsx +++ b/web/src/pages/files/files-table.tsx @@ -14,6 +14,7 @@ import { import { ArrowUpDown } from 'lucide-react'; import * as React from 'react'; +import { RenameDialog } from '@/components/rename-dialog'; import SvgIcon from '@/components/svg-icon'; import { TableEmpty, TableSkeleton } from '@/components/table-skeleton'; import { Badge } from '@/components/ui/badge'; @@ -41,7 +42,11 @@ import { getExtension } from '@/utils/document-util'; import { useMemo } from 'react'; import { useTranslation } from 'react-i18next'; import { ActionCell } from './action-cell'; -import { useHandleConnectToKnowledge, useNavigateToOtherFolder } from './hooks'; +import { + useHandleConnectToKnowledge, + useNavigateToOtherFolder, + useRenameCurrentFile, +} from './hooks'; import { LinkToDatasetDialog } from './link-to-dataset-dialog'; export function FilesTable() { @@ -64,6 +69,14 @@ export function FilesTable() { onConnectToKnowledgeOk, connectToKnowledgeLoading, } = useHandleConnectToKnowledge(); + const { + fileRenameVisible, + showFileRenameModal, + hideFileRenameModal, + onFileRenameOk, + initialFileName, + fileRenameLoading, + } = useRenameCurrentFile(); const { pagination, data, loading, setPagination } = useFetchFileList(); @@ -208,6 +221,7 @@ export function FilesTable() { ); }, @@ -341,6 +355,14 @@ export function FilesTable() { loading={connectToKnowledgeLoading} > )} + {fileRenameVisible && ( + + )} ); } diff --git a/web/src/pages/files/hooks.ts b/web/src/pages/files/hooks.ts index 9a891d711ba..3b13e719edb 100644 --- a/web/src/pages/files/hooks.ts +++ b/web/src/pages/files/hooks.ts @@ -90,6 +90,10 @@ export const useRenameCurrentFile = () => { }; }; +export type UseRenameCurrentFileReturnType = ReturnType< + typeof useRenameCurrentFile +>; + export const useSelectBreadcrumbItems = () => { const parentFolderList = useFetchParentFolderList(); From 99430a7db71fbc42dba9da44beb1f30ccb1990d0 Mon Sep 17 00:00:00 2001 From: writinwaters <93570324+writinwaters@users.noreply.github.com> Date: Mon, 20 Jan 2025 19:54:02 +0800 Subject: [PATCH 2/9] Added description of the Concentrator component (#4549) ### What problem does this PR solve? ### Type of change - [x] Documentation Update --- .../concentrator.mdx | 26 +++++++++++++++++++ .../agent_component_reference/switch.mdx | 2 +- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/docs/references/agent_component_reference/concentrator.mdx b/docs/references/agent_component_reference/concentrator.mdx index e69de29bb2d..fbc24695a5e 100644 --- a/docs/references/agent_component_reference/concentrator.mdx +++ b/docs/references/agent_component_reference/concentrator.mdx @@ -0,0 +1,26 @@ +--- +sidebar_position: 10 +slug: /concentrator_component +--- + +# Concentrator component + +A component that directs execution flow to multiple downstream components. + +--- + +The **Concentrator** component acts as a "repeater" of execution flow, transmitting a flow to multiple downstream components. + + +## Scenarios + +A **Concentrator** component enhances the current UX design. For a component originally designed to support only one downstream component, you can append a **Concentrator**, enabling it to have multiple downstream components. + +## Examples + +Explore our general-purpose chatbot agent template, featuring a **Concentrator** component (component ID: **medical**) that relays an execution flow from category 2 of the **Categorize** component to the two translator components: + +1. Click the **Agent** tab at the top center of the page to access the **Agent** page. +2. Click **+ Create agent** on the top right of the page to open the **agent template** page. +3. On the **agent template** page, hover over the **General-purpose chatbot** card and click **Use this template**. +4. Name your new agent and click **OK** to enter the workflow editor. \ No newline at end of file diff --git a/docs/references/agent_component_reference/switch.mdx b/docs/references/agent_component_reference/switch.mdx index f2f709e37e0..085f35bf032 100644 --- a/docs/references/agent_component_reference/switch.mdx +++ b/docs/references/agent_component_reference/switch.mdx @@ -19,7 +19,7 @@ A **Switch** component is essential for condition-based direction of execution f ### Case n -A **Switch** component must have at least one case, each with multiple specified conditions and corresponding downstream components. When multiple conditions are specified for a case, you must set the logical relationship between them to either AND or OR. +A **Switch** component must have at least one case, each with multiple specified conditions and *only one* downstream component. When multiple conditions are specified for a case, you must set the logical relationship between them to either AND or OR. #### Next step From db803764276bff9d85df0ed58215c578b5d71c44 Mon Sep 17 00:00:00 2001 From: Zhichang Yu Date: Mon, 20 Jan 2025 22:49:46 +0800 Subject: [PATCH 3/9] Added entrypoint for task executor (#4551) ### What problem does this PR solve? Added entrypoint for task executor ### Type of change - [x] Refactoring --- Dockerfile | 4 ++-- docker/docker-compose.yml | 24 +++++++++++++++++++++++- docker/entrypoint.sh | 3 --- docker/entrypoint_task_executor.sh | 28 ++++++++++++++++++++++++++++ 4 files changed, 53 insertions(+), 6 deletions(-) create mode 100755 docker/entrypoint_task_executor.sh diff --git a/Dockerfile b/Dockerfile index 6b519073be8..ba274ddbb34 100644 --- a/Dockerfile +++ b/Dockerfile @@ -183,8 +183,8 @@ COPY graphrag graphrag COPY pyproject.toml uv.lock ./ COPY docker/service_conf.yaml.template ./conf/service_conf.yaml.template -COPY docker/entrypoint.sh ./entrypoint.sh -RUN chmod +x ./entrypoint.sh +COPY docker/entrypoint.sh docker/entrypoint_task_executor.sh ./ +RUN chmod +x ./entrypoint*.sh # Copy compiled web pages COPY --from=builder /ragflow/web/dist /ragflow/web/dist diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index 00901ddc7cf..676f167d6c7 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -26,6 +26,28 @@ services: - ragflow restart: on-failure # https://docs.docker.com/engine/daemon/prometheus/#create-a-prometheus-configuration - # If you're using Docker Desktop, the --add-host flag is optional. This flag makes sure that the host's internal IP gets exposed to the Prometheus container. + # If you're using Docker Desktop, the --add-host flag is optional. This flag makes sure that the host's internal IP gets exposed to the Prometheus container. extra_hosts: - "host.docker.internal:host-gateway" + # executor: + # depends_on: + # mysql: + # condition: service_healthy + # image: ${RAGFLOW_IMAGE} + # container_name: ragflow-executor + # volumes: + # - ./ragflow-logs:/ragflow/logs + # - ./nginx/ragflow.conf:/etc/nginx/conf.d/ragflow.conf + # env_file: .env + # environment: + # - TZ=${TIMEZONE} + # - HF_ENDPOINT=${HF_ENDPOINT} + # - MACOS=${MACOS} + # entrypoint: "/ragflow/entrypoint_task_executor.sh 1 3" + # networks: + # - ragflow + # restart: on-failure + # # https://docs.docker.com/engine/daemon/prometheus/#create-a-prometheus-configuration + # # If you're using Docker Desktop, the --add-host flag is optional. This flag makes sure that the host's internal IP gets exposed to the Prometheus container. + # extra_hosts: + # - "host.docker.internal:host-gateway" diff --git a/docker/entrypoint.sh b/docker/entrypoint.sh index 792bbca7a60..3881029601b 100755 --- a/docker/entrypoint.sh +++ b/docker/entrypoint.sh @@ -7,9 +7,6 @@ while IFS= read -r line || [[ -n "$line" ]]; do eval "echo \"$line\"" >> /ragflow/conf/service_conf.yaml done < /ragflow/conf/service_conf.yaml.template -# unset http proxy which maybe set by docker daemon -export http_proxy=""; export https_proxy=""; export no_proxy=""; export HTTP_PROXY=""; export HTTPS_PROXY=""; export NO_PROXY="" - /usr/sbin/nginx export LD_LIBRARY_PATH=/usr/lib/x86_64-linux-gnu/ diff --git a/docker/entrypoint_task_executor.sh b/docker/entrypoint_task_executor.sh new file mode 100755 index 00000000000..899f16f8fb9 --- /dev/null +++ b/docker/entrypoint_task_executor.sh @@ -0,0 +1,28 @@ +#!/bin/bash + +# replace env variables in the service_conf.yaml file +rm -rf /ragflow/conf/service_conf.yaml +while IFS= read -r line || [[ -n "$line" ]]; do + # Use eval to interpret the variable with default values + eval "echo \"$line\"" >> /ragflow/conf/service_conf.yaml +done < /ragflow/conf/service_conf.yaml.template + +export LD_LIBRARY_PATH=/usr/lib/x86_64-linux-gnu/ + +PY=python3 + +CONSUMER_NO_BEG=$1 +CONSUMER_NO_END=$2 + +function task_exe(){ + while [ 1 -eq 1 ]; do + $PY rag/svr/task_executor.py $1; + done +} + +for ((i=CONSUMER_NO_BEG; i Date: Tue, 21 Jan 2025 10:19:38 +0800 Subject: [PATCH 4/9] Feat: Make the scroll bar of the DatasetSettings page appear inside #3221 (#4548) ### What problem does this PR solve? Feat: Make the scroll bar of the DatasetSettings page appear inside #3221 ### Type of change - [x] New Feature (non-breaking change which adds functionality) --- web/src/global.less | 1 + web/src/pages/dataset/index.tsx | 2 +- web/src/pages/dataset/setting/index.tsx | 24 +++++---- web/src/pages/dataset/testing/index.tsx | 2 +- web/src/pages/profile-setting/model/index.tsx | 54 +++++++++---------- 5 files changed, 44 insertions(+), 39 deletions(-) diff --git a/web/src/global.less b/web/src/global.less index c95fdb0bdd9..58308ad737f 100644 --- a/web/src/global.less +++ b/web/src/global.less @@ -2,6 +2,7 @@ html { height: 100%; + overflow: hidden; // The content of the DatasetSettings page is too high, which will cause scroll bars to appear on the html tags. Setting the maximum height in DatasetSettings does not work either. I don't understand. } body { diff --git a/web/src/pages/dataset/index.tsx b/web/src/pages/dataset/index.tsx index d79abb76160..d1f65c7e3b4 100644 --- a/web/src/pages/dataset/index.tsx +++ b/web/src/pages/dataset/index.tsx @@ -3,7 +3,7 @@ import { SideBar } from './sidebar'; export default function DatasetWrapper() { return ( -
+
diff --git a/web/src/pages/dataset/setting/index.tsx b/web/src/pages/dataset/setting/index.tsx index 15f82ab9300..93278fc6d82 100644 --- a/web/src/pages/dataset/setting/index.tsx +++ b/web/src/pages/dataset/setting/index.tsx @@ -1,20 +1,24 @@ -import { Card } from '@/components/ui/card'; +import { Card, CardContent } from '@/components/ui/card'; import AdvancedSettingForm from './advanced-setting-form'; import BasicSettingForm from './basic-setting-form'; export default function DatasetSettings() { return ( -
-
Basic settings
- -
- -
+
+
Basic settings
+ + +
+ +
+
-
Advanced settings
- - +
Advanced settings
+ + + +
); diff --git a/web/src/pages/dataset/testing/index.tsx b/web/src/pages/dataset/testing/index.tsx index df7048f117d..1aab3572bac 100644 --- a/web/src/pages/dataset/testing/index.tsx +++ b/web/src/pages/dataset/testing/index.tsx @@ -16,7 +16,7 @@ export default function RetrievalTesting() {

15 Results from 3 files

-
+
{list.map((x, idx) => ( +

Team management

- + +
+
+ +
+

Added model

+
+ {addedModelList.map((x, idx) => ( + + ))} +
+
+
+
+

Model library

+ +
+
+ {modelLibraryList.map((x, idx) => ( + + ))} +
+
- -
-

Added model

-
- {addedModelList.map((x, idx) => ( - - ))} -
-
-
-
-

Model library

- -
-
- {modelLibraryList.map((x, idx) => ( - - ))} -
-
); } From 5632613eb50b5eb64eb562957d7c6781ff155d75 Mon Sep 17 00:00:00 2001 From: Henrique <44172470+henriquelca@users.noreply.github.com> Date: Tue, 21 Jan 2025 00:22:29 -0300 Subject: [PATCH 5/9] Add language portugese br (#4550) ### What problem does this PR solve? Add language Portugese from Brazil ### Type of change - [X] New Feature (non-breaking change which adds functionality) --- README.md | 40 +- README_id.md | 38 +- README_ja.md | 55 +- README_ko.md | 75 +- README_pt_br.md | 352 ++++++ README_tzh.md | 64 +- README_zh.md | 63 +- web/src/constants/common.ts | 3 + web/src/locales/config.ts | 8 +- web/src/locales/en.ts | 1 + web/src/locales/es.ts | 1 + web/src/locales/id.ts | 1 + web/src/locales/ja.ts | 1 + web/src/locales/pt-br.ts | 1099 +++++++++++++++++ web/src/locales/vi.ts | 1 + web/src/locales/zh-traditional.ts | 1 + web/src/locales/zh.ts | 1 + .../user-setting/setting-locale/index.tsx | 1 + 18 files changed, 1662 insertions(+), 143 deletions(-) create mode 100644 README_pt_br.md create mode 100644 web/src/locales/pt-br.ts diff --git a/README.md b/README.md index afb48edc3e0..0baac4bd38a 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,8 @@ 简体中文 | 日本語 | 한국어 | - Bahasa Indonesia + Bahasa Indonesia | + Português (Brasil)

@@ -68,6 +69,7 @@ data. ## 🎮 Demo Try our demo at [https://demo.ragflow.io](https://demo.ragflow.io). +

@@ -86,6 +88,7 @@ Try our demo at [https://demo.ragflow.io](https://demo.ragflow.io). ⭐️ Star our repository to stay up-to-date with exciting new features and improvements! Get instant notifications for new releases! 🌟 +
@@ -134,7 +137,7 @@ releases! 🌟 - Disk >= 50 GB - Docker >= 24.0.0 & Docker Compose >= v2.26.1 > If you have not installed Docker on your local machine (Windows, Mac, or Linux), - see [Install Docker Engine](https://docs.docker.com/engine/install/). + > see [Install Docker Engine](https://docs.docker.com/engine/install/). ### 🚀 Start up the server @@ -154,7 +157,7 @@ releases! 🌟 > ``` > > This change will be reset after a system reboot. To ensure your change remains permanent, add or update the - `vm.max_map_count` value in **/etc/sysctl.conf** accordingly: + > `vm.max_map_count` value in **/etc/sysctl.conf** accordingly: > > ```bash > vm.max_map_count=262144 @@ -179,8 +182,8 @@ releases! 🌟 | ----------------- | --------------- | --------------------- | ------------------------ | | v0.15.1 | ≈9 | :heavy_check_mark: | Stable release | | v0.15.1-slim | ≈2 | ❌ | Stable release | - | nightly | ≈9 | :heavy_check_mark: | *Unstable* nightly build | - | nightly-slim | ≈2 | ❌ | *Unstable* nightly build | + | nightly | ≈9 | :heavy_check_mark: | _Unstable_ nightly build | + | nightly-slim | ≈2 | ❌ | _Unstable_ nightly build | 4. Check the server status after having the server up and running: @@ -192,23 +195,24 @@ releases! 🌟 ```bash - ____ ___ ______ ______ __ + ____ ___ ______ ______ __ / __ \ / | / ____// ____// /____ _ __ / /_/ // /| | / / __ / /_ / // __ \| | /| / / - / _, _// ___ |/ /_/ // __/ / // /_/ /| |/ |/ / - /_/ |_|/_/ |_|\____//_/ /_/ \____/ |__/|__/ + / _, _// ___ |/ /_/ // __/ / // /_/ /| |/ |/ / + /_/ |_|/_/ |_|\____//_/ /_/ \____/ |__/|__/ * Running on all addresses (0.0.0.0) * Running on http://127.0.0.1:9380 * Running on http://x.x.x.x:9380 INFO:werkzeug:Press CTRL+C to quit ``` + > If you skip this confirmation step and directly log in to RAGFlow, your browser may prompt a `network anormal` - error because, at that moment, your RAGFlow may not be fully initialized. + > error because, at that moment, your RAGFlow may not be fully initialized. 5. In your web browser, enter the IP address of your server and log in to RAGFlow. > With the default settings, you only need to enter `http://IP_OF_YOUR_MACHINE` (**sans** port number) as the default - HTTP serving port `80` can be omitted when using the default configurations. + > HTTP serving port `80` can be omitted when using the default configurations. 6. In [service_conf.yaml.template](./docker/service_conf.yaml.template), select the desired LLM factory in `user_default_llm` and update the `API_KEY` field with the corresponding API key. @@ -255,7 +259,7 @@ RAGFlow uses Elasticsearch by default for storing full text and vectors. To swit $ docker compose -f docker/docker-compose.yml up -d ``` -> [!WARNING] +> [!WARNING] > Switching to Infinity on a Linux/arm64 machine is not yet officially supported. ## 🔧 Build a Docker image without embedding models @@ -281,11 +285,13 @@ docker build -f Dockerfile -t infiniflow/ragflow:nightly . ## 🔨 Launch service from source for development 1. Install uv, or skip this step if it is already installed: + ```bash pipx install uv ``` 2. Clone the source code and install Python dependencies: + ```bash git clone https://github.com/infiniflow/ragflow.git cd ragflow/ @@ -293,14 +299,16 @@ docker build -f Dockerfile -t infiniflow/ragflow:nightly . ``` 3. Launch the dependent services (MinIO, Elasticsearch, Redis, and MySQL) using Docker Compose: + ```bash docker compose -f docker/docker-compose-base.yml up -d ``` Add the following line to `/etc/hosts` to resolve all hosts specified in **docker/.env** to `127.0.0.1`: + ``` 127.0.0.1 es01 infinity mysql minio redis - ``` + ``` 4. If you cannot access HuggingFace, set the `HF_ENDPOINT` environment variable to use a mirror site: @@ -309,6 +317,7 @@ docker build -f Dockerfile -t infiniflow/ragflow:nightly . ``` 5. Launch backend service: + ```bash source .venv/bin/activate export PYTHONPATH=$(pwd) @@ -319,11 +328,12 @@ docker build -f Dockerfile -t infiniflow/ragflow:nightly . ```bash cd web npm install - ``` + ``` 7. Launch frontend service: + ```bash - npm run dev - ``` + npm run dev + ``` _The following output confirms a successful launch of the system:_ diff --git a/README_id.md b/README_id.md index 547b51e41ad..256083e12b7 100644 --- a/README_id.md +++ b/README_id.md @@ -9,7 +9,8 @@ 简体中文 | 日本語 | 한국어 | - Bahasa Indonesia + Bahasa Indonesia | + Português (Brasil)

@@ -65,6 +66,7 @@ ## 🎮 Demo Coba demo kami di [https://demo.ragflow.io](https://demo.ragflow.io). +

@@ -82,6 +84,7 @@ Coba demo kami di [https://demo.ragflow.io](https://demo.ragflow.io). ## 🎉 Tetap Terkini ⭐️ Star repositori kami untuk tetap mendapat informasi tentang fitur baru dan peningkatan menarik! 🌟 +
@@ -147,7 +150,7 @@ Coba demo kami di [https://demo.ragflow.io](https://demo.ragflow.io). > ``` > > Perubahan ini akan hilang setelah sistem direboot. Untuk membuat perubahan ini permanen, tambahkan atau perbarui nilai - `vm.max_map_count` di **/etc/sysctl.conf**: + > `vm.max_map_count` di **/etc/sysctl.conf**: > > ```bash > vm.max_map_count=262144 @@ -172,8 +175,8 @@ Coba demo kami di [https://demo.ragflow.io](https://demo.ragflow.io). | ----------------- | --------------- | --------------------- | ------------------------ | | v0.15.1 | ≈9 | :heavy_check_mark: | Stable release | | v0.15.1-slim | ≈2 | ❌ | Stable release | - | nightly | ≈9 | :heavy_check_mark: | *Unstable* nightly build | - | nightly-slim | ≈2 | ❌ | *Unstable* nightly build | + | nightly | ≈9 | :heavy_check_mark: | _Unstable_ nightly build | + | nightly-slim | ≈2 | ❌ | _Unstable_ nightly build | 4. Periksa status server setelah server aktif dan berjalan: @@ -185,23 +188,24 @@ Coba demo kami di [https://demo.ragflow.io](https://demo.ragflow.io). ```bash - ____ ___ ______ ______ __ + ____ ___ ______ ______ __ / __ \ / | / ____// ____// /____ _ __ / /_/ // /| | / / __ / /_ / // __ \| | /| / / - / _, _// ___ |/ /_/ // __/ / // /_/ /| |/ |/ / - /_/ |_|/_/ |_|\____//_/ /_/ \____/ |__/|__/ + / _, _// ___ |/ /_/ // __/ / // /_/ /| |/ |/ / + /_/ |_|/_/ |_|\____//_/ /_/ \____/ |__/|__/ * Running on all addresses (0.0.0.0) * Running on http://127.0.0.1:9380 * Running on http://x.x.x.x:9380 INFO:werkzeug:Press CTRL+C to quit ``` + > Jika Anda melewatkan langkah ini dan langsung login ke RAGFlow, browser Anda mungkin menampilkan error `network anormal` - karena RAGFlow mungkin belum sepenuhnya siap. + > karena RAGFlow mungkin belum sepenuhnya siap. 5. Buka browser web Anda, masukkan alamat IP server Anda, dan login ke RAGFlow. - > Dengan pengaturan default, Anda hanya perlu memasukkan `http://IP_DEVICE_ANDA` (**tanpa** nomor port) karena - port HTTP default `80` bisa dihilangkan saat menggunakan konfigurasi default. + > Dengan pengaturan default, Anda hanya perlu memasukkan `http://IP_DEVICE_ANDA` (**tanpa** nomor port) karena + > port HTTP default `80` bisa dihilangkan saat menggunakan konfigurasi default. 6. Dalam [service_conf.yaml.template](./docker/service_conf.yaml.template), pilih LLM factory yang diinginkan di `user_default_llm` dan perbarui bidang `API_KEY` dengan kunci API yang sesuai. @@ -250,11 +254,13 @@ docker build -f Dockerfile -t infiniflow/ragflow:nightly . ## 🔨 Menjalankan Aplikasi dari untuk Pengembangan 1. Instal uv, atau lewati langkah ini jika sudah terinstal: + ```bash pipx install uv ``` 2. Clone kode sumber dan instal dependensi Python: + ```bash git clone https://github.com/infiniflow/ragflow.git cd ragflow/ @@ -262,14 +268,16 @@ docker build -f Dockerfile -t infiniflow/ragflow:nightly . ``` 3. Jalankan aplikasi yang diperlukan (MinIO, Elasticsearch, Redis, dan MySQL) menggunakan Docker Compose: + ```bash docker compose -f docker/docker-compose-base.yml up -d ``` Tambahkan baris berikut ke `/etc/hosts` untuk memetakan semua host yang ditentukan di **conf/service_conf.yaml** ke `127.0.0.1`: + ``` 127.0.0.1 es01 infinity mysql minio redis - ``` + ``` 4. Jika Anda tidak dapat mengakses HuggingFace, atur variabel lingkungan `HF_ENDPOINT` untuk menggunakan situs mirror: @@ -278,6 +286,7 @@ docker build -f Dockerfile -t infiniflow/ragflow:nightly . ``` 5. Jalankan aplikasi backend: + ```bash source .venv/bin/activate export PYTHONPATH=$(pwd) @@ -290,9 +299,10 @@ docker build -f Dockerfile -t infiniflow/ragflow:nightly . npm install ``` 7. Jalankan aplikasi frontend: + ```bash - npm run dev - ``` + npm run dev + ``` _Output berikut menandakan bahwa sistem berhasil diluncurkan:_ @@ -318,4 +328,4 @@ Lihat [Roadmap RAGFlow 2025](https://github.com/infiniflow/ragflow/issues/4214) ## 🙌 Kontribusi RAGFlow berkembang melalui kolaborasi open-source. Dalam semangat ini, kami menerima kontribusi dari komunitas. -Jika Anda ingin berpartisipasi, tinjau terlebih dahulu [Panduan Kontribusi](./CONTRIBUTING.md). \ No newline at end of file +Jika Anda ingin berpartisipasi, tinjau terlebih dahulu [Panduan Kontribusi](./CONTRIBUTING.md). diff --git a/README_ja.md b/README_ja.md index 5292968b46d..32795f1c6df 100644 --- a/README_ja.md +++ b/README_ja.md @@ -9,7 +9,8 @@ 简体中文 | 日本語 | 한국어 | - Bahasa Indonesia + Bahasa Indonesia | + Português (Brasil)

@@ -30,7 +31,6 @@

-

Document | Roadmap | @@ -46,12 +46,12 @@ ## 🎮 Demo デモをお試しください:[https://demo.ragflow.io](https://demo.ragflow.io)。 +
- ## 🔥 最新情報 - 2024-12-18 Deepdoc のドキュメント レイアウト分析モデルをアップグレードします。 @@ -62,7 +62,9 @@ - 2024-08-02 [graphrag](https://github.com/microsoft/graphrag) からインスピレーションを得た GraphRAG とマインド マップをサポートします。 ## 🎉 続きを楽しみに + ⭐️ リポジトリをスター登録して、エキサイティングな新機能やアップデートを最新の状態に保ちましょう!すべての新しいリリースに関する即時通知を受け取れます! 🌟 +
@@ -142,7 +144,7 @@ 3. ビルド済みの Docker イメージをビルドし、サーバーを起動する: - > 以下のコマンドは、RAGFlow Dockerイメージの v0.15.1-slim エディションをダウンロードします。異なる RAGFlow エディションの説明については、以下の表を参照してください。v0.15.1-slim とは異なるエディションをダウンロードするには、docker/.env ファイルの RAGFLOW_IMAGE 変数を適宜更新し、docker compose を使用してサーバーを起動してください。例えば、完全版 v0.15.1 をダウンロードするには、RAGFLOW_IMAGE=infiniflow/ragflow:v0.15.1 と設定します。 + > 以下のコマンドは、RAGFlow Docker イメージの v0.15.1-slim エディションをダウンロードします。異なる RAGFlow エディションの説明については、以下の表を参照してください。v0.15.1-slim とは異なるエディションをダウンロードするには、docker/.env ファイルの RAGFLOW_IMAGE 変数を適宜更新し、docker compose を使用してサーバーを起動してください。例えば、完全版 v0.15.1 をダウンロードするには、RAGFLOW_IMAGE=infiniflow/ragflow:v0.15.1 と設定します。 ```bash $ cd ragflow @@ -151,10 +153,10 @@ | RAGFlow image tag | Image size (GB) | Has embedding models? | Stable? | | ----------------- | --------------- | --------------------- | ------------------------ | - | v0.15.1 | ≈9 | :heavy_check_mark: | Stable release | + | v0.15.1 | ≈9 | :heavy_check_mark: | Stable release | | v0.15.1-slim | ≈2 | ❌ | Stable release | - | nightly | ≈9 | :heavy_check_mark: | *Unstable* nightly build | - | nightly-slim | ≈2 | ❌ | *Unstable* nightly build | + | nightly | ≈9 | :heavy_check_mark: | _Unstable_ nightly build | + | nightly-slim | ≈2 | ❌ | _Unstable_ nightly build | 4. サーバーを立ち上げた後、サーバーの状態を確認する: @@ -165,17 +167,18 @@ _以下の出力は、システムが正常に起動したことを確認するものです:_ ```bash - ____ ___ ______ ______ __ + ____ ___ ______ ______ __ / __ \ / | / ____// ____// /____ _ __ / /_/ // /| | / / __ / /_ / // __ \| | /| / / - / _, _// ___ |/ /_/ // __/ / // /_/ /| |/ |/ / - /_/ |_|/_/ |_|\____//_/ /_/ \____/ |__/|__/ + / _, _// ___ |/ /_/ // __/ / // /_/ /| |/ |/ / + /_/ |_|/_/ |_|\____//_/ /_/ \____/ |__/|__/ * Running on all addresses (0.0.0.0) * Running on http://127.0.0.1:9380 * Running on http://x.x.x.x:9380 INFO:werkzeug:Press CTRL+C to quit ``` + > もし確認ステップをスキップして直接 RAGFlow にログインした場合、その時点で RAGFlow が完全に初期化されていない可能性があるため、ブラウザーがネットワーク異常エラーを表示するかもしれません。 5. ウェブブラウザで、プロンプトに従ってサーバーの IP アドレスを入力し、RAGFlow にログインします。 @@ -214,16 +217,16 @@ RAGFlow はデフォルトで Elasticsearch を使用して全文とベクトル ```bash $ docker compose -f docker/docker-compose.yml down -v ``` -2. **docker/.env** の「DOC _ ENGINE」を「infinity」に設定します。 +2. **docker/.env** の「DOC \_ ENGINE」を「infinity」に設定します。 3. 起動コンテナ: ```bash $ docker compose -f docker/docker-compose.yml up -d ``` -> [!WARNING] -> Linux/arm64 マシンでの Infinity への切り替えは正式にサポートされていません。 + > [!WARNING] + > Linux/arm64 マシンでの Infinity への切り替えは正式にサポートされていません。 -## 🔧 ソースコードでDockerイメージを作成(埋め込みモデルなし) +## 🔧 ソースコードで Docker イメージを作成(埋め込みモデルなし) この Docker イメージのサイズは約 1GB で、外部の大モデルと埋め込みサービスに依存しています。 @@ -233,7 +236,7 @@ cd ragflow/ docker build --build-arg LIGHTEN=1 -f Dockerfile -t infiniflow/ragflow:nightly-slim . ``` -## 🔧 ソースコードをコンパイルしたDockerイメージ(埋め込みモデルを含む) +## 🔧 ソースコードをコンパイルした Docker イメージ(埋め込みモデルを含む) この Docker のサイズは約 9GB で、埋め込みモデルを含むため、外部の大モデルサービスのみが必要です。 @@ -246,11 +249,13 @@ docker build -f Dockerfile -t infiniflow/ragflow:nightly . ## 🔨 ソースコードからサービスを起動する方法 1. uv をインストールする。すでにインストールされている場合は、このステップをスキップしてください: + ```bash pipx install uv ``` 2. ソースコードをクローンし、Python の依存関係をインストールする: + ```bash git clone https://github.com/infiniflow/ragflow.git cd ragflow/ @@ -258,39 +263,43 @@ docker build -f Dockerfile -t infiniflow/ragflow:nightly . ``` 3. Docker Compose を使用して依存サービス(MinIO、Elasticsearch、Redis、MySQL)を起動する: + ```bash docker compose -f docker/docker-compose-base.yml up -d ``` - `/etc/hosts` に以下の行を追加して、**conf/service_conf.yaml** に指定されたすべてのホストを `127.0.0.1` に解決します: + `/etc/hosts` に以下の行を追加して、**conf/service_conf.yaml** に指定されたすべてのホストを `127.0.0.1` に解決します: + ``` 127.0.0.1 es01 infinity mysql minio redis - ``` + ``` 4. HuggingFace にアクセスできない場合は、`HF_ENDPOINT` 環境変数を設定してミラーサイトを使用してください: - + ```bash export HF_ENDPOINT=https://hf-mirror.com ``` 5. バックエンドサービスを起動する: + ```bash source .venv/bin/activate export PYTHONPATH=$(pwd) bash docker/launch_backend_service.sh ``` -6. フロントエンドの依存関係をインストールする: +6. フロントエンドの依存関係をインストールする: ```bash cd web npm install - ``` -7. フロントエンドサービスを起動する: + ``` +7. フロントエンドサービスを起動する: + ```bash - npm run dev + npm run dev ``` - _以下の画面で、システムが正常に起動したことを示します:_ + _以下の画面で、システムが正常に起動したことを示します:_ ![](https://github.com/user-attachments/assets/0daf462c-a24d-4496-a66f-92533534e187) diff --git a/README_ko.md b/README_ko.md index faad27bc3e3..91baac64221 100644 --- a/README_ko.md +++ b/README_ko.md @@ -9,7 +9,8 @@ 简体中文 | 日本語 | 한국어 | - Bahasa Indonesia + Bahasa Indonesia | + Português (Brasil)

@@ -30,7 +31,6 @@

-

Document | Roadmap | @@ -39,69 +39,65 @@ Demo

- ## 💡 RAGFlow란? [RAGFlow](https://ragflow.io/)는 심층 문서 이해에 기반한 오픈소스 RAG (Retrieval-Augmented Generation) 엔진입니다. 이 엔진은 대규모 언어 모델(LLM)과 결합하여 정확한 질문 응답 기능을 제공하며, 다양한 복잡한 형식의 데이터에서 신뢰할 수 있는 출처를 바탕으로 한 인용을 통해 이를 뒷받침합니다. RAGFlow는 규모에 상관없이 모든 기업에 최적화된 RAG 워크플로우를 제공합니다. - - ## 🎮 데모 + 데모를 [https://demo.ragflow.io](https://demo.ragflow.io)에서 실행해 보세요. +
- ## 🔥 업데이트 - 2024-12-18 Deepdoc의 문서 레이아웃 분석 모델 업그레이드. - - 2024-12-04 지식베이스에 대한 페이지랭크 점수를 지원합니다. - 2024-11-22 에이전트의 변수 정의 및 사용을 개선했습니다. - - 2024-11-01 파싱된 청크에 키워드 추출 및 관련 질문 생성을 추가하여 재현율을 향상시킵니다. - - 2024-08-22 RAG를 통해 SQL 문에 텍스트를 지원합니다. - - 2024-08-02: [graphrag](https://github.com/microsoft/graphrag)와 마인드맵에서 영감을 받은 GraphRAG를 지원합니다. - ## 🎉 계속 지켜봐 주세요 + ⭐️우리의 저장소를 즐겨찾기에 등록하여 흥미로운 새로운 기능과 업데이트를 최신 상태로 유지하세요! 모든 새로운 릴리스에 대한 즉시 알림을 받으세요! 🌟 +
- ## 🌟 주요 기능 ### 🍭 **"Quality in, quality out"** + - [심층 문서 이해](./deepdoc/README.md)를 기반으로 복잡한 형식의 비정형 데이터에서 지식을 추출합니다. - 문자 그대로 무한한 토큰에서 "데이터 속의 바늘"을 찾아냅니다. ### 🍱 **템플릿 기반의 chunking** + - 똑똑하고 설명 가능한 방식. - 다양한 템플릿 옵션을 제공합니다. - ### 🌱 **할루시네이션을 줄인 신뢰할 수 있는 인용** + - 텍스트 청킹을 시각화하여 사용자가 개입할 수 있도록 합니다. - 중요한 참고 자료와 추적 가능한 인용을 빠르게 확인하여 신뢰할 수 있는 답변을 지원합니다. - ### 🍔 **다른 종류의 데이터 소스와의 호환성** + - 워드, 슬라이드, 엑셀, 텍스트 파일, 이미지, 스캔본, 구조화된 데이터, 웹 페이지 등을 지원합니다. ### 🛀 **자동화되고 손쉬운 RAG 워크플로우** + - 개인 및 대규모 비즈니스에 맞춘 효율적인 RAG 오케스트레이션. - 구성 가능한 LLM 및 임베딩 모델. - 다중 검색과 결합된 re-ranking. - 비즈니스와 원활하게 통합할 수 있는 직관적인 API. - ## 🔎 시스템 아키텍처
@@ -109,17 +105,19 @@
## 🎬 시작하기 + ### 📝 사전 준비 사항 + - CPU >= 4 cores - RAM >= 16 GB - Disk >= 50 GB - Docker >= 24.0.0 & Docker Compose >= v2.26.1 - > 로컬 머신(Windows, Mac, Linux)에 Docker가 설치되지 않은 경우, [Docker 엔진 설치]((https://docs.docker.com/engine/install/))를 참조하세요. - + > 로컬 머신(Windows, Mac, Linux)에 Docker가 설치되지 않은 경우, [Docker 엔진 설치](<(https://docs.docker.com/engine/install/)>)를 참조하세요. ### 🚀 서버 시작하기 1. `vm.max_map_count`가 262144 이상인지 확인하세요: + > `vm.max_map_count`의 값을 아래 명령어를 통해 확인하세요: > > ```bash @@ -158,8 +156,8 @@ | ----------------- | --------------- | --------------------- | ------------------------ | | v0.15.1 | ≈9 | :heavy_check_mark: | Stable release | | v0.15.1-slim | ≈2 | ❌ | Stable release | - | nightly | ≈9 | :heavy_check_mark: | *Unstable* nightly build | - | nightly-slim | ≈2 | ❌ | *Unstable* nightly build | + | nightly | ≈9 | :heavy_check_mark: | _Unstable_ nightly build | + | nightly-slim | ≈2 | ❌ | _Unstable_ nightly build | 4. 서버가 시작된 후 서버 상태를 확인하세요: @@ -170,22 +168,24 @@ _다음 출력 결과로 시스템이 성공적으로 시작되었음을 확인합니다:_ ```bash - ____ ___ ______ ______ __ + ____ ___ ______ ______ __ / __ \ / | / ____// ____// /____ _ __ / /_/ // /| | / / __ / /_ / // __ \| | /| / / - / _, _// ___ |/ /_/ // __/ / // /_/ /| |/ |/ / - /_/ |_|/_/ |_|\____//_/ /_/ \____/ |__/|__/ + / _, _// ___ |/ /_/ // __/ / // /_/ /| |/ |/ / + /_/ |_|/_/ |_|\____//_/ /_/ \____/ |__/|__/ * Running on all addresses (0.0.0.0) * Running on http://127.0.0.1:9380 * Running on http://x.x.x.x:9380 INFO:werkzeug:Press CTRL+C to quit ``` + > 만약 확인 단계를 건너뛰고 바로 RAGFlow에 로그인하면, RAGFlow가 완전히 초기화되지 않았기 때문에 브라우저에서 `network anormal` 오류가 발생할 수 있습니다. 5. 웹 브라우저에 서버의 IP 주소를 입력하고 RAGFlow에 로그인하세요. > 기본 설정을 사용할 경우, `http://IP_OF_YOUR_MACHINE`만 입력하면 됩니다 (포트 번호는 제외). 기본 HTTP 서비스 포트 `80`은 기본 구성으로 사용할 때 생략할 수 있습니다. 6. [service_conf.yaml.template](./docker/service_conf.yaml.template) 파일에서 원하는 LLM 팩토리를 `user_default_llm`에 선택하고, `API_KEY` 필드를 해당 API 키로 업데이트하세요. + > 자세한 내용은 [llm_api_key_setup](https://ragflow.io/docs/dev/llm_api_key_setup)를 참조하세요. _이제 쇼가 시작됩니다!_ @@ -213,6 +213,7 @@ ### Elasticsearch 에서 Infinity 로 문서 엔진 전환 RAGFlow 는 기본적으로 Elasticsearch 를 사용하여 전체 텍스트 및 벡터를 저장합니다. [Infinity]로 전환(https://github.com/infiniflow/infinity/), 다음 절차를 따르십시오. + 1. 실행 중인 모든 컨테이너를 중지합니다. ```bash $docker compose-f docker/docker-compose.yml down -v @@ -221,10 +222,10 @@ RAGFlow 는 기본적으로 Elasticsearch 를 사용하여 전체 텍스트 및 3. 컨테이너 부팅: ```bash $docker compose-f docker/docker-compose.yml up -d - ``` -> [!WARNING] -> Linux/arm64 시스템에서 Infinity로 전환하는 것은 공식적으로 지원되지 않습니다. - + ``` + > [!WARNING] + > Linux/arm64 시스템에서 Infinity로 전환하는 것은 공식적으로 지원되지 않습니다. + ## 🔧 소스 코드로 Docker 이미지를 컴파일합니다(임베딩 모델 포함하지 않음) 이 Docker 이미지의 크기는 약 1GB이며, 외부 대형 모델과 임베딩 서비스에 의존합니다. @@ -248,11 +249,13 @@ docker build -f Dockerfile -t infiniflow/ragflow:nightly . ## 🔨 소스 코드로 서비스를 시작합니다. 1. uv를 설치하거나 이미 설치된 경우 이 단계를 건너뜁니다: + ```bash pipx install uv ``` 2. 소스 코드를 클론하고 Python 의존성을 설치합니다: + ```bash git clone https://github.com/infiniflow/ragflow.git cd ragflow/ @@ -260,39 +263,43 @@ docker build -f Dockerfile -t infiniflow/ragflow:nightly . ``` 3. Docker Compose를 사용하여 의존 서비스(MinIO, Elasticsearch, Redis 및 MySQL)를 시작합니다: + ```bash docker compose -f docker/docker-compose-base.yml up -d ``` - `/etc/hosts` 에 다음 줄을 추가하여 **conf/service_conf.yaml** 에 지정된 모든 호스트를 `127.0.0.1` 로 해결합니다: + `/etc/hosts` 에 다음 줄을 추가하여 **conf/service_conf.yaml** 에 지정된 모든 호스트를 `127.0.0.1` 로 해결합니다: + ``` 127.0.0.1 es01 infinity mysql minio redis - ``` + ``` 4. HuggingFace에 접근할 수 없는 경우, `HF_ENDPOINT` 환경 변수를 설정하여 미러 사이트를 사용하세요: - + ```bash export HF_ENDPOINT=https://hf-mirror.com ``` 5. 백엔드 서비스를 시작합니다: + ```bash source .venv/bin/activate export PYTHONPATH=$(pwd) bash docker/launch_backend_service.sh ``` -6. 프론트엔드 의존성을 설치합니다: +6. 프론트엔드 의존성을 설치합니다: ```bash cd web npm install - ``` -7. 프론트엔드 서비스를 시작합니다: + ``` +7. 프론트엔드 서비스를 시작합니다: + ```bash - npm run dev + npm run dev ``` - _다음 인터페이스는 시스템이 성공적으로 시작되었음을 나타냅니다:_ + _다음 인터페이스는 시스템이 성공적으로 시작되었음을 나타냅니다:_ ![](https://github.com/user-attachments/assets/0daf462c-a24d-4496-a66f-92533534e187) diff --git a/README_pt_br.md b/README_pt_br.md new file mode 100644 index 00000000000..d44f810d9be --- /dev/null +++ b/README_pt_br.md @@ -0,0 +1,352 @@ +
+ +ragflow logo + +
+ +

+ English | + 简体中文 | + 日本語 | + 한국어 | + Bahasa Indonesia | + Português (Brasil) +

+ +

+ + seguir no X(Twitter) + + + Badge Estático + + + docker pull infiniflow/ragflow:v0.15.1 + + + Última Versão + + + licença + +

+ +

+ Documentação | + Roadmap | + Twitter | + Discord | + Demo +

+ +
+📕 Índice + +- 💡 [O que é o RAGFlow?](#-o-que-é-o-ragflow) +- 🎮 [Demo](#-demo) +- 📌 [Últimas Atualizações](#-últimas-atualizações) +- 🌟 [Principais Funcionalidades](#-principais-funcionalidades) +- 🔎 [Arquitetura do Sistema](#-arquitetura-do-sistema) +- 🎬 [Primeiros Passos](#-primeiros-passos) +- 🔧 [Configurações](#-configurações) +- 🔧 [Construir uma imagem docker sem incorporar modelos](#-construir-uma-imagem-docker-sem-incorporar-modelos) +- 🔧 [Construir uma imagem docker incluindo modelos](#-construir-uma-imagem-docker-incluindo-modelos) +- 🔨 [Lançar serviço a partir do código-fonte para desenvolvimento](#-lançar-serviço-a-partir-do-código-fonte-para-desenvolvimento) +- 📚 [Documentação](#-documentação) +- 📜 [Roadmap](#-roadmap) +- 🏄 [Comunidade](#-comunidade) +- 🙌 [Contribuindo](#-contribuindo) + +
+ +## 💡 O que é o RAGFlow? + +[RAGFlow](https://ragflow.io/) é um mecanismo RAG (Geração Aumentada por Recuperação) de código aberto baseado em entendimento profundo de documentos. Ele oferece um fluxo de trabalho RAG simplificado para empresas de qualquer porte, combinando LLMs (Modelos de Linguagem de Grande Escala) para fornecer capacidades de perguntas e respostas verídicas, respaldadas por citações bem fundamentadas de diversos dados complexos formatados. + +## 🎮 Demo + +Experimente nossa demo em [https://demo.ragflow.io](https://demo.ragflow.io). + +
+ + +
+ +## 🔥 Últimas Atualizações + +- 18-12-2024 Atualiza o modelo de Análise de Layout de Documentos no Deepdoc. +- 04-12-2024 Adiciona suporte para pontuação de pagerank na base de conhecimento. +- 22-11-2024 Adiciona mais variáveis para o Agente. +- 01-11-2024 Adiciona extração de palavras-chave e geração de perguntas relacionadas aos blocos analisados para melhorar a precisão da recuperação. +- 22-08-2024 Suporta conversão de texto para comandos SQL via RAG. +- 02-08-2024 Suporta GraphRAG inspirado pelo [graphrag](https://github.com/microsoft/graphrag) e mapa mental. + +## 🎉 Fique Ligado + +⭐️ Dê uma estrela no nosso repositório para se manter atualizado com novas funcionalidades e melhorias empolgantes! Receba notificações instantâneas sobre novos lançamentos! 🌟 + +
+ +
+ +## 🌟 Principais Funcionalidades + +### 🍭 **"Qualidade entra, qualidade sai"** + +- Extração de conhecimento baseada em [entendimento profundo de documentos](./deepdoc/README.md) a partir de dados não estruturados com formatos complicados. +- Encontra a "agulha no palheiro de dados" de literalmente tokens ilimitados. + +### 🍱 **Fragmentação baseada em templates** + +- Inteligente e explicável. +- Muitas opções de templates para escolher. + +### 🌱 **Citações fundamentadas com menos alucinações** + +- Visualização da fragmentação de texto para permitir intervenção humana. +- Visualização rápida das referências chave e citações rastreáveis para apoiar respostas fundamentadas. + +### 🍔 **Compatibilidade com fontes de dados heterogêneas** + +- Suporta Word, apresentações, excel, txt, imagens, cópias digitalizadas, dados estruturados, páginas da web e mais. + +### 🛀 **Fluxo de trabalho RAG automatizado e sem esforço** + +- Orquestração RAG simplificada voltada tanto para negócios pessoais quanto grandes empresas. +- Modelos LLM e de incorporação configuráveis. +- Múltiplas recuperações emparelhadas com reclassificação fundida. +- APIs intuitivas para integração sem problemas com os negócios. + +## 🔎 Arquitetura do Sistema + +
+ +
+ +## 🎬 Primeiros Passos + +### 📝 Pré-requisitos + +- CPU >= 4 núcleos +- RAM >= 16 GB +- Disco >= 50 GB +- Docker >= 24.0.0 & Docker Compose >= v2.26.1 + > Se você não instalou o Docker na sua máquina local (Windows, Mac ou Linux), veja [Instalar Docker Engine](https://docs.docker.com/engine/install/). + +### 🚀 Iniciar o servidor + +1. Certifique-se de que `vm.max_map_count` >= 262144: + + > Para verificar o valor de `vm.max_map_count`: + > + > ```bash + > $ sysctl vm.max_map_count + > ``` + > + > Se necessário, redefina `vm.max_map_count` para um valor de pelo menos 262144: + > + > ```bash + > # Neste caso, defina para 262144: + > $ sudo sysctl -w vm.max_map_count=262144 + > ``` + > + > Essa mudança será resetada após a reinicialização do sistema. Para garantir que a alteração permaneça permanente, adicione ou atualize o valor de `vm.max_map_count` em **/etc/sysctl.conf**: + > + > ```bash + > vm.max_map_count=262144 + > ``` + +2. Clone o repositório: + + ```bash + $ git clone https://github.com/infiniflow/ragflow.git + ``` + +3. Inicie o servidor usando as imagens Docker pré-compiladas: + + > O comando abaixo baixa a edição `v0.15.1-slim` da imagem Docker do RAGFlow. Consulte a tabela a seguir para descrições de diferentes edições do RAGFlow. Para baixar uma edição do RAGFlow diferente da `v0.15.1-slim`, atualize a variável `RAGFLOW_IMAGE` conforme necessário no **docker/.env** antes de usar `docker compose` para iniciar o servidor. Por exemplo: defina `RAGFLOW_IMAGE=infiniflow/ragflow:v0.15.1` para a edição completa `v0.15.1`. + + ```bash + $ cd ragflow + $ docker compose -f docker/docker-compose.yml up -d + ``` + + | Tag da imagem RAGFlow | Tamanho da imagem (GB) | Possui modelos de incorporação? | Estável? | + | --------------------- | ---------------------- | ------------------------------- | ------------------------ | + | v0.15.1 | ~9 | :heavy_check_mark: | Lançamento estável | + | v0.15.1-slim | ~2 | ❌ | Lançamento estável | + | nightly | ~9 | :heavy_check_mark: | _Instável_ build noturno | + | nightly-slim | ~2 | ❌ | _Instável_ build noturno | + +4. Verifique o status do servidor após tê-lo iniciado: + + ```bash + $ docker logs -f ragflow-server + ``` + + _O seguinte resultado confirma o lançamento bem-sucedido do sistema:_ + + ```bash + ____ ___ ______ ______ __ + / __ \ / | / ____// ____// /____ _ __ + / /_/ // /| | / / __ / /_ / // __ \| | /| / / + / _, _// ___ |/ /_/ // __/ / // /_/ /| |/ |/ / + /_/ |_|/_/ |_|\____//_/ /_/ \____/ |__/|__/ + + * Rodando em todos os endereços (0.0.0.0) + * Rodando em http://127.0.0.1:9380 + * Rodando em http://x.x.x.x:9380 + INFO:werkzeug:Pressione CTRL+C para sair + ``` + + > Se você pular essa etapa de confirmação e acessar diretamente o RAGFlow, seu navegador pode exibir um erro `network anormal`, pois, nesse momento, seu RAGFlow pode não estar totalmente inicializado. + +5. No seu navegador, insira o endereço IP do seu servidor e faça login no RAGFlow. + + > Com as configurações padrão, você só precisa digitar `http://IP_DO_SEU_MÁQUINA` (**sem** o número da porta), pois a porta HTTP padrão `80` pode ser omitida ao usar as configurações padrão. + +6. Em [service_conf.yaml.template](./docker/service_conf.yaml.template), selecione a fábrica LLM desejada em `user_default_llm` e atualize o campo `API_KEY` com a chave de API correspondente. + + > Consulte [llm_api_key_setup](https://ragflow.io/docs/dev/llm_api_key_setup) para mais informações. + +_O show está no ar!_ + +## 🔧 Configurações + +Quando se trata de configurações do sistema, você precisará gerenciar os seguintes arquivos: + +- [.env](./docker/.env): Contém as configurações fundamentais para o sistema, como `SVR_HTTP_PORT`, `MYSQL_PASSWORD` e `MINIO_PASSWORD`. +- [service_conf.yaml.template](./docker/service_conf.yaml.template): Configura os serviços de back-end. As variáveis de ambiente neste arquivo serão automaticamente preenchidas quando o contêiner Docker for iniciado. Quaisquer variáveis de ambiente definidas dentro do contêiner Docker estarão disponíveis para uso, permitindo personalizar o comportamento do serviço com base no ambiente de implantação. +- [docker-compose.yml](./docker/docker-compose.yml): O sistema depende do [docker-compose.yml](./docker/docker-compose.yml) para iniciar. + +> O arquivo [./docker/README](./docker/README.md) fornece uma descrição detalhada das configurações do ambiente e dos serviços, que podem ser usadas como `${ENV_VARS}` no arquivo [service_conf.yaml.template](./docker/service_conf.yaml.template). + +Para atualizar a porta HTTP de serviço padrão (80), vá até [docker-compose.yml](./docker/docker-compose.yml) e altere `80:80` para `:80`. + +Atualizações nas configurações acima exigem um reinício de todos os contêineres para que tenham efeito: + +> ```bash +> $ docker compose -f docker/docker-compose.yml up -d +> ``` + +### Mudar o mecanismo de documentos de Elasticsearch para Infinity + +O RAGFlow usa o Elasticsearch por padrão para armazenar texto completo e vetores. Para mudar para o [Infinity](https://github.com/infiniflow/infinity/), siga estas etapas: + +1. Pare todos os contêineres em execução: + + ```bash + $ docker compose -f docker/docker-compose.yml down -v + ``` + +2. Defina `DOC_ENGINE` no **docker/.env** para `infinity`. + +3. Inicie os contêineres: + + ```bash + $ docker compose -f docker/docker-compose.yml up -d + ``` + +> [!ATENÇÃO] +> A mudança para o Infinity em uma máquina Linux/arm64 ainda não é oficialmente suportada. + +## 🔧 Criar uma imagem Docker sem modelos de incorporação + +Esta imagem tem cerca de 2 GB de tamanho e depende de serviços externos de LLM e incorporação. + +```bash +git clone https://github.com/infiniflow/ragflow.git +cd ragflow/ +docker build --build-arg LIGHTEN=1 -f Dockerfile -t infiniflow/ragflow:nightly-slim . +``` + +## 🔧 Criar uma imagem Docker incluindo modelos de incorporação + +Esta imagem tem cerca de 9 GB de tamanho. Como inclui modelos de incorporação, depende apenas de serviços externos de LLM. + +```bash +git clone https://github.com/infiniflow/ragflow.git +cd ragflow/ +docker build -f Dockerfile -t infiniflow/ragflow:nightly . +``` + +## 🔨 Lançar o serviço a partir do código-fonte para desenvolvimento + +1. Instale o `uv`, ou pule esta etapa se ele já estiver instalado: + + ```bash + pipx install uv + ``` + +2. Clone o código-fonte e instale as dependências Python: + + ```bash + git clone https://github.com/infiniflow/ragflow.git + cd ragflow/ + uv sync --python 3.10 --all-extras # instala os módulos Python dependentes do RAGFlow + ``` + +3. Inicie os serviços dependentes (MinIO, Elasticsearch, Redis e MySQL) usando Docker Compose: + + ```bash + docker compose -f docker/docker-compose-base.yml up -d + ``` + + Adicione a seguinte linha ao arquivo `/etc/hosts` para resolver todos os hosts especificados em **docker/.env** para `127.0.0.1`: + + ``` + 127.0.0.1 es01 infinity mysql minio redis + ``` + +4. Se não conseguir acessar o HuggingFace, defina a variável de ambiente `HF_ENDPOINT` para usar um site espelho: + + ```bash + export HF_ENDPOINT=https://hf-mirror.com + ``` + +5. Lance o serviço de back-end: + + ```bash + source .venv/bin/activate + export PYTHONPATH=$(pwd) + bash docker/launch_backend_service.sh + ``` + +6. Instale as dependências do front-end: + + ```bash + cd web + npm install + ``` + +7. Lance o serviço de front-end: + + ```bash + npm run dev + ``` + + _O seguinte resultado confirma o lançamento bem-sucedido do sistema:_ + + ![](https://github.com/user-attachments/assets/0daf462c-a24d-4496-a66f-92533534e187) + +## 📚 Documentação + +- [Início rápido](https://ragflow.io/docs/dev/) +- [Guia do usuário](https://ragflow.io/docs/dev/category/guides) +- [Referências](https://ragflow.io/docs/dev/category/references) +- [FAQ](https://ragflow.io/docs/dev/faq) + +## 📜 Roadmap + +Veja o [RAGFlow Roadmap 2025](https://github.com/infiniflow/ragflow/issues/4214) + +## 🏄 Comunidade + +- [Discord](https://discord.gg/4XxujFgUN7) +- [Twitter](https://twitter.com/infiniflowai) +- [GitHub Discussions](https://github.com/orgs/infiniflow/discussions) + +## 🙌 Contribuindo + +O RAGFlow prospera por meio da colaboração de código aberto. Com esse espírito, abraçamos contribuições diversas da comunidade. +Se você deseja fazer parte, primeiro revise nossas [Diretrizes de Contribuição](./CONTRIBUTING.md). diff --git a/README_tzh.md b/README_tzh.md index 02dc11e7cfc..f15f7b40d85 100644 --- a/README_tzh.md +++ b/README_tzh.md @@ -9,7 +9,8 @@ 简体中文 | 日本語 | 한국어 | - Bahasa Indonesia + Bahasa Indonesia | + Português (Brasil)

@@ -30,7 +31,6 @@

-

Document | Roadmap | @@ -45,13 +45,13 @@ ## 🎮 Demo 試用 -請登入網址 [https://demo.ragflow.io](https://demo.ragflow.io) 試用 demo。 +請登入網址 [https://demo.ragflow.io](https://demo.ragflow.io) 試用 demo。 +
- ## 🔥 近期更新 - 2024-12-18 升級了 Deepdoc 的文檔佈局分析模型。 @@ -62,12 +62,13 @@ - 2024-08-02 支持 GraphRAG 啟發於 [graphrag](https://github.com/microsoft/graphrag) 和心智圖。 ## 🎉 關注項目 -⭐️點擊右上角的 Star 追蹤RAGFlow,可以取得最新發布的即時通知 !🌟 + +⭐️ 點擊右上角的 Star 追蹤 RAGFlow,可以取得最新發布的即時通知 !🌟 +
- ## 🌟 主要功能 ### 🍭 **"Quality in, quality out"** @@ -102,7 +103,7 @@

-## 🎬快速開始 +## 🎬 快速開始 ### 📝 前提條件 @@ -144,6 +145,7 @@ 3. 進入 **docker** 資料夾,利用事先編譯好的 Docker 映像啟動伺服器: > 執行以下指令會自動下載 RAGFlow slim Docker 映像 `v0.15.1-slim`。請參考下表查看不同 Docker 發行版的說明。如需下載不同於 `v0.15.1-slim` 的 Docker 映像,請在執行 `docker compose` 啟動服務之前先更新 **docker/.env** 檔案內的 `RAGFLOW_IMAGE` 變數。例如,你可以透過設定 `RAGFLOW_IMAGE=infiniflow/ragflow:v0.15.1` 來下載 RAGFlow 鏡像的 `v0.15.1` 完整發行版。 + ```bash $ cd ragflow $ docker compose -f docker/docker-compose.yml up -d @@ -153,11 +155,12 @@ | ----------------- | --------------- | --------------------- | ------------------------ | | v0.15.1 | ≈9 | :heavy_check_mark: | Stable release | | v0.15.1-slim | ≈2 | ❌ | Stable release | - | nightly | ≈9 | :heavy_check_mark: | *Unstable* nightly build | - | nightly-slim | ≈2 | ❌ | *Unstable* nightly build | + | nightly | ≈9 | :heavy_check_mark: | _Unstable_ nightly build | + | nightly-slim | ≈2 | ❌ | _Unstable_ nightly build | - > [!TIP] + > [!TIP] > 如果你遇到 Docker 映像檔拉不下來的問題,可以在 **docker/.env** 檔案內根據變數 `RAGFLOW_IMAGE` 的註解提示選擇華為雲或阿里雲的對應映像。 + > > - 華為雲鏡像名:`swr.cn-north-4.myhuaweicloud.com/infiniflow/ragflow` > - 阿里雲鏡像名:`registry.cn-hangzhou.aliyuncs.com/infiniflow/ragflow` @@ -170,17 +173,18 @@ _出現以下介面提示說明伺服器啟動成功:_ ```bash - ____ ___ ______ ______ __ + ____ ___ ______ ______ __ / __ \ / | / ____// ____// /____ _ __ / /_/ // /| | / / __ / /_ / // __ \| | /| / / - / _, _// ___ |/ /_/ // __/ / // /_/ /| |/ |/ / - /_/ |_|/_/ |_|\____//_/ /_/ \____/ |__/|__/ + / _, _// ___ |/ /_/ // __/ / // /_/ /| |/ |/ / + /_/ |_|/_/ |_|\____//_/ /_/ \____/ |__/|__/ * Running on all addresses (0.0.0.0) * Running on http://127.0.0.1:9380 * Running on http://x.x.x.x:9380 INFO:werkzeug:Press CTRL+C to quit ``` + > 如果您跳過這一步驟系統確認步驟就登入 RAGFlow,你的瀏覽器有可能會提示 `network anormal` 或 `網路異常`,因為 RAGFlow 可能並未完全啟動成功。 5. 在你的瀏覽器中輸入你的伺服器對應的 IP 位址並登入 RAGFlow。 @@ -205,7 +209,7 @@ > [./docker/README](./docker/README.md) 解釋了 [service_conf.yaml.template](./docker/service_conf.yaml.template) 用到的環境變數設定和服務配置。 -如需更新預設的HTTP 服務連接埠(80), 可以在[docker-compose.yml](./docker/docker-compose.yml) 檔案中將配置`80:80` 改為`:80` 。 +如需更新預設的 HTTP 服務連接埠(80), 可以在[docker-compose.yml](./docker/docker-compose.yml) 檔案中將配置`80:80` 改為`:80` 。 > 所有系統配置都需要透過系統重新啟動生效: > @@ -234,7 +238,6 @@ RAGFlow 預設使用 Elasticsearch 儲存文字和向量資料. 如果要切換 > [!WARNING] > Infinity 目前官方並未正式支援在 Linux/arm64 架構下的機器上運行. - ## 🔧 原始碼編譯 Docker 映像(不含 embedding 模型) 本 Docker 映像大小約 2 GB 左右並且依賴外部的大模型和 embedding 服務。 @@ -258,12 +261,14 @@ docker build --build-arg NEED_MIRROR=1 -f Dockerfile -t infiniflow/ragflow:night ## 🔨 以原始碼啟動服務 1. 安裝 uv。如已安裝,可跳過此步驟: + ```bash pipx install uv export UV_INDEX=https://pypi.tuna.tsinghua.edu.cn/simple ``` 2. 下載原始碼並安裝 Python 依賴: + ```bash git clone https://github.com/infiniflow/ragflow.git cd ragflow/ @@ -271,41 +276,47 @@ docker build --build-arg NEED_MIRROR=1 -f Dockerfile -t infiniflow/ragflow:night ``` 3. 透過 Docker Compose 啟動依賴的服務(MinIO, Elasticsearch, Redis, and MySQL): + ```bash docker compose -f docker/docker-compose-base.yml up -d ``` 在 `/etc/hosts` 中加入以下程式碼,將 **conf/service_conf.yaml** 檔案中的所有 host 位址都解析為 `127.0.0.1`: + ``` 127.0.0.1 es01 infinity mysql minio redis ``` -4. 如果無法存取 HuggingFace,可以把環境變數 `HF_ENDPOINT` 設為對應的鏡像網站: - +4. 如果無法存取 HuggingFace,可以把環境變數 `HF_ENDPOINT` 設為對應的鏡像網站: + ```bash export HF_ENDPOINT=https://hf-mirror.com ``` 5.啟動後端服務: - 『`bash - source .venv/bin/activate - export PYTHONPATH=$(pwd) - bash docker/launch_backend_service.sh - ``` +『`bash +source .venv/bin/activate +export PYTHONPATH=$(pwd) +bash docker/launch_backend_service.sh + +``` 6. 安裝前端依賴: - 『`bash - cd web - npm install - ``` +『`bash +cd web +npm install +``` + 7. 啟動前端服務: 『`bash npm run dev + ``` 以下界面說明系統已成功啟動:_ ![](https://github.com/user-attachments/assets/0daf462c-a24d-4496-a66f-92533534e187) + ``` ## 📚 技術文檔 @@ -339,4 +350,3 @@ RAGFlow 只有透過開源協作才能蓬勃發展。秉持這項精神,我們

- diff --git a/README_zh.md b/README_zh.md index 88e7aa351d7..de162f7f1e7 100644 --- a/README_zh.md +++ b/README_zh.md @@ -9,7 +9,8 @@ 简体中文 | 日本語 | 한국어 | - Bahasa Indonesia + Bahasa Indonesia | + Português (Brasil)

@@ -30,7 +31,6 @@

-

Document | Roadmap | @@ -46,12 +46,12 @@ ## 🎮 Demo 试用 请登录网址 [https://demo.ragflow.io](https://demo.ragflow.io) 试用 demo。 +
- ## 🔥 近期更新 - 2024-12-18 升级了 Deepdoc 的文档布局分析模型。 @@ -62,12 +62,13 @@ - 2024-08-02 支持 GraphRAG 启发于 [graphrag](https://github.com/microsoft/graphrag) 和思维导图。 ## 🎉 关注项目 -⭐️点击右上角的 Star 关注RAGFlow,可以获取最新发布的实时通知 !🌟 + +⭐️ 点击右上角的 Star 关注 RAGFlow,可以获取最新发布的实时通知 !🌟 +
- ## 🌟 主要功能 ### 🍭 **"Quality in, quality out"** @@ -154,11 +155,12 @@ | ----------------- | --------------- | --------------------- | ------------------------ | | v0.15.1 | ≈9 | :heavy_check_mark: | Stable release | | v0.15.1-slim | ≈2 | ❌ | Stable release | - | nightly | ≈9 | :heavy_check_mark: | *Unstable* nightly build | - | nightly-slim | ≈2 | ❌ | *Unstable* nightly build | + | nightly | ≈9 | :heavy_check_mark: | _Unstable_ nightly build | + | nightly-slim | ≈2 | ❌ | _Unstable_ nightly build | - > [!TIP] + > [!TIP] > 如果你遇到 Docker 镜像拉不下来的问题,可以在 **docker/.env** 文件内根据变量 `RAGFLOW_IMAGE` 的注释提示选择华为云或者阿里云的相应镜像。 + > > - 华为云镜像名:`swr.cn-north-4.myhuaweicloud.com/infiniflow/ragflow` > - 阿里云镜像名:`registry.cn-hangzhou.aliyuncs.com/infiniflow/ragflow` @@ -171,17 +173,18 @@ _出现以下界面提示说明服务器启动成功:_ ```bash - ____ ___ ______ ______ __ + ____ ___ ______ ______ __ / __ \ / | / ____// ____// /____ _ __ / /_/ // /| | / / __ / /_ / // __ \| | /| / / - / _, _// ___ |/ /_/ // __/ / // /_/ /| |/ |/ / - /_/ |_|/_/ |_|\____//_/ /_/ \____/ |__/|__/ + / _, _// ___ |/ /_/ // __/ / // /_/ /| |/ |/ / + /_/ |_|/_/ |_|\____//_/ /_/ \____/ |__/|__/ * Running on all addresses (0.0.0.0) * Running on http://127.0.0.1:9380 * Running on http://x.x.x.x:9380 INFO:werkzeug:Press CTRL+C to quit ``` + > 如果您跳过这一步系统确认步骤就登录 RAGFlow,你的浏览器有可能会提示 `network anormal` 或 `网络异常`,因为 RAGFlow 可能并未完全启动成功。 5. 在你的浏览器中输入你的服务器对应的 IP 地址并登录 RAGFlow。 @@ -232,10 +235,9 @@ RAGFlow 默认使用 Elasticsearch 存储文本和向量数据. 如果要切换 $ docker compose -f docker/docker-compose.yml up -d ``` -> [!WARNING] +> [!WARNING] > Infinity 目前官方并未正式支持在 Linux/arm64 架构下的机器上运行. - ## 🔧 源码编译 Docker 镜像(不含 embedding 模型) 本 Docker 镜像大小约 2 GB 左右并且依赖外部的大模型和 embedding 服务。 @@ -258,53 +260,59 @@ docker build --build-arg NEED_MIRROR=1 -f Dockerfile -t infiniflow/ragflow:night ## 🔨 以源代码启动服务 -1. 安装 uv。如已经安装,可跳过本步骤: +1. 安装 uv。如已经安装,可跳过本步骤: + ```bash pipx install uv export UV_INDEX=https://pypi.tuna.tsinghua.edu.cn/simple ``` -2. 下载源代码并安装 Python 依赖: +2. 下载源代码并安装 Python 依赖: + ```bash git clone https://github.com/infiniflow/ragflow.git cd ragflow/ uv sync --python 3.10 --all-extras # install RAGFlow dependent python modules ``` -3. 通过 Docker Compose 启动依赖的服务(MinIO, Elasticsearch, Redis, and MySQL): +3. 通过 Docker Compose 启动依赖的服务(MinIO, Elasticsearch, Redis, and MySQL): + ```bash docker compose -f docker/docker-compose-base.yml up -d ``` - 在 `/etc/hosts` 中添加以下代码,将 **conf/service_conf.yaml** 文件中的所有 host 地址都解析为 `127.0.0.1`: + 在 `/etc/hosts` 中添加以下代码,将 **conf/service_conf.yaml** 文件中的所有 host 地址都解析为 `127.0.0.1`: + ``` 127.0.0.1 es01 infinity mysql minio redis - ``` + ``` + +4. 如果无法访问 HuggingFace,可以把环境变量 `HF_ENDPOINT` 设成相应的镜像站点: -4. 如果无法访问 HuggingFace,可以把环境变量 `HF_ENDPOINT` 设成相应的镜像站点: - ```bash export HF_ENDPOINT=https://hf-mirror.com ``` -5. 启动后端服务: +5. 启动后端服务: + ```bash source .venv/bin/activate export PYTHONPATH=$(pwd) bash docker/launch_backend_service.sh ``` -6. 安装前端依赖: +6. 安装前端依赖: ```bash cd web npm install - ``` -7. 启动前端服务: + ``` +7. 启动前端服务: + ```bash - npm run dev - ``` + npm run dev + ``` - _以下界面说明系统已经成功启动:_ + _以下界面说明系统已经成功启动:_ ![](https://github.com/user-attachments/assets/0daf462c-a24d-4496-a66f-92533534e187) @@ -340,4 +348,3 @@ RAGFlow 只有通过开源协作才能蓬勃发展。秉持这一精神,我们

- diff --git a/web/src/constants/common.ts b/web/src/constants/common.ts index 7bce63d7469..9b442556f8d 100644 --- a/web/src/constants/common.ts +++ b/web/src/constants/common.ts @@ -47,6 +47,7 @@ export const LanguageList = [ 'Spanish', 'Vietnamese', 'Japanese', + 'Portuguese BR', ]; export const LanguageMap = { @@ -57,6 +58,7 @@ export const LanguageMap = { Spanish: 'Español', Vietnamese: 'Tiếng việt', Japanese: '日本語', + 'Portuguese BR': 'Português BR', }; export const LanguageTranslationMap = { @@ -67,6 +69,7 @@ export const LanguageTranslationMap = { Spanish: 'es', Vietnamese: 'vi', Japanese: 'ja', + 'Portuguese BR': 'pt-br', }; export enum FileMimeType { diff --git a/web/src/locales/config.ts b/web/src/locales/config.ts index 50040306c3d..96d3a9579f8 100644 --- a/web/src/locales/config.ts +++ b/web/src/locales/config.ts @@ -6,6 +6,7 @@ import translation_en from './en'; import translation_es from './es'; import translation_id from './id'; import translation_ja from './ja'; +import translation_pt_br from './pt-br'; import { createTranslationTable, flattenObject } from './until'; import translation_vi from './vi'; import translation_zh from './zh'; @@ -19,12 +20,14 @@ const resources = { ja: translation_ja, es: translation_es, vi: translation_vi, + 'pt-br': translation_pt_br, }; const enFlattened = flattenObject(translation_en); const viFlattened = flattenObject(translation_vi); const esFlattened = flattenObject(translation_es); const zhFlattened = flattenObject(translation_zh); const jaFlattened = flattenObject(translation_ja); +const pt_brFlattened = flattenObject(translation_pt_br); const zh_traditionalFlattened = flattenObject(translation_zh_traditional); export const translationTable = createTranslationTable( [ @@ -34,8 +37,9 @@ export const translationTable = createTranslationTable( zhFlattened, zh_traditionalFlattened, jaFlattened, + pt_brFlattened, ], - ['English', 'Vietnamese', 'Spanish', 'zh', 'zh-TRADITIONAL', 'ja'], + ['English', 'Vietnamese', 'Spanish', 'zh', 'zh-TRADITIONAL', 'ja', 'pt-br'], ); i18n .use(initReactI18next) @@ -44,7 +48,7 @@ i18n detection: { lookupLocalStorage: 'lng', }, - supportedLngs: ['en', 'zh', 'zh-TRADITIONAL', 'id', 'es', 'vi', 'ja'], + supportedLngs: ['en', 'zh', 'zh-TRADITIONAL', 'id', 'es', 'vi', 'ja', 'pt-br'], resources, fallbackLng: 'en', interpolation: { diff --git a/web/src/locales/en.ts b/web/src/locales/en.ts index 19c901c1909..22832126caa 100644 --- a/web/src/locales/en.ts +++ b/web/src/locales/en.ts @@ -15,6 +15,7 @@ export default { edit: 'Edit', upload: 'Upload', english: 'English', + portugeseBr: 'Portuguese (Brazil)', chinese: 'Simplified Chinese', traditionalChinese: 'Traditional Chinese', language: 'Language', diff --git a/web/src/locales/es.ts b/web/src/locales/es.ts index 6dd26eca052..77474108423 100644 --- a/web/src/locales/es.ts +++ b/web/src/locales/es.ts @@ -16,6 +16,7 @@ export default { upload: 'Subir', english: 'Ingles', spanish: 'Español', + portugeseBr: 'Portugués (Brasil)', chinese: 'Chino simplificado', traditionalChinese: 'Chino tradicional', language: 'Idioma', diff --git a/web/src/locales/id.ts b/web/src/locales/id.ts index 99de1a64f97..635d0e940d7 100644 --- a/web/src/locales/id.ts +++ b/web/src/locales/id.ts @@ -16,6 +16,7 @@ export default { edit: 'Ubah', upload: 'Unggah', english: 'Inggris', + portugeseBr: 'Portugis (Brasil)', chinese: 'Cina', traditionalChinese: 'Cina Tradisional', language: 'Bahasa', diff --git a/web/src/locales/ja.ts b/web/src/locales/ja.ts index 58610652b02..cad44a46f44 100644 --- a/web/src/locales/ja.ts +++ b/web/src/locales/ja.ts @@ -15,6 +15,7 @@ export default { edit: '編集', upload: 'アップロード', english: '英語', + portugeseBr: 'ポルトガル語 (ブラジル)', chinese: '中国語(簡体字)', traditionalChinese: '中国語(繁体字)', language: '言語', diff --git a/web/src/locales/pt-br.ts b/web/src/locales/pt-br.ts new file mode 100644 index 00000000000..aee7a6a960f --- /dev/null +++ b/web/src/locales/pt-br.ts @@ -0,0 +1,1099 @@ +export default { + translation: { + common: { + delete: 'Excluir', + deleteModalTitle: 'Tem certeza de que deseja excluir este item?', + ok: 'Sim', + cancel: 'Não', + total: 'Total', + rename: 'Renomear', + name: 'Nome', + save: 'Salvar', + namePlaceholder: 'Por favor, insira o nome', + next: 'Próximo', + create: 'Criar', + edit: 'Editar', + upload: 'Carregar', + english: 'Inglês', + portugeseBr: 'Português (Brasil)', + chinese: 'Chinês Simplificado', + traditionalChinese: 'Chinês Tradicional', + language: 'Idioma', + languageMessage: 'Por favor, insira seu idioma!', + languagePlaceholder: 'selecione seu idioma', + copy: 'Copiar', + copied: 'Copiado', + comingSoon: 'Em breve', + download: 'Baixar', + close: 'Fechar', + preview: 'Pré-visualizar', + move: 'Mover', + warn: 'Aviso', + action: 'Ação', + s: 'S', + pleaseSelect: 'Por favor, selecione', + pleaseInput: 'Por favor, insira', + submit: 'Enviar', + embedIntoSite: 'Incorporar no site', + previousPage: 'Anterior', + nextPage: 'Próxima' + }, + login: { + login: 'Entrar', + signUp: 'Inscrever-se', + loginDescription: 'Estamos muito animados para vê-lo novamente!', + registerDescription: 'Feliz por tê-lo a bordo!', + emailLabel: 'Email', + emailPlaceholder: 'Por favor, insira o email', + passwordLabel: 'Senha', + passwordPlaceholder: 'Por favor, insira a senha', + rememberMe: 'Lembrar-me', + signInTip: 'Não tem uma conta?', + signUpTip: 'Já tem uma conta?', + nicknameLabel: 'Apelido', + nicknamePlaceholder: 'Por favor, insira o apelido', + register: 'Criar uma conta', + continue: 'Continuar', + title: 'Comece a construir seus assistentes inteligentes.', + description: 'Inscreva-se gratuitamente para explorar a tecnologia RAG de ponta. Crie bases de conhecimento e IAs para capacitar seu negócio.', + review: 'de 500+ avaliações' + }, + header: { + knowledgeBase: 'Base de Conhecimento', + chat: 'Chat', + register: 'Registrar', + signin: 'Entrar', + home: 'Início', + setting: 'Configurações do usuário', + logout: 'Sair', + fileManager: 'Gerenciamento de Arquivos', + flow: 'Agente', + search: 'Buscar' + }, + knowledgeList: { + welcome: 'Bem-vindo de volta', + description: 'Quais bases de conhecimento você usará hoje?', + createKnowledgeBase: 'Criar base de conhecimento', + name: 'Nome', + namePlaceholder: 'Por favor, insira o nome!', + doc: 'Documentos', + searchKnowledgePlaceholder: 'Buscar', + noMoreData: 'Isso é tudo. Nada mais.' + }, + knowledgeDetail: { + dataset: 'Conjunto de dados', + testing: 'Teste de recuperação', + files: 'Arquivos', + configuration: 'Configuração', + name: 'Nome', + namePlaceholder: 'Por favor, insira o nome!', + doc: 'Documentos', + datasetDescription: '😉 Por favor, aguarde o término da análise do seu arquivo antes de iniciar um chat com IA.', + addFile: 'Adicionar arquivo', + searchFiles: 'Buscar seus arquivos', + localFiles: 'Arquivos locais', + emptyFiles: 'Criar arquivo vazio', + webCrawl: 'Rastreamento na web', + chunkNumber: 'Número de fragmentos', + uploadDate: 'Data de upload', + chunkMethod: 'Método de fragmentação', + enabled: 'Habilitar', + disabled: 'Desabilitar', + action: 'Ação', + parsingStatus: 'Status da análise', + processBeginAt: 'Início em', + processDuration: 'Duração', + progressMsg: 'Progresso', + testingDescription: 'Realize um teste de recuperação para verificar se o RAGFlow pode recuperar o conteúdo pretendido para o LLM.', + similarityThreshold: 'Limite de similaridade', + similarityThresholdTip: 'O RAGFlow emprega uma combinação de similaridade de palavras-chave ponderada e similaridade de cosseno vetorial ponderada, ou uma combinação de similaridade de palavras-chave ponderada e pontuação de reranking ponderada durante a recuperação. Este parâmetro define o limite para similaridades entre a consulta do usuário e os fragmentos. Qualquer fragmento com uma pontuação de similaridade abaixo deste limite será excluído dos resultados.', + vectorSimilarityWeight: 'Peso da similaridade de palavras-chave', + vectorSimilarityWeightTip: 'Define o peso da similaridade de palavras-chave na pontuação de similaridade combinada, usada com a similaridade de cosseno vetorial ou com a pontuação de reranking. O total dos dois pesos deve ser igual a 1.0.', + testText: 'Texto de teste', + testTextPlaceholder: 'Insira sua pergunta aqui!', + testingLabel: 'Testando', + similarity: 'Similaridade híbrida', + termSimilarity: 'Similaridade de termos', + vectorSimilarity: 'Similaridade vetorial', + hits: 'Acertos', + view: 'Visualizar', + filesSelected: 'Arquivos selecionados', + upload: 'Carregar', + run: 'Analisar', + runningStatus0: 'Não analisado', + runningStatus1: 'Analisando', + runningStatus2: 'Cancelado', + runningStatus3: 'Sucesso', + runningStatus4: 'Falha', + pageRanges: 'Intervalos de páginas', + pageRangesTip: 'Intervalo de páginas a serem analisadas; páginas fora deste intervalo não serão processadas.', + fromPlaceholder: 'de', + fromMessage: 'Página inicial ausente', + toPlaceholder: 'até', + toMessage: 'Página final ausente (excluída)', + layoutRecognize: 'Reconhecimento de layout', + layoutRecognizeTip: 'Use modelos visuais para análise de layout para entender melhor a estrutura do documento e localizar efetivamente títulos, blocos de texto, imagens e tabelas. Se desativado, apenas o texto simples no PDF será recuperado.', + taskPageSize: 'Tamanho da página da tarefa', + taskPageSizeMessage: 'Por favor, insira o tamanho da página da tarefa!', + taskPageSizeTip: 'Durante o reconhecimento de layout, um arquivo PDF é dividido em fragmentos e processado em paralelo para aumentar a velocidade de processamento. Este parâmetro define o tamanho de cada fragmento. Um tamanho de fragmento maior reduz a probabilidade de dividir texto contínuo entre páginas.', + addPage: 'Adicionar página', + greaterThan: 'O valor atual deve ser maior que!', + greaterThanPrevious: 'O valor atual deve ser maior que o anterior!', + selectFiles: 'Selecionar arquivos', + changeSpecificCategory: 'Alterar categoria específica', + uploadTitle: 'Clique ou arraste o arquivo para esta área para fazer o upload', + uploadDescription: 'Suporte para upload único ou em massa. Estritamente proibido fazer upload de dados da empresa ou outros arquivos proibidos.', + chunk: 'Fragmento', + bulk: 'Em massa', + cancel: 'Cancelar', + rerankModel: 'Modelo de reranking', + rerankPlaceholder: 'Por favor, selecione', + rerankTip: 'Se deixado vazio, o RAGFlow usará uma combinação de similaridade de palavras-chave ponderada e similaridade de cosseno vetorial ponderada; se um modelo de reranking for selecionado, uma pontuação de reranking ponderada substituirá a similaridade de cosseno vetorial ponderada. Esteja ciente de que usar um modelo de reranking aumentará significativamente o tempo de resposta do sistema.', + topK: 'Top-K', + topKTip: 'K fragmentos serão alimentados em modelos de reranking.', + delimiter: 'Delimitador', + delimiterTip: 'Um delimitador ou separador pode consistir em um ou vários caracteres especiais. Se for múltiplos caracteres, certifique-se de que estejam entre crases (``). Por exemplo, se você configurar seus delimitadores assim: \n`##`;, seus textos serão separados em quebras de linha, símbolos de hash duplo (##) ou ponto e vírgula.', + html4excel: 'Excel para HTML', + html4excelTip: 'Quando ativado, a planilha será analisada em tabelas HTML, com no máximo 256 linhas por tabela. Caso contrário, será analisada em pares chave-valor por linha.', + autoKeywords: 'Palavras-chave automáticas', + autoKeywordsTip: 'Extraia automaticamente N palavras-chave para cada fragmento para aumentar sua classificação para consultas que contenham essas palavras-chave. Você pode verificar ou atualizar as palavras-chave adicionadas para um fragmento na lista de fragmentos. Esteja ciente de que tokens extras serão consumidos pelo LLM especificado nas "Configurações do modelo do sistema".', + autoQuestions: 'Perguntas automáticas', + autoQuestionsTip: `Extraia automaticamente N perguntas para cada fragmento para aumentar sua relevância em consultas que contenham essas perguntas. Você pode verificar ou atualizar as perguntas adicionadas a um fragmento na lista de fragmentos. Essa funcionalidade não interromperá o processo de fragmentação em caso de erro, exceto pelo fato de que pode adicionar um resultado vazio ao fragmento original. Esteja ciente de que tokens extras serão consumidos pelo LLM especificado nas 'Configurações do modelo do sistema'.`, + redo: 'Deseja limpar os {{chunkNum}} fragmentos existentes?', + setMetaData: 'Definir Metadados', + pleaseInputJson: 'Por favor, insira um JSON', + documentMetaTips: `

Os metadados estão no formato JSON (não são pesquisáveis). Eles serão adicionados ao prompt para o LLM se quaisquer fragmentos deste documento forem incluídos no prompt.

+

Exemplos:

+ Os metadados são:
+ + { + "Autor": "Alex Dowson", + "Data": "2024-11-12" + } +
+ O prompt será:
+

Documento: nome_do_documento

+

Autor: Alex Dowson

+

Data: 2024-11-12

+

Fragmentos relevantes a seguir:

+
    +
  • Aqui está o conteúdo do fragmento....
  • +
  • Aqui está o conteúdo do fragmento....
  • +
+ `, + metaData: 'Metadados', + }, + knowledgeConfiguration: { + titleDescription: + 'Atualize a configuração da sua base de conhecimento aqui, especialmente o método de fragmentação.', + name: 'Nome da base de conhecimento', + photo: 'Foto da base de conhecimento', + description: 'Descrição', + language: 'Idioma', + languageMessage: 'Por favor, insira seu idioma!', + languagePlaceholder: 'Por favor, insira seu idioma!', + permissions: 'Permissões', + embeddingModel: 'Modelo de incorporação', + chunkTokenNumber: 'Número de tokens por fragmento', + chunkTokenNumberMessage: 'O número de tokens por fragmento é obrigatório', + embeddingModelTip: + 'O modelo que converte fragmentos em embeddings. Ele não pode ser alterado depois que a base de conhecimento tiver fragmentos. Para mudar para um modelo diferente, é necessário excluir todos os fragmentos existentes.', + permissionsTip: + "Se definido como 'Equipe', todos os membros da equipe poderão gerenciar a base de conhecimento.", + chunkTokenNumberTip: + 'Define o limite de tokens para um fragmento. Um parágrafo com menos tokens que esse limite será combinado com o próximo parágrafo até que a contagem de tokens ultrapasse o limite, momento em que um fragmento será criado.', + chunkMethod: 'Método de fragmentação', + chunkMethodTip: 'Veja as dicas à direita.', + upload: 'Enviar', + english: 'Inglês', + chinese: 'Chinês', + embeddingModelPlaceholder: 'Por favor, selecione um modelo de incorporação', + chunkMethodPlaceholder: 'Por favor, selecione um método de fragmentação', + save: 'Salvar', + me: 'Somente eu', + team: 'Equipe', + cancel: 'Cancelar', + methodTitle: 'Descrição do método de fragmentação', + methodExamples: 'Exemplos', + methodExamplesDescription: + 'As capturas de tela a seguir são fornecidas para maior clareza.', + dialogueExamplesTitle: 'Exemplos de diálogos', + methodEmpty: + 'Aqui será exibida uma explicação visual das categorias da base de conhecimento', + book: `

Os formatos de arquivo suportados são DOCX, PDF, TXT.

+ Para cada livro em PDF, defina os intervalos de páginas para remover informações indesejadas e reduzir o tempo de análise.

`, + laws: `

Os formatos de arquivo suportados são DOCX, PDF, TXT.

+ Documentos legais normalmente seguem um formato de escrita rigoroso. Usamos recursos textuais para identificar pontos de divisão.

+ Os fragmentos terão granularidade compatível com 'ARTIGO', garantindo que todo o texto de nível superior seja incluído no fragmento.

`, + manual: `

Apenas PDF é suportado.

+ Assumimos que o manual tem uma estrutura hierárquica de seções, usando os títulos das seções inferiores como unidade básica para fragmentação. Assim, figuras e tabelas na mesma seção não serão separadas, o que pode resultar em fragmentos maiores.

`, + naive: `

Os formatos de arquivo suportados são DOCX, EXCEL, PPT, IMAGE, PDF, TXT, MD, JSON, EML, HTML.

+

Este método fragmenta arquivos de maneira 'simples':

+

+

  • Usa um modelo de detecção visual para dividir os textos em segmentos menores.
  • +
  • Depois, combina segmentos adjacentes até que a contagem de tokens ultrapasse o limite definido em 'Número de tokens por fragmento', criando então um fragmento.
  • `, + paper: `

    Apenas PDF é suportado.

    + Os artigos serão divididos por seção, como resumo, 1.1, 1.2.

    + Essa abordagem permite que o LLM resuma o artigo de forma mais eficaz e forneça respostas mais compreensíveis. No entanto, aumenta o contexto para conversas de IA e o custo computacional do LLM. Durante uma conversa, considere reduzir o valor de 'topN'.

    `, + presentation: `

    Os formatos de arquivo suportados são PDF, PPTX.

    + Cada página do slide é tratada como um fragmento, com sua imagem em miniatura armazenada.

    + Esse método de fragmentação é aplicado automaticamente a todos os arquivos PPT enviados, então não é necessário especificá-lo manualmente.

    `, + qa: `

    Este método suporta arquivos nos formatos EXCEL e CSV/TXT.

    +
  • Se o arquivo estiver no formato Excel, ele deve conter duas colunas sem cabeçalhos: uma para perguntas e outra para respostas, com a coluna de perguntas antes da de respostas. Múltiplas planilhas são aceitas, desde que as colunas estejam corretamente estruturadas.
  • +
  • Se o arquivo estiver no formato CSV/TXT, ele deve estar codificado em UTF-8 e usar TAB como delimitador para separar perguntas e respostas.
  • +

    Linhas de texto que não seguirem essas regras serão ignoradas, e cada par de Pergunta & Resposta será tratado como um fragmento distinto.

    `, + useRaptor: 'Usar RAPTOR para melhorar a recuperação', + useRaptorTip: + 'Processamento Abstrativo Recursivo para Recuperação Organizada em Árvore. Veja mais em https://huggingface.co/papers/2401.18059.', + prompt: 'Prompt', + promptTip: 'Prompt usado pelo LLM para sumarização.', + promptMessage: 'O prompt é obrigatório', + promptText: `Por favor, resuma os seguintes parágrafos. Tenha cuidado com os números, não invente informações. Os parágrafos são os seguintes: + {cluster_content} + O conteúdo acima precisa ser resumido.`, + maxToken: 'Máximo de tokens', + maxTokenTip: 'Número máximo de tokens para sumarização.', + maxTokenMessage: 'O número máximo de tokens é obrigatório', + threshold: 'Limite', + thresholdTip: 'Quanto maior o limite, menor será o número de clusters.', + thresholdMessage: 'O limite é obrigatório', + maxCluster: 'Máximo de clusters', + maxClusterTip: 'Número máximo de clusters.', + maxClusterMessage: 'O número máximo de clusters é obrigatório', + randomSeed: 'Semente aleatória', + randomSeedMessage: 'A semente aleatória é obrigatória', + entityTypes: 'Tipos de entidades', + vietnamese: 'Vietnamita', + pageRank: 'Ranking de páginas', + pageRankTip: `Isso aumenta a pontuação de relevância da base de conhecimento. Seu valor será adicionado à pontuação de relevância de todos os fragmentos recuperados dessa base de conhecimento. Útil ao pesquisar em múltiplas bases e querer priorizar uma específica.`, + tagName: 'Etiqueta', + frequency: 'Frequência', + searchTags: 'Pesquisar etiquetas', + tagCloud: 'Nuvem', + tagTable: 'Tabela', + tagSet: 'Conjunto de etiquetas', + tagSetTip: ` +

    Selecionar bases de conhecimento com 'Etiqueta' ajuda a etiquetar fragmentos.

    +

    Consultas nesses fragmentos também usarão etiquetas.

    +

    Isso melhora a precisão da recuperação adicionando mais informações ao conjunto de dados, especialmente quando há muitos fragmentos.

    +

    Diferenças entre etiquetas e palavras-chave:

    +
      +
    • As etiquetas são um conjunto fechado definido pelo usuário, enquanto palavras-chave são um conjunto aberto.
    • +
    • É necessário enviar conjuntos de etiquetas com exemplos antes de usá-los.
    • +
    • Palavras-chave são geradas pelo LLM, o que é caro e demorado.
    • +
    `, + topnTags: 'Top-N Etiquetas', + tags: 'Etiquetas', + addTag: 'Adicionar etiqueta', + }, + chunk: { + chunk: 'Fragmento', + bulk: 'Em massa', + selectAll: 'Selecionar tudo', + enabledSelected: 'Ativar selecionados', + disabledSelected: 'Desativar selecionados', + deleteSelected: 'Excluir selecionados', + search: 'Pesquisar', + all: 'Todos', + enabled: 'Ativado', + disabled: 'Desativado', + keyword: 'Palavra-chave', + function: 'Função', + chunkMessage: 'Por favor, insira um valor!', + full: 'Texto completo', + ellipse: 'Reticências', + graph: 'Grafo de conhecimento', + mind: 'Mapa mental', + question: 'Pergunta', + questionTip: `Se houver perguntas fornecidas, a incorporação do fragmento será baseada nelas.`, + }, + chat: { + newConversation: 'Nova conversa', + createAssistant: 'Criar um Assistente', + assistantSetting: 'Configuração do Assistente', + promptEngine: 'Motor de Prompt', + modelSetting: 'Configuração do Modelo', + chat: 'Chat', + newChat: 'Novo chat', + send: 'Enviar', + sendPlaceholder: 'Envie uma mensagem para o assistente...', + chatConfiguration: 'Configuração do Chat', + chatConfigurationDescription: + 'Configure aqui um assistente de chat dedicado às bases de conhecimento selecionadas! 💕', + assistantName: 'Nome do assistente', + assistantNameMessage: 'O nome do assistente é obrigatório', + namePlaceholder: 'Ex.: Jarvis Currículos', + assistantAvatar: 'Avatar do assistente', + language: 'Idioma', + emptyResponse: 'Resposta vazia', + emptyResponseTip: `Defina isto como uma resposta caso nenhuma informação seja encontrada nas bases de conhecimento para sua consulta, ou deixe este campo vazio para permitir que o LLM improvise quando nada for encontrado.`, + setAnOpener: 'Saudação inicial', + setAnOpenerInitial: `Olá! Sou seu assistente, como posso ajudar?`, + setAnOpenerTip: 'Defina uma saudação inicial para os usuários.', + knowledgeBases: 'Bases de conhecimento', + knowledgeBasesMessage: 'Por favor, selecione', + knowledgeBasesTip: + 'Selecione as bases de conhecimento para associar a este assistente de chat.', + system: 'Sistema', + systemInitialValue: `Você é um assistente inteligente. Por favor, resuma o conteúdo da base de conhecimento para responder à pergunta. Liste os dados da base de conhecimento e responda com detalhes. Quando todo o conteúdo da base de conhecimento for irrelevante para a pergunta, sua resposta deve incluir a frase "A resposta que você procura não foi encontrada na base de conhecimento!" As respostas devem considerar o histórico do chat. + Aqui está a base de conhecimento: + {knowledge} + O acima é a base de conhecimento.`, + systemMessage: 'Por favor, insira!', + systemTip: + 'Seus prompts ou instruções para o LLM, incluindo, mas não se limitando, ao papel, ao comprimento desejado, ao tom e ao idioma das respostas.', + topN: 'Top N', + topNTip: `Nem todos os fragmentos com pontuação de similaridade acima do 'limiar de similaridade' serão enviados ao LLM. Isso seleciona os 'Top N' fragmentos recuperados.`, + variable: 'Variável', + variableTip: `As variáveis podem ajudar a desenvolver estratégias mais flexíveis, especialmente ao usar nossas APIs de gerenciamento de assistentes de chat. Essas variáveis serão usadas pelo 'Sistema' como parte dos prompts para o LLM. A variável {knowledge} é uma variável especial reservada que representa suas bases de conhecimento selecionadas, e todas as variáveis devem estar entre chaves { }.`, + add: 'Adicionar', + key: 'Chave', + optional: 'Opcional', + operation: 'Operação', + model: 'Modelo', + modelTip: 'Modelo de chat com linguagem ampla', + modelMessage: 'Por favor, selecione!', + freedom: 'Liberdade', + improvise: 'Improvisar', + precise: 'Preciso', + balance: 'Equilíbrio', + freedomTip: `Um atalho para as configurações de 'Temperatura', 'Top P', 'Penalidade de presença' e 'Penalidade de frequência', indicando o nível de liberdade do modelo. Este parâmetro possui três opções: selecione 'Improvisar' para respostas mais criativas; selecione 'Preciso' (padrão) para respostas mais conservadoras; 'Equilíbrio' é um meio-termo entre 'Improvisar' e 'Preciso'.`, + temperature: 'Temperatura', + temperatureMessage: 'A temperatura é obrigatória', + temperatureTip: `Este parâmetro controla a aleatoriedade das previsões do modelo. Uma temperatura mais baixa resulta em respostas mais conservadoras, enquanto uma temperatura mais alta gera respostas mais criativas e diversificadas.`, + topP: 'Top P', + topPMessage: 'Top P é obrigatório', + topPTip: + 'Também conhecido como "amostragem por núcleo", este parâmetro define um limite para selecionar um conjunto menor das palavras mais prováveis para amostragem, cortando as menos prováveis.', + presencePenalty: 'Penalidade de presença', + presencePenaltyMessage: 'Penalidade de presença é obrigatória', + presencePenaltyTip: + 'Isso desencoraja o modelo de repetir as mesmas informações, penalizando palavras que já apareceram na conversa.', + frequencyPenalty: 'Penalidade de frequência', + frequencyPenaltyMessage: 'Penalidade de frequência é obrigatória', + frequencyPenaltyTip: + 'Semelhante à penalidade de presença, isso reduz a tendência do modelo de repetir as mesmas palavras frequentemente.', + maxTokens: 'Máximo de tokens', + maxTokensMessage: 'O máximo de tokens é obrigatório', + maxTokensTip: `Define o comprimento máximo da saída do modelo, medido pelo número de tokens (palavras ou partes de palavras). O padrão é 512. Se desativado, você remove o limite máximo de tokens, permitindo que o modelo determine o número de tokens em suas respostas.`, + maxTokensInvalidMessage: 'Por favor, insira um número válido para o máximo de tokens.', + maxTokensMinMessage: 'O máximo de tokens não pode ser menor que 0.', + quote: 'Mostrar citação', + quoteTip: 'Exibir ou não o texto original como referência.', + selfRag: 'Self-RAG', + selfRagTip: 'Consulte: https://huggingface.co/papers/2310.11511', + overview: 'ID do Chat', + pv: 'Número de mensagens', + uv: 'Número de usuários ativos', + speed: 'Velocidade de saída de tokens', + tokens: 'Consumo de tokens', + round: 'Número de interações por sessão', + thumbUp: 'Satisfação do cliente', + preview: 'Pré-visualizar', + embedded: 'Incorporado', + serviceApiEndpoint: 'Endpoint da API de Serviço', + apiKey: 'Chave da API', + apiReference: 'Documentos da API', + dateRange: 'Intervalo de datas:', + backendServiceApi: 'Servidor API', + createNewKey: 'Criar nova chave', + created: 'Criado', + action: 'Ação', + embedModalTitle: 'Incorporar no site', + comingSoon: 'Em breve', + fullScreenTitle: 'Incorporar Total', + fullScreenDescription: + 'Incorpore o iframe abaixo no local desejado em seu site', + partialTitle: 'Incorporar Parcial', + extensionTitle: 'Extensão do Chrome', + tokenError: 'Por favor, crie uma chave API primeiro.', + betaError: + 'Por favor, adquira uma chave API do RAGFlow na página Configurações do Sistema primeiro.', + searching: 'Pesquisando...', + parsing: 'Analisando', + uploading: 'Carregando', + uploadFailed: 'Falha no carregamento', + regenerate: 'Regenerar', + read: 'Ler conteúdo', + tts: 'Texto para fala', + ttsTip: + 'Certifique-se de selecionar um modelo TTS na página Configurações antes de habilitar esta opção para reproduzir texto como áudio.', + relatedQuestion: 'Pergunta relacionada', + answerTitle: 'R', + multiTurn: 'Otimização de múltiplas interações', + multiTurnTip: + 'Isso otimiza as consultas dos usuários usando o contexto em uma conversa de múltiplas rodadas. Quando ativado, consumirá tokens adicionais do LLM.', + howUseId: 'Como usar o ID do chat?', + description: 'Descrição do assistente', + }, + setting: { + profile: 'Perfil', + profileDescription: 'Atualize sua foto e detalhes pessoais aqui.', + maxTokens: 'Máximo de Tokens', + maxTokensMessage: 'Máximo de Tokens é obrigatório', + maxTokensTip: `Isso define o comprimento máximo da saída do modelo, medido em número de tokens (palavras ou partes de palavras). O padrão é 512. Se desativado, você remove o limite máximo de tokens, permitindo que o modelo determine o número de tokens em suas respostas.`, + maxTokensInvalidMessage: 'Por favor, insira um número válido para Máximo de Tokens.', + maxTokensMinMessage: 'O Máximo de Tokens não pode ser menor que 0.', + password: 'Senha', + passwordDescription: 'Digite sua senha atual para alterá-la.', + model: 'Provedores de Modelo', + modelDescription: 'Defina o parâmetro do modelo e a chave da API aqui.', + team: 'Equipe', + system: 'Sistema', + logout: 'Sair', + api: 'API', + username: 'Nome de usuário', + usernameMessage: 'Por favor, insira seu nome de usuário!', + photo: 'Sua foto', + photoDescription: 'Isso será exibido no seu perfil.', + colorSchema: 'Esquema de cores', + colorSchemaMessage: 'Por favor, selecione seu esquema de cores!', + colorSchemaPlaceholder: 'selecione seu esquema de cores', + bright: 'Claro', + dark: 'Escuro', + timezone: 'Fuso horário', + timezoneMessage: 'Por favor, insira seu fuso horário!', + timezonePlaceholder: 'selecione seu fuso horário', + email: 'Endereço de e-mail', + emailDescription: 'Após o registro, o e-mail não pode ser alterado.', + currentPassword: 'Senha atual', + currentPasswordMessage: 'Por favor, insira sua senha!', + newPassword: 'Nova senha', + newPasswordMessage: 'Por favor, insira sua nova senha!', + newPasswordDescription: 'Sua nova senha deve ter mais de 8 caracteres.', + confirmPassword: 'Confirmar nova senha', + confirmPasswordMessage: 'Por favor, confirme sua senha!', + confirmPasswordNonMatchMessage: 'A nova senha que você inseriu não corresponde!', + cancel: 'Cancelar', + addedModels: 'Modelos adicionados', + modelsToBeAdded: 'Modelos a serem adicionados', + addTheModel: 'Adicionar o modelo', + apiKey: 'Chave da API', + apiKeyMessage: 'Por favor, insira a chave da API (para modelos implantados localmente, ignore isso).', + apiKeyTip: 'A chave da API pode ser obtida registrando-se no fornecedor correspondente do LLM.', + showMoreModels: 'Mostrar mais modelos', + baseUrl: 'URL Base', + baseUrlTip: 'Se sua chave da API for do OpenAI, ignore isso. Outros provedores intermediários fornecerão essa URL base com a chave da API.', + modify: 'Modificar', + systemModelSettings: 'Configurações do Modelo do Sistema', + chatModel: 'Modelo de chat', + chatModelTip: 'O modelo LLM padrão que todos os novos bancos de conhecimento usarão.', + embeddingModel: 'Modelo de incorporação', + embeddingModelTip: 'O modelo de incorporação padrão que todos os novos bancos de conhecimento usarão.', + img2txtModel: 'Modelo Img2Txt', + img2txtModelTip: 'O modelo multimodal padrão que todos os novos bancos de conhecimento usarão. Ele pode descrever uma imagem ou vídeo.', + sequence2txtModel: 'Modelo Sequence2Txt', + sequence2txtModelTip: 'O modelo ASR padrão que todos os novos bancos de conhecimento usarão. Use este modelo para converter vozes em texto correspondente.', + rerankModel: 'Modelo de Reordenação', + rerankModelTip: 'O modelo de reordenação padrão usado para reordenar os fragmentos recuperados pelas perguntas dos usuários.', + ttsModel: 'Modelo TTS', + ttsModelTip: 'O modelo TTS padrão será usado para gerar fala durante as conversas sob demanda.', + workspace: 'Área de trabalho', + upgrade: 'Atualizar', + addLlmTitle: 'Adicionar LLM', + modelName: 'Nome do modelo', + modelID: 'ID do modelo', + modelUid: 'UID do modelo', + modelNameMessage: 'Por favor, insira o nome do seu modelo!', + modelType: 'Tipo de modelo', + modelTypeMessage: 'Por favor, insira o tipo do seu modelo!', + addLlmBaseUrl: 'URL base', + baseUrlNameMessage: 'Por favor, insira sua URL base!', + vision: 'Suporta visão?', + ollamaLink: 'Como integrar {{name}}', + FishAudioLink: 'Como usar FishAudio', + TencentCloudLink: 'Como usar TencentCloud ASR', + volcModelNameMessage: 'Por favor, insira o nome do seu modelo!', + addEndpointID: 'EndpointID do modelo', + endpointIDMessage: 'Por favor, insira o EndpointID do modelo', + addArkApiKey: 'VOLC ARK_API_KEY', + ArkApiKeyMessage: 'Por favor, insira sua ARK_API_KEY', + bedrockModelNameMessage: 'Por favor, insira o nome do seu modelo!', + addBedrockEngineAK: 'CHAVE DE ACESSO', + bedrockAKMessage: 'Por favor, insira sua CHAVE DE ACESSO', + addBedrockSK: 'CHAVE SECRETA', + bedrockSKMessage: 'Por favor, insira sua CHAVE SECRETA', + bedrockRegion: 'Região AWS', + bedrockRegionMessage: 'Por favor, selecione!', + 'us-east-1': 'Leste dos EUA (N. Virgínia)', + 'us-west-2': 'Oeste dos EUA (Oregon)', + 'ap-southeast-1': 'Ásia-Pacífico (Singapura)', + 'ap-northeast-1': 'Ásia-Pacífico (Tóquio)', + 'eu-central-1': 'Europa (Frankfurt)', + 'us-gov-west-1': 'AWS GovCloud (EUA-Oeste)', + 'ap-southeast-2': 'Ásia-Pacífico (Sydney)', + addHunyuanSID: 'Hunyuan Secret ID', + HunyuanSIDMessage: 'Por favor, insira seu Secret ID', + addHunyuanSK: 'Hunyuan Secret Key', + HunyuanSKMessage: 'Por favor, insira sua Secret Key', + addTencentCloudSID: 'TencentCloud Secret ID', + TencentCloudSIDMessage: 'Por favor, insira seu Secret ID', + addTencentCloudSK: 'TencentCloud Secret Key', + TencentCloudSKMessage: 'Por favor, insira sua Secret Key', + SparkModelNameMessage: 'Por favor, selecione o modelo Spark', + addSparkAPIPassword: 'Senha da API Spark', + SparkAPIPasswordMessage: 'Por favor, insira sua senha da API', + addSparkAPPID: 'ID do aplicativo Spark', + SparkAPPIDMessage: 'Por favor, insira seu ID do aplicativo', + addSparkAPISecret: 'Segredo da API Spark', + SparkAPISecretMessage: 'Por favor, insira seu segredo da API', + addSparkAPIKey: 'Chave da API Spark', + SparkAPIKeyMessage: 'Por favor, insira sua chave da API', + yiyanModelNameMessage: 'Por favor, insira o nome do modelo', + addyiyanAK: 'Chave da API yiyan', + yiyanAKMessage: 'Por favor, insira sua chave da API', + addyiyanSK: 'Chave secreta yiyan', + yiyanSKMessage: 'Por favor, insira sua chave secreta', + FishAudioModelNameMessage: 'Por favor, dê um nome ao seu modelo de síntese de voz', + addFishAudioAK: 'Chave da API Fish Audio', + addFishAudioAKMessage: 'Por favor, insira sua chave da API', + addFishAudioRefID: 'ID de referência do FishAudio', + addFishAudioRefIDMessage: 'Por favor, insira o ID de referência (deixe em branco para usar o modelo padrão).', + modelProvidersWarn: `Por favor, adicione tanto o modelo de incorporação quanto o LLM em Configurações > Provedores de Modelo primeiro. Depois, defina-os nas 'Configurações do modelo do sistema'.`, + apiVersion: 'Versão da API', + apiVersionMessage: 'Por favor, insira a versão da API', + add: 'Adicionar', + updateDate: 'Data de atualização', + role: 'Função', + invite: 'Convidar', + agree: 'Aceitar', + refuse: 'Recusar', + teamMembers: 'Membros da equipe', + joinedTeams: 'Equipes ingressadas', + sureDelete: 'Tem certeza de que deseja remover este membro?', + quit: 'Sair', + sureQuit: 'Tem certeza de que deseja sair da equipe que você ingressou?', + }, + message: { + registered: 'Registrado!', + logout: 'sair', + logged: 'conectado!', + pleaseSelectChunk: 'Por favor, selecione o pedaço!', + modified: 'Modificado', + created: 'Criado', + deleted: 'Deletado', + renamed: 'Renomeado', + operated: 'Operado', + updated: 'Atualizado', + uploaded: 'Carregado', + 200: 'O servidor retornou com sucesso os dados solicitados.', + 201: 'Dados criados ou modificados com sucesso.', + 202: 'Uma solicitação foi colocada na fila em segundo plano (tarefa assíncrona).', + 204: 'Dados deletados com sucesso.', + 400: 'Houve um erro na solicitação emitida, e o servidor não criou ou modificou os dados.', + 401: 'O usuário não tem permissões (token, nome de usuário ou senha incorretos).', + 403: 'O usuário está autorizado, mas o acesso é proibido.', + 404: 'A solicitação foi feita para um registro que não existe, e o servidor não executou a operação.', + 406: 'O formato solicitado não está disponível.', + 410: 'O recurso solicitado foi permanentemente deletado e não estará mais disponível.', + 413: 'O tamanho total dos arquivos carregados de uma vez é muito grande.', + 422: 'Ao criar um objeto, ocorreu um erro de validação.', + 500: 'Ocorreu um erro no servidor, por favor, verifique o servidor.', + 502: 'Erro de gateway.', + 503: 'O serviço está indisponível e o servidor está temporariamente sobrecarregado ou em manutenção.', + 504: 'Timeout de gateway.', + requestError: 'Erro na solicitação', + networkAnomalyDescription: + 'Há uma anomalia na sua rede e você não consegue se conectar ao servidor.', + networkAnomaly: 'anomalia de rede', + hint: 'dica', + }, + fileManager: { + name: 'Nome', + uploadDate: 'Data de Upload', + knowledgeBase: 'Base de Conhecimento', + size: 'Tamanho', + action: 'Ação', + addToKnowledge: 'Link para a Base de Conhecimento', + pleaseSelect: 'Por favor, selecione', + newFolder: 'Nova Pasta', + file: 'Arquivo', + uploadFile: 'Carregar Arquivo', + directory: 'Diretório', + uploadTitle: 'Clique ou arraste o arquivo para esta área para fazer o upload', + uploadDescription: + 'Suporta upload de um único arquivo ou múltiplos arquivos. É estritamente proibido o upload de dados da empresa ou outros arquivos proibidos.', + local: 'Uploads locais', + s3: 'Uploads S3', + preview: 'Pré-visualização', + fileError: 'Erro no arquivo', + uploadLimit: + 'O tamanho do arquivo não pode exceder 10M, e o número total de arquivos não pode exceder 128', + destinationFolder: 'Pasta de destino', + }, + flow: { + cite: 'Citar', + citeTip: 'dicaDeCitação', + name: 'Nome', + nameMessage: 'Por favor, insira o nome', + description: 'Descrição', + examples: 'Exemplos', + to: 'Para', + msg: 'Mensagens', + messagePlaceholder: 'mensagem', + messageMsg: 'Por favor, insira uma mensagem ou delete este campo.', + addField: 'Adicionar opção', + addMessage: 'Adicionar mensagem', + loop: 'Loop', + loopTip: + 'O loop é o limite superior do número de repetições do componente atual. Quando o número de repetições excede o valor do loop, significa que o componente não pode completar a tarefa atual, por favor, reotimize o agente', + yes: 'Sim', + no: 'Não', + key: 'Chave', + componentId: 'ID do componente', + add: 'Adicionar', + operation: 'Operação', + run: 'Executar', + save: 'Salvar', + title: 'ID:', + beginDescription: 'Aqui é onde o fluxo começa.', + answerDescription: `Um componente que serve como a interface entre o ser humano e o bot, recebendo entradas do usuário e exibindo as respostas do agente.`, + retrievalDescription: `Um componente que recupera informações de bases de conhecimento especificadas (conjuntos de dados). Certifique-se de que as bases de conhecimento que você seleciona utilizam o mesmo modelo de incorporação.`, + generateDescription: `Um componente que solicita ao LLM gerar respostas. Certifique-se de que o prompt está configurado corretamente.`, + categorizeDescription: `Um componente que utiliza o LLM para classificar as entradas do usuário em categorias predefinidas. Certifique-se de especificar o nome, a descrição e os exemplos para cada categoria, juntamente com o próximo componente correspondente.`, + relevantDescription: `Um componente que usa o LLM para avaliar se a saída anterior é relevante para a última consulta do usuário. Certifique-se de especificar o próximo componente para cada resultado de avaliação.`, + rewriteQuestionDescription: `Um componente que refina uma consulta do usuário caso ela não recupere informações relevantes da base de conhecimento. Esse processo é repetido até que o limite de repetições predefinido seja alcançado.`, + messageDescription: + "Um componente que envia uma mensagem estática. Se várias mensagens forem fornecidas, uma delas será selecionada aleatoriamente para ser enviada. Certifique-se de que o componente posterior seja 'Interagir', o componente de interface.", + keywordDescription: `Um componente que recupera os N melhores resultados de pesquisa a partir da entrada do usuário. Certifique-se de que o valor de TopN esteja configurado corretamente antes de usar.`, + switchDescription: `Um componente que avalia condições com base na saída de componentes anteriores e direciona o fluxo de execução conforme necessário. Ele permite lógica de ramificação complexa, definindo casos e especificando ações para cada caso ou ação padrão caso nenhuma condição seja atendida.`, + wikipediaDescription: `Um componente que realiza buscas no wikipedia.org, utilizando TopN para especificar o número de resultados de pesquisa. Ele complementa as bases de conhecimento existentes.`, + promptText: `Por favor, resuma os seguintes parágrafos. Tenha cuidado com os números, não invente nada. Os parágrafos são os seguintes: + {input} Acima está o conteúdo que você precisa resumir.`, + createGraph: 'Criar agente', + createFromTemplates: 'Criar a partir de modelos', + retrieval: 'Recuperação', + generate: 'Gerar', + answer: 'Interagir', + categorize: 'Categorizar', + relevant: 'Relevante', + rewriteQuestion: 'Reescrever', + rewrite: 'Reescrever', + begin: 'Começar', + message: 'Mensagem', + blank: 'Em branco', + createFromNothing: 'Crie seu agente do zero', + addItem: 'Adicionar Item', + addSubItem: 'Adicionar Subitem', + nameRequiredMsg: 'Nome é obrigatório', + nameRepeatedMsg: 'O nome não pode ser repetido', + keywordExtract: 'Palavra-chave', + keywordExtractDescription: `Um componente que extrai palavras-chave de uma consulta do usuário, com Top N especificando o número de palavras-chave a serem extraídas.`, + baidu: 'Baidu', + baiduDescription: `Um componente que realiza buscas no baidu.com, utilizando TopN para especificar o número de resultados de pesquisa. Ele complementa as bases de conhecimento existentes.`, + duckDuckGo: 'DuckDuckGo', + duckDuckGoDescription: + 'Um componente que realiza buscas no duckduckgo.com, permitindo especificar o número de resultados de pesquisa usando TopN. Ele complementa as bases de conhecimento existentes.', + channel: 'Canal', + channelTip: `Realize uma busca por texto ou por notícias na entrada do componente`, + text: 'Texto', + news: 'Notícias', + messageHistoryWindowSize: 'Tamanho da janela de mensagens', + messageHistoryWindowSizeTip: + 'O tamanho da janela do histórico de conversa que precisa ser visualizado pelo LLM. Quanto maior, melhor. Mas tenha cuidado com o comprimento máximo de conteúdo do LLM.', + wikipedia: 'Wikipedia', + pubMed: 'PubMed', + pubMedDescription: + 'Um componente que realiza buscas em https://pubmed.ncbi.nlm.nih.gov/, permitindo especificar o número de resultados de pesquisa usando TopN. Ele complementa as bases de conhecimento existentes.', + email: 'Email', + emailTip: + 'O E-mail é um campo obrigatório. Você deve inserir um endereço de E-mail aqui.', + arXiv: 'ArXiv', + arXivDescription: + 'Um componente que realiza buscas em https://arxiv.org/, permitindo especificar o número de resultados de pesquisa usando TopN. Ele complementa as bases de conhecimento existentes.', + sortBy: 'Ordenar por', + submittedDate: 'Data de envio', + lastUpdatedDate: 'Última data de atualização', + relevance: 'Relevância', + google: 'Google', + googleDescription: + 'Um componente que realiza buscas em https://www.google.com/, permitindo especificar o número de resultados de pesquisa usando TopN. Ele complementa as bases de conhecimento existentes. Observe que isso requer uma chave API de serpapi.com.', + bing: 'Bing', + bingDescription: + 'Um componente que realiza buscas em https://www.bing.com/, permitindo especificar o número de resultados de pesquisa usando TopN. Ele complementa as bases de conhecimento existentes. Observe que isso requer uma chave API de microsoft.com.', + apiKey: 'CHAVE API', + country: 'País&Região', + language: 'Idioma', + googleScholar: 'Google Scholar', + googleScholarDescription: + 'Um componente que realiza buscas em https://scholar.google.com/. Você pode usar Top N para especificar o número de resultados de pesquisa.', + yearLow: 'Ano mínimo', + yearHigh: 'Ano máximo', + patents: 'Patentes', + data: 'Dados', + deepL: 'DeepL', + deepLDescription: + 'Um componente que realiza traduções mais especializadas a partir de https://www.deepl.com/.', + authKey: 'Chave de autenticação', + sourceLang: 'Idioma de origem', + targetLang: 'Idioma de destino', + gitHub: 'GitHub', + gitHubDescription: + 'Um componente que realiza buscas por repositórios em https://github.com/. Você pode usar Top N para especificar o número de resultados de pesquisa.', + baiduFanyi: 'BaiduFanyi', + baiduFanyiDescription: + 'Um componente que realiza traduções especializadas a partir de https://fanyi.baidu.com/.', + appid: 'ID do App', + secretKey: 'Chave secreta', + domain: 'Domínio', + transType: 'Tipo de tradução', + baiduSecretKeyOptions: { + translate: 'Tradução geral', + fieldtranslate: 'Tradução de campo', + }, + baiduDomainOptions: { + it: 'Tecnologia da informação', + finance: 'Finanças e economia', + machinery: 'Fabricação de máquinas', + senimed: 'Biomedicina', + novel: 'Literatura online', + academic: 'Artigo acadêmico', + aerospace: 'Aeroespacial', + wiki: 'Humanidades e ciências sociais', + news: 'Notícias e informações', + law: 'Leis e regulamentos', + contract: 'Contrato', + }, + baiduSourceLangOptions: { + auto: 'Detecção automática', + zh: 'Chinês', + en: 'Inglês', + yue: 'Cantonês', + wyw: 'Chinês clássico', + jp: 'Japonês', + kor: 'Coreano', + fra: 'Francês', + spa: 'Espanhol', + th: 'Tailandês', + ara: 'Árabe', + ru: 'Russo', + pt: 'Português', + de: 'Alemão', + it: 'Italiano', + el: 'Grego', + nl: 'Holandês', + pl: 'Polonês', + bul: 'Búlgaro', + est: 'Estoniano', + dan: 'Dinamarquês', + fin: 'Finlandês', + cs: 'Tcheco', + rom: 'Romeno', + slo: 'Esloveno', + swe: 'Sueco', + hu: 'Húngaro', + cht: 'Chinês tradicional', + vie: 'Vietnamita', + }, + + qWeather: 'QWeather', + qWeatherDescription: + 'Um componente que recupera informações meteorológicas, como temperatura e qualidade do ar, de https://www.qweather.com.', + + lang: 'Idioma', + type: 'Tipo', + webApiKey: 'Chave de API da Web', + userType: 'Tipo de usuário', + timePeriod: 'Período de tempo', + + qWeatherLangOptions: { + zh: 'Chinês simplificado', + 'zh-hant': 'Chinês tradicional', + en: 'Inglês', + de: 'Alemão', + es: 'Espanhol', + fr: 'Francês', + it: 'Italiano', + ja: 'Japonês', + ko: 'Coreano', + ru: 'Russo', + hi: 'Hindi', + th: 'Tailandês', + ar: 'Árabe', + pt: 'Português', + bn: 'Bengali', + ms: 'Malaio', + nl: 'Holandês', + el: 'Grego', + la: 'Latim', + sv: 'Sueco', + id: 'Indonésio', + pl: 'Polonês', + tr: 'Turco', + cs: 'Tcheco', + et: 'Estoniano', + vi: 'Vietnamita', + fil: 'Filipino', + fi: 'Finlandês', + he: 'Hebraico', + is: 'Islandês', + nb: 'Norueguês', + }, + + qWeatherTypeOptions: { + weather: 'Previsão do tempo', + indices: 'Índice de qualidade de vida relacionado ao clima', + airquality: 'Qualidade do ar', + }, + qWeatherUserTypeOptions: { + free: 'Assinante gratuito', + paid: 'Assinante pago', + }, + + qWeatherTimePeriodOptions: { + now: 'Agora', + '3d': '3 dias', + '7d': '7 dias', + '10d': '10 dias', + '15d': '12 dias', + '30d': '30 dias', + }, + + publish: 'API', + exeSQL: 'ExeSQL', + exeSQLDescription: + 'Um componente que executa consultas SQL em um banco de dados relacional, suportando consultas de MySQL, PostgreSQL ou MariaDB.', + + dbType: 'Tipo de banco de dados', + database: 'Banco de dados', + username: 'Nome de usuário', + host: 'Hospedeiro', + port: 'Porta', + password: 'Senha', + switch: 'Trocar', + logicalOperator: 'Operador lógico', + switchOperatorOptions: { + equal: 'igual', + notEqual: 'diferente', + gt: 'Maior que', + ge: 'Maior ou igual', + lt: 'Menor que', + le: 'Menor ou igual', + contains: 'Contém', + notContains: 'Não contém', + startWith: 'Começa com', + endWith: 'Termina com', + empty: 'Vazio', + notEmpty: 'Não vazio', + }, + + switchLogicOperatorOptions: { + and: 'E', + or: 'Ou', + }, + + operator: 'Operador', + value: 'Valor', + useTemplate: 'Usar este modelo', + wenCai: 'WenCai', + queryType: 'Tipo de consulta', + wenCaiDescription: + 'Um componente que obtém informações financeiras, incluindo preços de ações e notícias de financiamento, de uma ampla variedade de sites financeiros.', + + wenCaiQueryTypeOptions: { + stock: 'Ação', + zhishu: 'Índice', + fund: 'Fundo', + hkstock: 'Ações de Hong Kong', + usstock: 'Mercado de ações dos EUA', + threeboard: 'Mercado OTC Novo', + conbond: 'Título Conversível', + insurance: 'Seguro', + futures: 'Futuros', + lccp: 'Financiamento', + foreign_exchange: 'Câmbio', + }, + + akShare: 'AkShare', + akShareDescription: + 'Um componente que obtém notícias sobre ações de https://www.eastmoney.com/.', + + yahooFinance: 'YahooFinance', + yahooFinanceDescription: + 'Um componente que consulta informações sobre uma empresa de capital aberto usando seu símbolo de ticker.', + + crawler: 'Rastreador Web', + crawlerDescription: + 'Um componente que rastreia o código-fonte HTML de um URL especificado.', + + proxy: 'Proxy', + crawlerResultOptions: { + html: 'Html', + markdown: 'Markdown', + content: 'Conteúdo', + }, + + extractType: 'Tipo de extração', + info: 'Informações', + history: 'Histórico', + financials: 'Financeiro', + balanceSheet: 'Balanço patrimonial', + cashFlowStatement: 'Demonstração de fluxo de caixa', + jin10: 'Jin10', + jin10Description: + 'Um componente que obtém informações financeiras da Plataforma Aberta Jin10, incluindo notícias, calendários, cotações e referências.', + + flashType: 'Tipo de Flash', + filter: 'Filtro', + contain: 'Contém', + calendarType: 'Tipo de calendário', + calendarDatashape: 'Formato de dados do calendário', + symbolsDatatype: 'Tipo de dados de símbolos', + symbolsType: 'Tipo de símbolos', + jin10TypeOptions: { + flash: 'Notícias rápidas', + calendar: 'Calendário', + symbols: 'Cotações', + news: 'Referência', + }, + + jin10FlashTypeOptions: { + '1': 'Notícias do Mercado', + '2': 'Notícias de Futuros', + '3': 'Notícias EUA-Hong Kong', + '4': 'Notícias A-Share', + '5': 'Notícias de Commodities & Forex', + }, + + jin10CalendarTypeOptions: { + cj: 'Calendário de dados macroeconômicos', + qh: 'Calendário de Futuros', + hk: 'Calendário do mercado de ações de Hong Kong', + us: 'Calendário do mercado de ações dos EUA', + }, + + jin10CalendarDatashapeOptions: { + data: 'Dados', + event: 'Evento', + holiday: 'Feriado', + }, + + jin10SymbolsTypeOptions: { + GOODS: 'Cotações de commodities', + FOREX: 'Cotações de Forex', + FUTURE: 'Cotações do mercado internacional', + CRYPTO: 'Cotações de criptomoedas', + }, + + jin10SymbolsDatatypeOptions: { + symbols: 'Lista de commodities', + quotes: 'Últimas cotações do mercado', + }, + concentrator: 'Concentrador', + concentratorDescription: + 'Um componente que recebe a saída do componente anterior e a passa como entrada para os componentes subsequentes.', + + tuShare: 'TuShare', + tuShareDescription: + 'Um componente que obtém resumos de notícias financeiras de sites financeiros principais, auxiliando pesquisas industriais e quantitativas.', + + tuShareSrcOptions: { + sina: 'Sina', + wallstreetcn: 'wallstreetcn', + '10jqka': 'Straight flush', + eastmoney: 'Eastmoney', + yuncaijing: 'YUNCAIJING', + fenghuang: 'FENGHUANG', + jinrongjie: 'JRJ', + }, + + token: 'Token', + src: 'Fonte', + startDate: 'Data de início', + endDate: 'Data de término', + keyword: 'Palavra-chave', + note: 'Nota', + noteDescription: 'Nota', + notePlaceholder: 'Por favor, insira uma nota', + + invoke: 'Invocar', + invokeDescription: + 'Um componente capaz de chamar serviços remotos, usando saídas de outros componentes ou constantes como entradas.', + + url: 'Url', + method: 'Método', + timeout: 'Tempo de espera', + headers: 'Cabeçalhos', + cleanHtml: 'Limpar HTML', + cleanHtmlTip: + 'Se a resposta for formatada em HTML e apenas o conteúdo principal for desejado, ative esta opção.', + + reference: 'Referência', + input: 'Entrada', + output: 'Saída', + parameter: 'Parâmetro', + howUseId: 'Como usar o ID do agente?', + content: 'Conteúdo', + operationResults: 'Resultados da operação', + autosaved: 'Autossalvo', + optional: 'Opcional', + pasteFileLink: 'Cole o link do arquivo', + testRun: 'Executar teste', + template: 'Modelo', + templateDescription: + 'Um componente que formata a saída de outro componente.', + + emailComponent: 'Email', + emailDescription: 'Enviar um email para um endereço especificado.', + smtpServer: 'Servidor SMTP', + smtpPort: 'Porta SMTP', + senderEmail: 'Email do remetente', + authCode: 'Código de autorização', + senderName: 'Nome do remetente', + toEmail: 'Email do destinatário', + ccEmail: 'Email CC', + emailSubject: 'Assunto', + emailContent: 'Conteúdo', + smtpServerRequired: 'Por favor, insira o endereço do servidor SMTP', + senderEmailRequired: 'Por favor, insira o email do remetente', + authCodeRequired: 'Por favor, insira o código de autorização', + toEmailRequired: 'Por favor, insira o email do destinatário', + emailContentRequired: 'Por favor, insira o conteúdo do email', + emailSentSuccess: 'Email enviado com sucesso', + emailSentFailed: 'Falha ao enviar o email', + + dynamicParameters: 'Parâmetros dinâmicos', + jsonFormatTip: + 'O componente anterior deve fornecer a string JSON no seguinte formato:', + toEmailTip: 'to_email: Email do destinatário (Obrigatório)', + ccEmailTip: 'cc_email: Email CC (Opcional)', + subjectTip: 'subject: Assunto do email (Opcional)', + contentTip: 'content: Conteúdo do email (Opcional)', + jsonUploadTypeErrorMessage: 'Por favor, carregue um arquivo json', + jsonUploadContentErrorMessage: 'Erro no arquivo json', + + iteration: 'Iteração', + iterationDescription: + 'Este componente primeiramente divide a entrada em um array pelo "delimitador". Realiza os mesmos passos de operação nos elementos do array em sequência até que todos os resultados sejam gerados, o que pode ser entendido como um processador de tarefas em lote. Por exemplo, dentro do nó de tradução de texto longo, se todo o conteúdo for enviado ao nó LLM, o limite de conversação pode ser atingido. O nó anterior pode primeiro dividir o texto longo em fragmentos e cooperar com o nó iterativo para realizar a tradução em lote de cada fragmento para evitar atingir o limite de mensagem do LLM em uma única conversa.', + + delimiterTip: + 'Este delimitador é usado para dividir o texto de entrada em várias partes, cuja saída será realizada como entrada de cada iteração.', + + delimiterOptions: { + comma: 'Vírgula', + lineBreak: 'Quebra de linha', + tab: 'Tabulação', + underline: 'Sublinhado', + diagonal: 'Diagonal', + minus: 'Menos', + semicolon: 'Ponto e vírgula', + }, + addVariable: 'Adicionar variável', + variableSettings: 'Configurações da variável', + globalVariables: 'Variáveis globais', + systemPrompt: 'Prompt do sistema', + addCategory: 'Adicionar categoria', + categoryName: 'Nome da categoria', + nextStep: 'Próximo passo', + footer: { + profile: 'Todos os direitos reservados @ React', + }, + layout: { + file: 'arquivo', + knowledge: 'conhecimento', + chat: 'bate-papo', + }, + }, + }, +}; + diff --git a/web/src/locales/vi.ts b/web/src/locales/vi.ts index d4c93f19341..ef0e4988e65 100644 --- a/web/src/locales/vi.ts +++ b/web/src/locales/vi.ts @@ -15,6 +15,7 @@ export default { edit: 'Sửa', upload: 'Tải lên', english: 'Tiếng Anh', + portugueseBr: 'Tiếng Bồ Đào Nha (Brazil)', chinese: 'Tiếng Trung giản thể', traditionalChinese: 'Tiếng Trung phồn thể', language: 'Ngôn ngữ', diff --git a/web/src/locales/zh-traditional.ts b/web/src/locales/zh-traditional.ts index 810deedf3d6..0e983f4045b 100644 --- a/web/src/locales/zh-traditional.ts +++ b/web/src/locales/zh-traditional.ts @@ -15,6 +15,7 @@ export default { edit: '編輯', upload: '上傳', english: '英語', + portugeseBr: '葡萄牙語 (巴西)', chinese: '簡體中文', traditionalChinese: '繁體中文', language: '語言', diff --git a/web/src/locales/zh.ts b/web/src/locales/zh.ts index 5c28c78b9e2..837d9a5b42f 100644 --- a/web/src/locales/zh.ts +++ b/web/src/locales/zh.ts @@ -15,6 +15,7 @@ export default { edit: '编辑', upload: '上传', english: '英文', + portugeseBr: '葡萄牙语 (巴西)', chinese: '简体中文', traditionalChinese: '繁体中文', language: '语言', diff --git a/web/src/pages/user-setting/setting-locale/index.tsx b/web/src/pages/user-setting/setting-locale/index.tsx index 373906f68af..b3f262c0596 100644 --- a/web/src/pages/user-setting/setting-locale/index.tsx +++ b/web/src/pages/user-setting/setting-locale/index.tsx @@ -12,6 +12,7 @@ function UserSettingLocale() { 'zh', 'zh-TRADITIONAL', 'ja', + 'pt-br', ]} /> ); From 21052b2972130a5e115f72612c82a576f2d74833 Mon Sep 17 00:00:00 2001 From: balibabu Date: Tue, 21 Jan 2025 11:32:47 +0800 Subject: [PATCH 6/9] Feat: Support for Portuguese language #4557 (#4558) ### What problem does this PR solve? Feat: Support for Portuguese language #4557 ### Type of change - [x] New Feature (non-breaking change which adds functionality) --- web/src/locales/config.ts | 15 +++- web/src/locales/en.ts | 2 +- web/src/locales/es.ts | 2 +- web/src/locales/id.ts | 2 +- web/src/locales/ja.ts | 2 +- web/src/locales/pt-br.ts | 143 ++++++++++++++++++------------ web/src/locales/zh-traditional.ts | 2 +- web/src/locales/zh.ts | 2 +- 8 files changed, 104 insertions(+), 66 deletions(-) diff --git a/web/src/locales/config.ts b/web/src/locales/config.ts index 96d3a9579f8..fccdfd83c00 100644 --- a/web/src/locales/config.ts +++ b/web/src/locales/config.ts @@ -20,7 +20,7 @@ const resources = { ja: translation_ja, es: translation_es, vi: translation_vi, - 'pt-br': translation_pt_br, + 'pt-BR': translation_pt_br, }; const enFlattened = flattenObject(translation_en); const viFlattened = flattenObject(translation_vi); @@ -39,7 +39,7 @@ export const translationTable = createTranslationTable( jaFlattened, pt_brFlattened, ], - ['English', 'Vietnamese', 'Spanish', 'zh', 'zh-TRADITIONAL', 'ja', 'pt-br'], + ['English', 'Vietnamese', 'Spanish', 'zh', 'zh-TRADITIONAL', 'ja', 'pt-BR'], ); i18n .use(initReactI18next) @@ -48,7 +48,16 @@ i18n detection: { lookupLocalStorage: 'lng', }, - supportedLngs: ['en', 'zh', 'zh-TRADITIONAL', 'id', 'es', 'vi', 'ja', 'pt-br'], + supportedLngs: [ + 'en', + 'zh', + 'zh-TRADITIONAL', + 'id', + 'es', + 'vi', + 'ja', + 'pt-BR', + ], resources, fallbackLng: 'en', interpolation: { diff --git a/web/src/locales/en.ts b/web/src/locales/en.ts index 22832126caa..bfcd21223eb 100644 --- a/web/src/locales/en.ts +++ b/web/src/locales/en.ts @@ -15,7 +15,7 @@ export default { edit: 'Edit', upload: 'Upload', english: 'English', - portugeseBr: 'Portuguese (Brazil)', + portugueseBr: 'Portuguese (Brazil)', chinese: 'Simplified Chinese', traditionalChinese: 'Traditional Chinese', language: 'Language', diff --git a/web/src/locales/es.ts b/web/src/locales/es.ts index 77474108423..36ba3824f7e 100644 --- a/web/src/locales/es.ts +++ b/web/src/locales/es.ts @@ -16,7 +16,7 @@ export default { upload: 'Subir', english: 'Ingles', spanish: 'Español', - portugeseBr: 'Portugués (Brasil)', + portugueseBr: 'Portugués (Brasil)', chinese: 'Chino simplificado', traditionalChinese: 'Chino tradicional', language: 'Idioma', diff --git a/web/src/locales/id.ts b/web/src/locales/id.ts index 635d0e940d7..c80ff46531b 100644 --- a/web/src/locales/id.ts +++ b/web/src/locales/id.ts @@ -16,7 +16,7 @@ export default { edit: 'Ubah', upload: 'Unggah', english: 'Inggris', - portugeseBr: 'Portugis (Brasil)', + portugueseBr: 'Portugis (Brasil)', chinese: 'Cina', traditionalChinese: 'Cina Tradisional', language: 'Bahasa', diff --git a/web/src/locales/ja.ts b/web/src/locales/ja.ts index cad44a46f44..104d0a77927 100644 --- a/web/src/locales/ja.ts +++ b/web/src/locales/ja.ts @@ -15,7 +15,7 @@ export default { edit: '編集', upload: 'アップロード', english: '英語', - portugeseBr: 'ポルトガル語 (ブラジル)', + portugueseBr: 'ポルトガル語 (ブラジル)', chinese: '中国語(簡体字)', traditionalChinese: '中国語(繁体字)', language: '言語', diff --git a/web/src/locales/pt-br.ts b/web/src/locales/pt-br.ts index aee7a6a960f..ffb4c748722 100644 --- a/web/src/locales/pt-br.ts +++ b/web/src/locales/pt-br.ts @@ -15,7 +15,7 @@ export default { edit: 'Editar', upload: 'Carregar', english: 'Inglês', - portugeseBr: 'Português (Brasil)', + portugueseBr: 'Português (Brasil)', chinese: 'Chinês Simplificado', traditionalChinese: 'Chinês Tradicional', language: 'Idioma', @@ -36,7 +36,7 @@ export default { submit: 'Enviar', embedIntoSite: 'Incorporar no site', previousPage: 'Anterior', - nextPage: 'Próxima' + nextPage: 'Próxima', }, login: { login: 'Entrar', @@ -55,8 +55,9 @@ export default { register: 'Criar uma conta', continue: 'Continuar', title: 'Comece a construir seus assistentes inteligentes.', - description: 'Inscreva-se gratuitamente para explorar a tecnologia RAG de ponta. Crie bases de conhecimento e IAs para capacitar seu negócio.', - review: 'de 500+ avaliações' + description: + 'Inscreva-se gratuitamente para explorar a tecnologia RAG de ponta. Crie bases de conhecimento e IAs para capacitar seu negócio.', + review: 'de 500+ avaliações', }, header: { knowledgeBase: 'Base de Conhecimento', @@ -68,7 +69,7 @@ export default { logout: 'Sair', fileManager: 'Gerenciamento de Arquivos', flow: 'Agente', - search: 'Buscar' + search: 'Buscar', }, knowledgeList: { welcome: 'Bem-vindo de volta', @@ -78,7 +79,7 @@ export default { namePlaceholder: 'Por favor, insira o nome!', doc: 'Documentos', searchKnowledgePlaceholder: 'Buscar', - noMoreData: 'Isso é tudo. Nada mais.' + noMoreData: 'Isso é tudo. Nada mais.', }, knowledgeDetail: { dataset: 'Conjunto de dados', @@ -88,7 +89,8 @@ export default { name: 'Nome', namePlaceholder: 'Por favor, insira o nome!', doc: 'Documentos', - datasetDescription: '😉 Por favor, aguarde o término da análise do seu arquivo antes de iniciar um chat com IA.', + datasetDescription: + '😉 Por favor, aguarde o término da análise do seu arquivo antes de iniciar um chat com IA.', addFile: 'Adicionar arquivo', searchFiles: 'Buscar seus arquivos', localFiles: 'Arquivos locais', @@ -104,11 +106,14 @@ export default { processBeginAt: 'Início em', processDuration: 'Duração', progressMsg: 'Progresso', - testingDescription: 'Realize um teste de recuperação para verificar se o RAGFlow pode recuperar o conteúdo pretendido para o LLM.', + testingDescription: + 'Realize um teste de recuperação para verificar se o RAGFlow pode recuperar o conteúdo pretendido para o LLM.', similarityThreshold: 'Limite de similaridade', - similarityThresholdTip: 'O RAGFlow emprega uma combinação de similaridade de palavras-chave ponderada e similaridade de cosseno vetorial ponderada, ou uma combinação de similaridade de palavras-chave ponderada e pontuação de reranking ponderada durante a recuperação. Este parâmetro define o limite para similaridades entre a consulta do usuário e os fragmentos. Qualquer fragmento com uma pontuação de similaridade abaixo deste limite será excluído dos resultados.', + similarityThresholdTip: + 'O RAGFlow emprega uma combinação de similaridade de palavras-chave ponderada e similaridade de cosseno vetorial ponderada, ou uma combinação de similaridade de palavras-chave ponderada e pontuação de reranking ponderada durante a recuperação. Este parâmetro define o limite para similaridades entre a consulta do usuário e os fragmentos. Qualquer fragmento com uma pontuação de similaridade abaixo deste limite será excluído dos resultados.', vectorSimilarityWeight: 'Peso da similaridade de palavras-chave', - vectorSimilarityWeightTip: 'Define o peso da similaridade de palavras-chave na pontuação de similaridade combinada, usada com a similaridade de cosseno vetorial ou com a pontuação de reranking. O total dos dois pesos deve ser igual a 1.0.', + vectorSimilarityWeightTip: + 'Define o peso da similaridade de palavras-chave na pontuação de similaridade combinada, usada com a similaridade de cosseno vetorial ou com a pontuação de reranking. O total dos dois pesos deve ser igual a 1.0.', testText: 'Texto de teste', testTextPlaceholder: 'Insira sua pergunta aqui!', testingLabel: 'Testando', @@ -126,37 +131,46 @@ export default { runningStatus3: 'Sucesso', runningStatus4: 'Falha', pageRanges: 'Intervalos de páginas', - pageRangesTip: 'Intervalo de páginas a serem analisadas; páginas fora deste intervalo não serão processadas.', + pageRangesTip: + 'Intervalo de páginas a serem analisadas; páginas fora deste intervalo não serão processadas.', fromPlaceholder: 'de', fromMessage: 'Página inicial ausente', toPlaceholder: 'até', toMessage: 'Página final ausente (excluída)', layoutRecognize: 'Reconhecimento de layout', - layoutRecognizeTip: 'Use modelos visuais para análise de layout para entender melhor a estrutura do documento e localizar efetivamente títulos, blocos de texto, imagens e tabelas. Se desativado, apenas o texto simples no PDF será recuperado.', + layoutRecognizeTip: + 'Use modelos visuais para análise de layout para entender melhor a estrutura do documento e localizar efetivamente títulos, blocos de texto, imagens e tabelas. Se desativado, apenas o texto simples no PDF será recuperado.', taskPageSize: 'Tamanho da página da tarefa', taskPageSizeMessage: 'Por favor, insira o tamanho da página da tarefa!', - taskPageSizeTip: 'Durante o reconhecimento de layout, um arquivo PDF é dividido em fragmentos e processado em paralelo para aumentar a velocidade de processamento. Este parâmetro define o tamanho de cada fragmento. Um tamanho de fragmento maior reduz a probabilidade de dividir texto contínuo entre páginas.', + taskPageSizeTip: + 'Durante o reconhecimento de layout, um arquivo PDF é dividido em fragmentos e processado em paralelo para aumentar a velocidade de processamento. Este parâmetro define o tamanho de cada fragmento. Um tamanho de fragmento maior reduz a probabilidade de dividir texto contínuo entre páginas.', addPage: 'Adicionar página', greaterThan: 'O valor atual deve ser maior que!', greaterThanPrevious: 'O valor atual deve ser maior que o anterior!', selectFiles: 'Selecionar arquivos', changeSpecificCategory: 'Alterar categoria específica', - uploadTitle: 'Clique ou arraste o arquivo para esta área para fazer o upload', - uploadDescription: 'Suporte para upload único ou em massa. Estritamente proibido fazer upload de dados da empresa ou outros arquivos proibidos.', + uploadTitle: + 'Clique ou arraste o arquivo para esta área para fazer o upload', + uploadDescription: + 'Suporte para upload único ou em massa. Estritamente proibido fazer upload de dados da empresa ou outros arquivos proibidos.', chunk: 'Fragmento', bulk: 'Em massa', cancel: 'Cancelar', rerankModel: 'Modelo de reranking', rerankPlaceholder: 'Por favor, selecione', - rerankTip: 'Se deixado vazio, o RAGFlow usará uma combinação de similaridade de palavras-chave ponderada e similaridade de cosseno vetorial ponderada; se um modelo de reranking for selecionado, uma pontuação de reranking ponderada substituirá a similaridade de cosseno vetorial ponderada. Esteja ciente de que usar um modelo de reranking aumentará significativamente o tempo de resposta do sistema.', + rerankTip: + 'Se deixado vazio, o RAGFlow usará uma combinação de similaridade de palavras-chave ponderada e similaridade de cosseno vetorial ponderada; se um modelo de reranking for selecionado, uma pontuação de reranking ponderada substituirá a similaridade de cosseno vetorial ponderada. Esteja ciente de que usar um modelo de reranking aumentará significativamente o tempo de resposta do sistema.', topK: 'Top-K', topKTip: 'K fragmentos serão alimentados em modelos de reranking.', delimiter: 'Delimitador', - delimiterTip: 'Um delimitador ou separador pode consistir em um ou vários caracteres especiais. Se for múltiplos caracteres, certifique-se de que estejam entre crases (``). Por exemplo, se você configurar seus delimitadores assim: \n`##`;, seus textos serão separados em quebras de linha, símbolos de hash duplo (##) ou ponto e vírgula.', + delimiterTip: + 'Um delimitador ou separador pode consistir em um ou vários caracteres especiais. Se for múltiplos caracteres, certifique-se de que estejam entre crases (``). Por exemplo, se você configurar seus delimitadores assim: \n`##`;, seus textos serão separados em quebras de linha, símbolos de hash duplo (##) ou ponto e vírgula.', html4excel: 'Excel para HTML', - html4excelTip: 'Quando ativado, a planilha será analisada em tabelas HTML, com no máximo 256 linhas por tabela. Caso contrário, será analisada em pares chave-valor por linha.', + html4excelTip: + 'Quando ativado, a planilha será analisada em tabelas HTML, com no máximo 256 linhas por tabela. Caso contrário, será analisada em pares chave-valor por linha.', autoKeywords: 'Palavras-chave automáticas', - autoKeywordsTip: 'Extraia automaticamente N palavras-chave para cada fragmento para aumentar sua classificação para consultas que contenham essas palavras-chave. Você pode verificar ou atualizar as palavras-chave adicionadas para um fragmento na lista de fragmentos. Esteja ciente de que tokens extras serão consumidos pelo LLM especificado nas "Configurações do modelo do sistema".', + autoKeywordsTip: + 'Extraia automaticamente N palavras-chave para cada fragmento para aumentar sua classificação para consultas que contenham essas palavras-chave. Você pode verificar ou atualizar as palavras-chave adicionadas para um fragmento na lista de fragmentos. Esteja ciente de que tokens extras serão consumidos pelo LLM especificado nas "Configurações do modelo do sistema".', autoQuestions: 'Perguntas automáticas', autoQuestionsTip: `Extraia automaticamente N perguntas para cada fragmento para aumentar sua relevância em consultas que contenham essas perguntas. Você pode verificar ou atualizar as perguntas adicionadas a um fragmento na lista de fragmentos. Essa funcionalidade não interromperá o processo de fragmentação em caso de erro, exceto pelo fato de que pode adicionar um resultado vazio ao fragmento original. Esteja ciente de que tokens extras serão consumidos pelo LLM especificado nas 'Configurações do modelo do sistema'.`, redo: 'Deseja limpar os {{chunkNum}} fragmentos existentes?', @@ -207,7 +221,8 @@ export default { upload: 'Enviar', english: 'Inglês', chinese: 'Chinês', - embeddingModelPlaceholder: 'Por favor, selecione um modelo de incorporação', + embeddingModelPlaceholder: + 'Por favor, selecione um modelo de incorporação', chunkMethodPlaceholder: 'Por favor, selecione um método de fragmentação', save: 'Salvar', me: 'Somente eu', @@ -376,7 +391,8 @@ export default { maxTokens: 'Máximo de tokens', maxTokensMessage: 'O máximo de tokens é obrigatório', maxTokensTip: `Define o comprimento máximo da saída do modelo, medido pelo número de tokens (palavras ou partes de palavras). O padrão é 512. Se desativado, você remove o limite máximo de tokens, permitindo que o modelo determine o número de tokens em suas respostas.`, - maxTokensInvalidMessage: 'Por favor, insira um número válido para o máximo de tokens.', + maxTokensInvalidMessage: + 'Por favor, insira um número válido para o máximo de tokens.', maxTokensMinMessage: 'O máximo de tokens não pode ser menor que 0.', quote: 'Mostrar citação', quoteTip: 'Exibir ou não o texto original como referência.', @@ -432,7 +448,8 @@ export default { maxTokens: 'Máximo de Tokens', maxTokensMessage: 'Máximo de Tokens é obrigatório', maxTokensTip: `Isso define o comprimento máximo da saída do modelo, medido em número de tokens (palavras ou partes de palavras). O padrão é 512. Se desativado, você remove o limite máximo de tokens, permitindo que o modelo determine o número de tokens em suas respostas.`, - maxTokensInvalidMessage: 'Por favor, insira um número válido para Máximo de Tokens.', + maxTokensInvalidMessage: + 'Por favor, insira um número válido para Máximo de Tokens.', maxTokensMinMessage: 'O Máximo de Tokens não pode ser menor que 0.', password: 'Senha', passwordDescription: 'Digite sua senha atual para alterá-la.', @@ -463,31 +480,41 @@ export default { newPasswordDescription: 'Sua nova senha deve ter mais de 8 caracteres.', confirmPassword: 'Confirmar nova senha', confirmPasswordMessage: 'Por favor, confirme sua senha!', - confirmPasswordNonMatchMessage: 'A nova senha que você inseriu não corresponde!', + confirmPasswordNonMatchMessage: + 'A nova senha que você inseriu não corresponde!', cancel: 'Cancelar', addedModels: 'Modelos adicionados', modelsToBeAdded: 'Modelos a serem adicionados', addTheModel: 'Adicionar o modelo', apiKey: 'Chave da API', - apiKeyMessage: 'Por favor, insira a chave da API (para modelos implantados localmente, ignore isso).', - apiKeyTip: 'A chave da API pode ser obtida registrando-se no fornecedor correspondente do LLM.', + apiKeyMessage: + 'Por favor, insira a chave da API (para modelos implantados localmente, ignore isso).', + apiKeyTip: + 'A chave da API pode ser obtida registrando-se no fornecedor correspondente do LLM.', showMoreModels: 'Mostrar mais modelos', baseUrl: 'URL Base', - baseUrlTip: 'Se sua chave da API for do OpenAI, ignore isso. Outros provedores intermediários fornecerão essa URL base com a chave da API.', + baseUrlTip: + 'Se sua chave da API for do OpenAI, ignore isso. Outros provedores intermediários fornecerão essa URL base com a chave da API.', modify: 'Modificar', systemModelSettings: 'Configurações do Modelo do Sistema', chatModel: 'Modelo de chat', - chatModelTip: 'O modelo LLM padrão que todos os novos bancos de conhecimento usarão.', + chatModelTip: + 'O modelo LLM padrão que todos os novos bancos de conhecimento usarão.', embeddingModel: 'Modelo de incorporação', - embeddingModelTip: 'O modelo de incorporação padrão que todos os novos bancos de conhecimento usarão.', + embeddingModelTip: + 'O modelo de incorporação padrão que todos os novos bancos de conhecimento usarão.', img2txtModel: 'Modelo Img2Txt', - img2txtModelTip: 'O modelo multimodal padrão que todos os novos bancos de conhecimento usarão. Ele pode descrever uma imagem ou vídeo.', + img2txtModelTip: + 'O modelo multimodal padrão que todos os novos bancos de conhecimento usarão. Ele pode descrever uma imagem ou vídeo.', sequence2txtModel: 'Modelo Sequence2Txt', - sequence2txtModelTip: 'O modelo ASR padrão que todos os novos bancos de conhecimento usarão. Use este modelo para converter vozes em texto correspondente.', + sequence2txtModelTip: + 'O modelo ASR padrão que todos os novos bancos de conhecimento usarão. Use este modelo para converter vozes em texto correspondente.', rerankModel: 'Modelo de Reordenação', - rerankModelTip: 'O modelo de reordenação padrão usado para reordenar os fragmentos recuperados pelas perguntas dos usuários.', + rerankModelTip: + 'O modelo de reordenação padrão usado para reordenar os fragmentos recuperados pelas perguntas dos usuários.', ttsModel: 'Modelo TTS', - ttsModelTip: 'O modelo TTS padrão será usado para gerar fala durante as conversas sob demanda.', + ttsModelTip: + 'O modelo TTS padrão será usado para gerar fala durante as conversas sob demanda.', workspace: 'Área de trabalho', upgrade: 'Atualizar', addLlmTitle: 'Adicionar LLM', @@ -544,11 +571,13 @@ export default { yiyanAKMessage: 'Por favor, insira sua chave da API', addyiyanSK: 'Chave secreta yiyan', yiyanSKMessage: 'Por favor, insira sua chave secreta', - FishAudioModelNameMessage: 'Por favor, dê um nome ao seu modelo de síntese de voz', + FishAudioModelNameMessage: + 'Por favor, dê um nome ao seu modelo de síntese de voz', addFishAudioAK: 'Chave da API Fish Audio', addFishAudioAKMessage: 'Por favor, insira sua chave da API', addFishAudioRefID: 'ID de referência do FishAudio', - addFishAudioRefIDMessage: 'Por favor, insira o ID de referência (deixe em branco para usar o modelo padrão).', + addFishAudioRefIDMessage: + 'Por favor, insira o ID de referência (deixe em branco para usar o modelo padrão).', modelProvidersWarn: `Por favor, adicione tanto o modelo de incorporação quanto o LLM em Configurações > Provedores de Modelo primeiro. Depois, defina-os nas 'Configurações do modelo do sistema'.`, apiVersion: 'Versão da API', apiVersionMessage: 'Por favor, insira a versão da API', @@ -610,7 +639,8 @@ export default { file: 'Arquivo', uploadFile: 'Carregar Arquivo', directory: 'Diretório', - uploadTitle: 'Clique ou arraste o arquivo para esta área para fazer o upload', + uploadTitle: + 'Clique ou arraste o arquivo para esta área para fazer o upload', uploadDescription: 'Suporta upload de um único arquivo ou múltiplos arquivos. É estritamente proibido o upload de dados da empresa ou outros arquivos proibidos.', local: 'Uploads locais', @@ -785,17 +815,17 @@ export default { cht: 'Chinês tradicional', vie: 'Vietnamita', }, - + qWeather: 'QWeather', qWeatherDescription: 'Um componente que recupera informações meteorológicas, como temperatura e qualidade do ar, de https://www.qweather.com.', - + lang: 'Idioma', type: 'Tipo', webApiKey: 'Chave de API da Web', userType: 'Tipo de usuário', timePeriod: 'Período de tempo', - + qWeatherLangOptions: { zh: 'Chinês simplificado', 'zh-hant': 'Chinês tradicional', @@ -829,7 +859,7 @@ export default { is: 'Islandês', nb: 'Norueguês', }, - + qWeatherTypeOptions: { weather: 'Previsão do tempo', indices: 'Índice de qualidade de vida relacionado ao clima', @@ -839,7 +869,7 @@ export default { free: 'Assinante gratuito', paid: 'Assinante pago', }, - + qWeatherTimePeriodOptions: { now: 'Agora', '3d': '3 dias', @@ -848,12 +878,12 @@ export default { '15d': '12 dias', '30d': '30 dias', }, - + publish: 'API', exeSQL: 'ExeSQL', exeSQLDescription: 'Um componente que executa consultas SQL em um banco de dados relacional, suportando consultas de MySQL, PostgreSQL ou MariaDB.', - + dbType: 'Tipo de banco de dados', database: 'Banco de dados', username: 'Nome de usuário', @@ -876,12 +906,12 @@ export default { empty: 'Vazio', notEmpty: 'Não vazio', }, - + switchLogicOperatorOptions: { and: 'E', or: 'Ou', }, - + operator: 'Operador', value: 'Valor', useTemplate: 'Usar este modelo', @@ -889,7 +919,7 @@ export default { queryType: 'Tipo de consulta', wenCaiDescription: 'Um componente que obtém informações financeiras, incluindo preços de ações e notícias de financiamento, de uma ampla variedade de sites financeiros.', - + wenCaiQueryTypeOptions: { stock: 'Ação', zhishu: 'Índice', @@ -903,26 +933,26 @@ export default { lccp: 'Financiamento', foreign_exchange: 'Câmbio', }, - + akShare: 'AkShare', akShareDescription: 'Um componente que obtém notícias sobre ações de https://www.eastmoney.com/.', - + yahooFinance: 'YahooFinance', yahooFinanceDescription: 'Um componente que consulta informações sobre uma empresa de capital aberto usando seu símbolo de ticker.', - + crawler: 'Rastreador Web', crawlerDescription: 'Um componente que rastreia o código-fonte HTML de um URL especificado.', - + proxy: 'Proxy', crawlerResultOptions: { html: 'Html', markdown: 'Markdown', content: 'Conteúdo', }, - + extractType: 'Tipo de extração', info: 'Informações', history: 'Histórico', @@ -932,7 +962,7 @@ export default { jin10: 'Jin10', jin10Description: 'Um componente que obtém informações financeiras da Plataforma Aberta Jin10, incluindo notícias, calendários, cotações e referências.', - + flashType: 'Tipo de Flash', filter: 'Filtro', contain: 'Contém', @@ -946,7 +976,7 @@ export default { symbols: 'Cotações', news: 'Referência', }, - + jin10FlashTypeOptions: { '1': 'Notícias do Mercado', '2': 'Notícias de Futuros', @@ -954,27 +984,27 @@ export default { '4': 'Notícias A-Share', '5': 'Notícias de Commodities & Forex', }, - + jin10CalendarTypeOptions: { cj: 'Calendário de dados macroeconômicos', qh: 'Calendário de Futuros', hk: 'Calendário do mercado de ações de Hong Kong', us: 'Calendário do mercado de ações dos EUA', }, - + jin10CalendarDatashapeOptions: { data: 'Dados', event: 'Evento', holiday: 'Feriado', }, - + jin10SymbolsTypeOptions: { GOODS: 'Cotações de commodities', FOREX: 'Cotações de Forex', FUTURE: 'Cotações do mercado internacional', CRYPTO: 'Cotações de criptomoedas', }, - + jin10SymbolsDatatypeOptions: { symbols: 'Lista de commodities', quotes: 'Últimas cotações do mercado', @@ -1096,4 +1126,3 @@ export default { }, }, }; - diff --git a/web/src/locales/zh-traditional.ts b/web/src/locales/zh-traditional.ts index 0e983f4045b..e90dec1210d 100644 --- a/web/src/locales/zh-traditional.ts +++ b/web/src/locales/zh-traditional.ts @@ -15,7 +15,7 @@ export default { edit: '編輯', upload: '上傳', english: '英語', - portugeseBr: '葡萄牙語 (巴西)', + portugueseBr: '葡萄牙語 (巴西)', chinese: '簡體中文', traditionalChinese: '繁體中文', language: '語言', diff --git a/web/src/locales/zh.ts b/web/src/locales/zh.ts index 837d9a5b42f..28e572bb713 100644 --- a/web/src/locales/zh.ts +++ b/web/src/locales/zh.ts @@ -15,7 +15,7 @@ export default { edit: '编辑', upload: '上传', english: '英文', - portugeseBr: '葡萄牙语 (巴西)', + portugueseBr: '葡萄牙语 (巴西)', chinese: '简体中文', traditionalChinese: '繁体中文', language: '语言', From a2946b0fb02779f4e8c950b9fca37d5de2e143e5 Mon Sep 17 00:00:00 2001 From: writinwaters <93570324+writinwaters@users.noreply.github.com> Date: Tue, 21 Jan 2025 19:51:30 +0800 Subject: [PATCH 7/9] Added descriptions of the Note and Template components (#4560) ### What problem does this PR solve? ### Type of change - [x] Documentation Update --- .../agent_component_reference/generate.mdx | 4 +- .../agent_component_reference/note.mdx | 22 +++++++++ .../agent_component_reference/template.mdx | 49 +++++++++++++++++++ web/src/locales/en.ts | 2 +- 4 files changed, 74 insertions(+), 3 deletions(-) create mode 100644 docs/references/agent_component_reference/note.mdx create mode 100644 docs/references/agent_component_reference/template.mdx diff --git a/docs/references/agent_component_reference/generate.mdx b/docs/references/agent_component_reference/generate.mdx index 9bfe771d30e..6572bc35a1d 100644 --- a/docs/references/agent_component_reference/generate.mdx +++ b/docs/references/agent_component_reference/generate.mdx @@ -9,7 +9,7 @@ The component that prompts the LLM to respond appropriately. --- -The **Generate** component fine-tunes the LLM and sets its prompt. +A **Generate** component fine-tunes the LLM and sets its prompt. ## Scenarios @@ -98,7 +98,7 @@ This feature is used for multi-turn dialogue *only*. ### Key (Variable) :::danger IMPORTANT -A **Generate** component relies on variables (keys) to specify its data inputs. Its immediate upstream component is *not* necessarily its data input, and the arrows in the workflow indicate *only* the processing sequence. +A **Generate** component relies on keys (variables) to specify its data inputs. Its immediate upstream component is *not* necessarily its data input, and the arrows in the workflow indicate *only* the processing sequence. ::: ![variable_settings](https://github.com/user-attachments/assets/cb024c9e-264a-43ff-9ee7-8649afd571b0) diff --git a/docs/references/agent_component_reference/note.mdx b/docs/references/agent_component_reference/note.mdx new file mode 100644 index 00000000000..0eadefa528b --- /dev/null +++ b/docs/references/agent_component_reference/note.mdx @@ -0,0 +1,22 @@ +--- +sidebar_position: 13 +slug: /note_component +--- + +# Interact component + +The component that keeps design notes. + +--- + +A **note** component allows you to keep design notes, including details about an agent, the output of specific components, the rationale of a particular design, or any information that may assist you, your users, or your fellow developers understand the agent. + +## Examples + +Explore our customer service agent template, which has five **Note** components: + +1. Click the **Agent** tab at the top center of the page to access the **Agent** page. +2. Click **+ Create agent** on the top right of the page to open the **agent template** page. +3. On the **agent template** page, hover over the **Customer service** card and click **Use this template**. +4. Name your new agent and click **OK** to enter the workflow editor. +5. Click on the **note** component to add or update notes. \ No newline at end of file diff --git a/docs/references/agent_component_reference/template.mdx b/docs/references/agent_component_reference/template.mdx new file mode 100644 index 00000000000..fee44821b80 --- /dev/null +++ b/docs/references/agent_component_reference/template.mdx @@ -0,0 +1,49 @@ +--- +sidebar_position: 11 +slug: /template_component +--- + +# Template component + +The component that formats user inputs or the outputs of other components. + +--- + +A **Template** component acts as a content formatter. It is usually the upstream component of an **Interact** component. + + +## Scenarios + +A **Template** component is useful for organizing various sources of data or information into specific formats. + +## Configurations + +### Content + +Used together with Keys to organize various data or information sources into desired formats. Example: + +```text +

    {subtitle}

    +
    {content}
    +``` + +Where `{subtitle}` and `{content}` are defined keys. + +### Key + +A **Template** component relies on keys (variables) to specify its data or information sources. Its immediate upstream component is *not* necessarily its input, and the arrows in the workflow indicate *only* the processing sequence. + +Values of keys are categorized into two groups: + +- **Component Output**: The value of the key should be a component ID. +- **Begin Input**: The value of the key should be the name of a global variable defined in the **Begin** component. + +## Examples + +Explore our research report generator agent template, where the **Template** component (component ID: **Article**) organizes user input and the outputs of the **Sections** component into HTML format: + +1. Click the **Agent** tab at the top center of the page to access the **Agent** page. +2. Click **+ Create agent** on the top right of the page to open the **agent template** page. +3. On the **agent template** page, hover over the **Research report generator** card and click **Use this template**. +4. Name your new agent and click **OK** to enter the workflow editor. +5. Click on the **Template** component to display its **Configuration** window diff --git a/web/src/locales/en.ts b/web/src/locales/en.ts index bfcd21223eb..98e06abce9e 100644 --- a/web/src/locales/en.ts +++ b/web/src/locales/en.ts @@ -1104,7 +1104,7 @@ This procedure will improve precision of retrieval by adding more information to testRun: 'Test Run', template: 'Template', templateDescription: - 'A component that formats the output of other components.', + 'A component that formats user inputs or the outputs of other components.', emailComponent: 'Email', emailDescription: 'Send an email to a specified address.', smtpServer: 'SMTP Server', From 583050a876824fd6dd39761557fce2a87abf4afe Mon Sep 17 00:00:00 2001 From: writinwaters <93570324+writinwaters@users.noreply.github.com> Date: Tue, 21 Jan 2025 20:02:04 +0800 Subject: [PATCH 8/9] minor (#4568) ### What problem does this PR solve? ### Type of change - [x] Documentation Update --- docs/references/agent_component_reference/note.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/references/agent_component_reference/note.mdx b/docs/references/agent_component_reference/note.mdx index 0eadefa528b..445648a36ac 100644 --- a/docs/references/agent_component_reference/note.mdx +++ b/docs/references/agent_component_reference/note.mdx @@ -3,7 +3,7 @@ sidebar_position: 13 slug: /note_component --- -# Interact component +# Note component The component that keeps design notes. From 3894de895b8c9e9435503094ee6b6cc2e55eb4d3 Mon Sep 17 00:00:00 2001 From: Jin Hai Date: Tue, 21 Jan 2025 20:52:28 +0800 Subject: [PATCH 9/9] Update comments (#4569) ### What problem does this PR solve? Add license statement. ### Type of change - [x] Refactoring Signed-off-by: Jin Hai --- agent/__init__.py | 16 +++ agent/component/__init__.py | 16 +++ agent/settings.py | 2 +- api/__init__.py | 16 +++ api/utils/t_crypt.py | 16 +++ api/utils/web_utils.py | 16 +++ deepdoc/__init__.py | 16 +++ deepdoc/parser/__init__.py | 3 + deepdoc/parser/docx_parser.py | 3 + deepdoc/parser/excel_parser.py | 3 + deepdoc/parser/html_parser.py | 4 + deepdoc/parser/json_parser.py | 16 +++ deepdoc/parser/markdown_parser.py | 4 + deepdoc/parser/pdf_parser.py | 3 + deepdoc/parser/ppt_parser.py | 4 + deepdoc/parser/resume/__init__.py | 3 + deepdoc/parser/resume/entities/__init__.py | 15 +++ .../parser/resume/entities/corporations.py | 3 + deepdoc/parser/resume/entities/degrees.py | 3 + deepdoc/parser/resume/entities/industries.py | 3 + deepdoc/parser/resume/entities/regions.py | 4 + deepdoc/parser/resume/entities/schools.py | 3 + deepdoc/parser/resume/step_one.py | 3 + deepdoc/parser/resume/step_two.py | 4 + deepdoc/parser/txt_parser.py | 4 + deepdoc/parser/utils.py | 3 + deepdoc/vision/__init__.py | 3 + deepdoc/vision/layout_recognizer.py | 4 + deepdoc/vision/ocr.py | 3 + deepdoc/vision/postprocess.py | 3 + deepdoc/vision/recognizer.py | 3 + deepdoc/vision/seeit.py | 3 + deepdoc/vision/t_ocr.py | 3 + deepdoc/vision/t_recognizer.py | 4 + deepdoc/vision/table_structure_recognizer.py | 3 + .../chatgpt-on-wechat/plugins/__init__.py | 16 +++ .../chatgpt-on-wechat/plugins/ragflow_chat.py | 16 +++ rag/__init__.py | 16 +++ rag/app/__init__.py | 15 +++ rag/app/audio.py | 4 + rag/app/book.py | 4 + rag/app/email.py | 3 + rag/app/knowledge_graph.py | 16 +++ rag/app/laws.py | 4 + rag/app/manual.py | 2 +- rag/app/naive.py | 4 + rag/app/one.py | 4 + rag/app/paper.py | 4 + rag/app/picture.py | 4 + rag/app/presentation.py | 4 + rag/app/qa.py | 4 + rag/app/resume.py | 4 + rag/app/table.py | 4 + rag/app/tag.py | 4 + rag/svr/jina_server.py | 16 +++ rag/utils/azure_sas_conn.py | 16 +++ rag/utils/azure_spn_conn.py | 16 +++ rag/utils/doc_store_conn.py | 16 +++ rag/utils/es_conn.py | 16 +++ rag/utils/infinity_conn.py | 16 +++ rag/utils/minio_conn.py | 16 +++ rag/utils/redis_conn.py | 16 +++ rag/utils/s3_conn.py | 16 +++ rag/utils/storage_factory.py | 16 +++ sdk/python/hello_ragflow.py | 18 ++- sdk/python/ragflow_sdk/__init__.py | 16 +++ sdk/python/ragflow_sdk/modules/__init__.py | 15 +++ sdk/python/ragflow_sdk/modules/agent.py | 16 +++ sdk/python/ragflow_sdk/modules/base.py | 16 +++ sdk/python/ragflow_sdk/modules/chat.py | 26 +++- sdk/python/ragflow_sdk/modules/chunk.py | 25 +++- sdk/python/ragflow_sdk/modules/dataset.py | 49 +++++--- sdk/python/ragflow_sdk/modules/document.py | 38 ++++-- sdk/python/ragflow_sdk/modules/session.py | 39 ++++-- sdk/python/test/conftest.py | 38 ++++-- sdk/python/test/test_frontend_api/common.py | 16 +++ .../test/test_frontend_api/get_email.py | 16 +++ .../test/test_frontend_api/test_dataset.py | 20 ++- sdk/python/test/test_sdk_api/common.py | 19 ++- sdk/python/test/test_sdk_api/get_email.py | 20 ++- sdk/python/test/test_sdk_api/t_agent.py | 27 ++++- sdk/python/test/test_sdk_api/t_chat.py | 24 +++- sdk/python/test/test_sdk_api/t_chunk.py | 44 +++++-- sdk/python/test/test_sdk_api/t_dataset.py | 27 ++++- sdk/python/test/test_sdk_api/t_document.py | 114 +++++++++++------- sdk/python/test/test_sdk_api/t_session.py | 49 +++++--- 86 files changed, 1034 insertions(+), 145 deletions(-) diff --git a/agent/__init__.py b/agent/__init__.py index 6bfdd33d0ba..643f79713c8 100644 --- a/agent/__init__.py +++ b/agent/__init__.py @@ -1,2 +1,18 @@ +# +# Copyright 2025 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 beartype.claw import beartype_this_package beartype_this_package() diff --git a/agent/component/__init__.py b/agent/component/__init__.py index 0d414fca997..da06c878c04 100644 --- a/agent/component/__init__.py +++ b/agent/component/__init__.py @@ -1,3 +1,19 @@ +# +# Copyright 2025 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. +# + import importlib from .begin import Begin, BeginParam from .generate import Generate, GenerateParam diff --git a/agent/settings.py b/agent/settings.py index fbdb263dc74..932cb1d57a5 100644 --- a/agent/settings.py +++ b/agent/settings.py @@ -1,5 +1,5 @@ # -# Copyright 2019 The FATE Authors. All Rights Reserved. +# Copyright 2025 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. diff --git a/api/__init__.py b/api/__init__.py index 6bfdd33d0ba..643f79713c8 100644 --- a/api/__init__.py +++ b/api/__init__.py @@ -1,2 +1,18 @@ +# +# Copyright 2025 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 beartype.claw import beartype_this_package beartype_this_package() diff --git a/api/utils/t_crypt.py b/api/utils/t_crypt.py index 67fd69c627a..cd9d1edcc9f 100644 --- a/api/utils/t_crypt.py +++ b/api/utils/t_crypt.py @@ -1,3 +1,19 @@ +# +# Copyright 2025 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. +# + import base64 import os import sys diff --git a/api/utils/web_utils.py b/api/utils/web_utils.py index 687d683acbe..084b7a6f73f 100644 --- a/api/utils/web_utils.py +++ b/api/utils/web_utils.py @@ -1,3 +1,19 @@ +# +# Copyright 2025 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. +# + import re import socket from urllib.parse import urlparse diff --git a/deepdoc/__init__.py b/deepdoc/__init__.py index 6bfdd33d0ba..643f79713c8 100644 --- a/deepdoc/__init__.py +++ b/deepdoc/__init__.py @@ -1,2 +1,18 @@ +# +# Copyright 2025 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 beartype.claw import beartype_this_package beartype_this_package() diff --git a/deepdoc/parser/__init__.py b/deepdoc/parser/__init__.py index 2a62a989468..1597ed08169 100644 --- a/deepdoc/parser/__init__.py +++ b/deepdoc/parser/__init__.py @@ -1,3 +1,6 @@ +# +# Copyright 2025 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 diff --git a/deepdoc/parser/docx_parser.py b/deepdoc/parser/docx_parser.py index 1910f4380c4..dfe3f37fd16 100644 --- a/deepdoc/parser/docx_parser.py +++ b/deepdoc/parser/docx_parser.py @@ -1,3 +1,6 @@ +# +# Copyright 2025 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 diff --git a/deepdoc/parser/excel_parser.py b/deepdoc/parser/excel_parser.py index 77cc7a058a3..bb9d65b00fc 100644 --- a/deepdoc/parser/excel_parser.py +++ b/deepdoc/parser/excel_parser.py @@ -1,3 +1,6 @@ +# +# Copyright 2025 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 diff --git a/deepdoc/parser/html_parser.py b/deepdoc/parser/html_parser.py index 973dbbd4644..29cc43a1d44 100644 --- a/deepdoc/parser/html_parser.py +++ b/deepdoc/parser/html_parser.py @@ -1,4 +1,7 @@ # -*- coding: utf-8 -*- +# +# Copyright 2025 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 @@ -11,6 +14,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # + from rag.nlp import find_codec import readability import html_text diff --git a/deepdoc/parser/json_parser.py b/deepdoc/parser/json_parser.py index fa30debdfe1..dc73246ef7e 100644 --- a/deepdoc/parser/json_parser.py +++ b/deepdoc/parser/json_parser.py @@ -1,4 +1,20 @@ # -*- coding: utf-8 -*- +# +# Copyright 2025 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. +# + # The following documents are mainly referenced, and only adaptation modifications have been made # from https://github.com/langchain-ai/langchain/blob/master/libs/text-splitters/langchain_text_splitters/json.py diff --git a/deepdoc/parser/markdown_parser.py b/deepdoc/parser/markdown_parser.py index 60e6ba49834..d5d13837706 100644 --- a/deepdoc/parser/markdown_parser.py +++ b/deepdoc/parser/markdown_parser.py @@ -1,4 +1,7 @@ # -*- coding: utf-8 -*- +# +# Copyright 2025 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 @@ -11,6 +14,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # + import re class RAGFlowMarkdownParser: diff --git a/deepdoc/parser/pdf_parser.py b/deepdoc/parser/pdf_parser.py index 5ff216edfa7..114339fa58c 100644 --- a/deepdoc/parser/pdf_parser.py +++ b/deepdoc/parser/pdf_parser.py @@ -1,3 +1,6 @@ +# +# Copyright 2025 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 diff --git a/deepdoc/parser/ppt_parser.py b/deepdoc/parser/ppt_parser.py index eca952badc9..4e459d19333 100644 --- a/deepdoc/parser/ppt_parser.py +++ b/deepdoc/parser/ppt_parser.py @@ -1,3 +1,6 @@ +# +# Copyright 2025 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 @@ -10,6 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # + import logging from io import BytesIO from pptx import Presentation diff --git a/deepdoc/parser/resume/__init__.py b/deepdoc/parser/resume/__init__.py index 1038bf2b7b1..5006d7fbcc5 100644 --- a/deepdoc/parser/resume/__init__.py +++ b/deepdoc/parser/resume/__init__.py @@ -1,3 +1,6 @@ +# +# Copyright 2025 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 diff --git a/deepdoc/parser/resume/entities/__init__.py b/deepdoc/parser/resume/entities/__init__.py index e69de29bb2d..e156bc93dde 100644 --- a/deepdoc/parser/resume/entities/__init__.py +++ b/deepdoc/parser/resume/entities/__init__.py @@ -0,0 +1,15 @@ +# +# Copyright 2025 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. +# \ No newline at end of file diff --git a/deepdoc/parser/resume/entities/corporations.py b/deepdoc/parser/resume/entities/corporations.py index faeae4061f0..a52bfa14a58 100644 --- a/deepdoc/parser/resume/entities/corporations.py +++ b/deepdoc/parser/resume/entities/corporations.py @@ -1,3 +1,6 @@ +# +# Copyright 2025 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 diff --git a/deepdoc/parser/resume/entities/degrees.py b/deepdoc/parser/resume/entities/degrees.py index 47a90b58211..ddb936e0b8f 100644 --- a/deepdoc/parser/resume/entities/degrees.py +++ b/deepdoc/parser/resume/entities/degrees.py @@ -1,3 +1,6 @@ +# +# Copyright 2025 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 diff --git a/deepdoc/parser/resume/entities/industries.py b/deepdoc/parser/resume/entities/industries.py index 4768ceb50e8..c2b1b8e8261 100644 --- a/deepdoc/parser/resume/entities/industries.py +++ b/deepdoc/parser/resume/entities/industries.py @@ -1,3 +1,6 @@ +# +# Copyright 2025 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 diff --git a/deepdoc/parser/resume/entities/regions.py b/deepdoc/parser/resume/entities/regions.py index 4c3f0d722fc..ac37f6ea1d8 100644 --- a/deepdoc/parser/resume/entities/regions.py +++ b/deepdoc/parser/resume/entities/regions.py @@ -1,3 +1,6 @@ +# +# Copyright 2025 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 @@ -10,6 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # + import re TBL = { diff --git a/deepdoc/parser/resume/entities/schools.py b/deepdoc/parser/resume/entities/schools.py index c6b0bf7fdbc..2bc40e83638 100644 --- a/deepdoc/parser/resume/entities/schools.py +++ b/deepdoc/parser/resume/entities/schools.py @@ -1,3 +1,6 @@ +# +# Copyright 2025 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 diff --git a/deepdoc/parser/resume/step_one.py b/deepdoc/parser/resume/step_one.py index 96cc668d316..4c65a97fe85 100644 --- a/deepdoc/parser/resume/step_one.py +++ b/deepdoc/parser/resume/step_one.py @@ -1,3 +1,6 @@ +# +# Copyright 2025 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 diff --git a/deepdoc/parser/resume/step_two.py b/deepdoc/parser/resume/step_two.py index 9e4376735c3..6097a0132dc 100644 --- a/deepdoc/parser/resume/step_two.py +++ b/deepdoc/parser/resume/step_two.py @@ -1,3 +1,6 @@ +# +# Copyright 2025 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 @@ -10,6 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # + import logging import re import copy diff --git a/deepdoc/parser/txt_parser.py b/deepdoc/parser/txt_parser.py index 93b52eea32d..7f21799237d 100644 --- a/deepdoc/parser/txt_parser.py +++ b/deepdoc/parser/txt_parser.py @@ -1,3 +1,6 @@ +# +# Copyright 2025 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 @@ -10,6 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # + import re from deepdoc.parser.utils import get_text diff --git a/deepdoc/parser/utils.py b/deepdoc/parser/utils.py index 58be06c915e..85a3554955b 100644 --- a/deepdoc/parser/utils.py +++ b/deepdoc/parser/utils.py @@ -1,3 +1,6 @@ +# +# Copyright 2025 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 diff --git a/deepdoc/vision/__init__.py b/deepdoc/vision/__init__.py index 1410efc2581..c2c964326ee 100644 --- a/deepdoc/vision/__init__.py +++ b/deepdoc/vision/__init__.py @@ -1,3 +1,6 @@ +# +# Copyright 2025 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 diff --git a/deepdoc/vision/layout_recognizer.py b/deepdoc/vision/layout_recognizer.py index 1cf3aa1a2c8..467a22ee9cf 100644 --- a/deepdoc/vision/layout_recognizer.py +++ b/deepdoc/vision/layout_recognizer.py @@ -1,3 +1,6 @@ +# +# Copyright 2025 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 @@ -10,6 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # + import os import re from collections import Counter diff --git a/deepdoc/vision/ocr.py b/deepdoc/vision/ocr.py index b6f81574120..9d9d44cde80 100644 --- a/deepdoc/vision/ocr.py +++ b/deepdoc/vision/ocr.py @@ -1,3 +1,6 @@ +# +# Copyright 2025 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 diff --git a/deepdoc/vision/postprocess.py b/deepdoc/vision/postprocess.py index 6fb111de3bb..2da1477b3e3 100644 --- a/deepdoc/vision/postprocess.py +++ b/deepdoc/vision/postprocess.py @@ -1,3 +1,6 @@ +# +# Copyright 2025 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 diff --git a/deepdoc/vision/recognizer.py b/deepdoc/vision/recognizer.py index 0695005c766..aeef52d5783 100644 --- a/deepdoc/vision/recognizer.py +++ b/deepdoc/vision/recognizer.py @@ -1,3 +1,6 @@ +# +# Copyright 2025 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 diff --git a/deepdoc/vision/seeit.py b/deepdoc/vision/seeit.py index 6064bc4843e..e820e89a51d 100644 --- a/deepdoc/vision/seeit.py +++ b/deepdoc/vision/seeit.py @@ -1,3 +1,6 @@ +# +# Copyright 2025 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 diff --git a/deepdoc/vision/t_ocr.py b/deepdoc/vision/t_ocr.py index 041c7710754..2165449de28 100644 --- a/deepdoc/vision/t_ocr.py +++ b/deepdoc/vision/t_ocr.py @@ -1,3 +1,6 @@ +# +# Copyright 2025 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 diff --git a/deepdoc/vision/t_recognizer.py b/deepdoc/vision/t_recognizer.py index e81a57b843b..1db3356a9d6 100644 --- a/deepdoc/vision/t_recognizer.py +++ b/deepdoc/vision/t_recognizer.py @@ -1,3 +1,6 @@ +# +# Copyright 2025 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 @@ -10,6 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # + import logging import os import sys diff --git a/deepdoc/vision/table_structure_recognizer.py b/deepdoc/vision/table_structure_recognizer.py index be48ca95e4c..e31fd901e36 100644 --- a/deepdoc/vision/table_structure_recognizer.py +++ b/deepdoc/vision/table_structure_recognizer.py @@ -1,3 +1,6 @@ +# +# Copyright 2025 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 diff --git a/intergrations/chatgpt-on-wechat/plugins/__init__.py b/intergrations/chatgpt-on-wechat/plugins/__init__.py index 28032b8b8e8..557f0d1f1ba 100644 --- a/intergrations/chatgpt-on-wechat/plugins/__init__.py +++ b/intergrations/chatgpt-on-wechat/plugins/__init__.py @@ -1,3 +1,19 @@ +# +# Copyright 2025 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 beartype.claw import beartype_this_package beartype_this_package() diff --git a/intergrations/chatgpt-on-wechat/plugins/ragflow_chat.py b/intergrations/chatgpt-on-wechat/plugins/ragflow_chat.py index 5d5615eaa17..fe96f39a747 100644 --- a/intergrations/chatgpt-on-wechat/plugins/ragflow_chat.py +++ b/intergrations/chatgpt-on-wechat/plugins/ragflow_chat.py @@ -1,3 +1,19 @@ +# +# Copyright 2025 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. +# + import logging import requests from bridge.context import ContextType # Import Context, ContextType diff --git a/rag/__init__.py b/rag/__init__.py index 6bfdd33d0ba..643f79713c8 100644 --- a/rag/__init__.py +++ b/rag/__init__.py @@ -1,2 +1,18 @@ +# +# Copyright 2025 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 beartype.claw import beartype_this_package beartype_this_package() diff --git a/rag/app/__init__.py b/rag/app/__init__.py index e69de29bb2d..e156bc93dde 100644 --- a/rag/app/__init__.py +++ b/rag/app/__init__.py @@ -0,0 +1,15 @@ +# +# Copyright 2025 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. +# \ No newline at end of file diff --git a/rag/app/audio.py b/rag/app/audio.py index ec7ffeea3e4..95e552ae9f5 100644 --- a/rag/app/audio.py +++ b/rag/app/audio.py @@ -1,3 +1,6 @@ +# +# Copyright 2025 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 @@ -10,6 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # + import re from api.db import LLMType diff --git a/rag/app/book.py b/rag/app/book.py index 763364778bc..fad526adcf2 100644 --- a/rag/app/book.py +++ b/rag/app/book.py @@ -1,3 +1,6 @@ +# +# Copyright 2025 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 @@ -10,6 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # + import logging from tika import parser import re diff --git a/rag/app/email.py b/rag/app/email.py index b14ee6d43e0..d1c98d5558c 100644 --- a/rag/app/email.py +++ b/rag/app/email.py @@ -1,3 +1,6 @@ +# +# Copyright 2025 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 diff --git a/rag/app/knowledge_graph.py b/rag/app/knowledge_graph.py index f4330f48286..030c9aaf24a 100644 --- a/rag/app/knowledge_graph.py +++ b/rag/app/knowledge_graph.py @@ -1,3 +1,19 @@ +# +# Copyright 2025 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. +# + import re from graphrag.index import build_knowledge_graph_chunks diff --git a/rag/app/laws.py b/rag/app/laws.py index 7a32c827319..6ed1ccc7782 100644 --- a/rag/app/laws.py +++ b/rag/app/laws.py @@ -1,3 +1,6 @@ +# +# Copyright 2025 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 @@ -10,6 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # + import logging from tika import parser import re diff --git a/rag/app/manual.py b/rag/app/manual.py index 9018cb2a587..96693697078 100644 --- a/rag/app/manual.py +++ b/rag/app/manual.py @@ -1,5 +1,5 @@ # -# Copyright 2024 The InfiniFlow Authors. All Rights Reserved. +# Copyright 2025 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. diff --git a/rag/app/naive.py b/rag/app/naive.py index fac626ab00f..7dbde2bb4a7 100644 --- a/rag/app/naive.py +++ b/rag/app/naive.py @@ -1,3 +1,6 @@ +# +# Copyright 2025 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 @@ -10,6 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # + import logging from tika import parser from io import BytesIO diff --git a/rag/app/one.py b/rag/app/one.py index bd691f46c3e..616a87dbc19 100644 --- a/rag/app/one.py +++ b/rag/app/one.py @@ -1,3 +1,6 @@ +# +# Copyright 2025 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 @@ -10,6 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # + import logging from tika import parser from io import BytesIO diff --git a/rag/app/paper.py b/rag/app/paper.py index 89af09b9085..529d3a02de4 100644 --- a/rag/app/paper.py +++ b/rag/app/paper.py @@ -1,3 +1,6 @@ +# +# Copyright 2025 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 @@ -10,6 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # + import logging import copy import re diff --git a/rag/app/picture.py b/rag/app/picture.py index fb9b1e26952..578da79ffee 100644 --- a/rag/app/picture.py +++ b/rag/app/picture.py @@ -1,3 +1,6 @@ +# +# Copyright 2025 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 @@ -10,6 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # + import io import numpy as np diff --git a/rag/app/presentation.py b/rag/app/presentation.py index a3305bdc116..09a8c3f461c 100644 --- a/rag/app/presentation.py +++ b/rag/app/presentation.py @@ -1,3 +1,6 @@ +# +# Copyright 2025 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 @@ -10,6 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # + import copy import re from io import BytesIO diff --git a/rag/app/qa.py b/rag/app/qa.py index 00cde2d64bf..a0c77c23833 100644 --- a/rag/app/qa.py +++ b/rag/app/qa.py @@ -1,3 +1,6 @@ +# +# Copyright 2025 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 @@ -10,6 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # + import logging import re import csv diff --git a/rag/app/resume.py b/rag/app/resume.py index da620cb38be..7c556e06ed9 100644 --- a/rag/app/resume.py +++ b/rag/app/resume.py @@ -1,3 +1,6 @@ +# +# Copyright 2025 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 @@ -10,6 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # + import logging import base64 import datetime diff --git a/rag/app/table.py b/rag/app/table.py index 88fceef787d..542edec7a68 100644 --- a/rag/app/table.py +++ b/rag/app/table.py @@ -1,3 +1,6 @@ +# +# Copyright 2025 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 @@ -10,6 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # + import copy import re from io import BytesIO diff --git a/rag/app/tag.py b/rag/app/tag.py index c1a15fafa3c..f5c29f2a818 100644 --- a/rag/app/tag.py +++ b/rag/app/tag.py @@ -1,3 +1,6 @@ +# +# Copyright 2025 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 @@ -10,6 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # + import re import csv from copy import deepcopy diff --git a/rag/svr/jina_server.py b/rag/svr/jina_server.py index 9dba8b55eb9..60bd0c8d8c7 100644 --- a/rag/svr/jina_server.py +++ b/rag/svr/jina_server.py @@ -1,3 +1,19 @@ +# +# Copyright 2025 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 jina import Deployment from docarray import BaseDoc from jina import Executor, requests diff --git a/rag/utils/azure_sas_conn.py b/rag/utils/azure_sas_conn.py index 8c1be4cd057..48f9d0a64ee 100644 --- a/rag/utils/azure_sas_conn.py +++ b/rag/utils/azure_sas_conn.py @@ -1,3 +1,19 @@ +# +# Copyright 2025 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. +# + import logging import os import time diff --git a/rag/utils/azure_spn_conn.py b/rag/utils/azure_spn_conn.py index c45ceb79527..625ccc4b541 100644 --- a/rag/utils/azure_spn_conn.py +++ b/rag/utils/azure_spn_conn.py @@ -1,3 +1,19 @@ +# +# Copyright 2025 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. +# + import logging import os import time diff --git a/rag/utils/doc_store_conn.py b/rag/utils/doc_store_conn.py index b8a20884109..c3fa61b0cda 100644 --- a/rag/utils/doc_store_conn.py +++ b/rag/utils/doc_store_conn.py @@ -1,3 +1,19 @@ +# +# Copyright 2025 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 abc import ABC, abstractmethod from dataclasses import dataclass import numpy as np diff --git a/rag/utils/es_conn.py b/rag/utils/es_conn.py index 1f959004552..c2b5fc22b80 100644 --- a/rag/utils/es_conn.py +++ b/rag/utils/es_conn.py @@ -1,3 +1,19 @@ +# +# Copyright 2025 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. +# + import logging import re import json diff --git a/rag/utils/infinity_conn.py b/rag/utils/infinity_conn.py index dd11b9ece27..57cbc34b2de 100644 --- a/rag/utils/infinity_conn.py +++ b/rag/utils/infinity_conn.py @@ -1,3 +1,19 @@ +# +# Copyright 2025 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. +# + import logging import os import re diff --git a/rag/utils/minio_conn.py b/rag/utils/minio_conn.py index 4662c7c8340..48f02b69997 100644 --- a/rag/utils/minio_conn.py +++ b/rag/utils/minio_conn.py @@ -1,3 +1,19 @@ +# +# Copyright 2025 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. +# + import logging import time from minio import Minio diff --git a/rag/utils/redis_conn.py b/rag/utils/redis_conn.py index 660e518734b..40779aa27a5 100644 --- a/rag/utils/redis_conn.py +++ b/rag/utils/redis_conn.py @@ -1,3 +1,19 @@ +# +# Copyright 2025 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. +# + import logging import json diff --git a/rag/utils/s3_conn.py b/rag/utils/s3_conn.py index 03690d8ad06..d1e7e72697e 100644 --- a/rag/utils/s3_conn.py +++ b/rag/utils/s3_conn.py @@ -1,3 +1,19 @@ +# +# Copyright 2025 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. +# + import logging import boto3 from botocore.exceptions import ClientError diff --git a/rag/utils/storage_factory.py b/rag/utils/storage_factory.py index 7c7a4a71de2..a27fda91a09 100644 --- a/rag/utils/storage_factory.py +++ b/rag/utils/storage_factory.py @@ -1,3 +1,19 @@ +# +# Copyright 2025 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. +# + import os from enum import Enum diff --git a/sdk/python/hello_ragflow.py b/sdk/python/hello_ragflow.py index d258943b304..5b73cb81ba9 100644 --- a/sdk/python/hello_ragflow.py +++ b/sdk/python/hello_ragflow.py @@ -1,3 +1,19 @@ +# +# Copyright 2025 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. +# + import ragflow_sdk -print(ragflow_sdk.__version__) \ No newline at end of file +print(ragflow_sdk.__version__) diff --git a/sdk/python/ragflow_sdk/__init__.py b/sdk/python/ragflow_sdk/__init__.py index b7cf31e1235..7535aa4eda1 100644 --- a/sdk/python/ragflow_sdk/__init__.py +++ b/sdk/python/ragflow_sdk/__init__.py @@ -1,3 +1,19 @@ +# +# Copyright 2025 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 beartype.claw import beartype_this_package beartype_this_package() diff --git a/sdk/python/ragflow_sdk/modules/__init__.py b/sdk/python/ragflow_sdk/modules/__init__.py index e69de29bb2d..e156bc93dde 100644 --- a/sdk/python/ragflow_sdk/modules/__init__.py +++ b/sdk/python/ragflow_sdk/modules/__init__.py @@ -0,0 +1,15 @@ +# +# Copyright 2025 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. +# \ No newline at end of file diff --git a/sdk/python/ragflow_sdk/modules/agent.py b/sdk/python/ragflow_sdk/modules/agent.py index 9ca3141281b..5579af98dca 100644 --- a/sdk/python/ragflow_sdk/modules/agent.py +++ b/sdk/python/ragflow_sdk/modules/agent.py @@ -1,3 +1,19 @@ +# +# Copyright 2025 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 .base import Base from .session import Session import requests diff --git a/sdk/python/ragflow_sdk/modules/base.py b/sdk/python/ragflow_sdk/modules/base.py index 49aa18db37f..5a6264f7903 100644 --- a/sdk/python/ragflow_sdk/modules/base.py +++ b/sdk/python/ragflow_sdk/modules/base.py @@ -1,3 +1,19 @@ +# +# Copyright 2025 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. +# + class Base(object): def __init__(self, rag, res_dict): self.rag = rag diff --git a/sdk/python/ragflow_sdk/modules/chat.py b/sdk/python/ragflow_sdk/modules/chat.py index 013bddd7ef2..e85011504d3 100644 --- a/sdk/python/ragflow_sdk/modules/chat.py +++ b/sdk/python/ragflow_sdk/modules/chat.py @@ -1,3 +1,19 @@ +# +# Copyright 2025 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 .base import Base from .session import Session @@ -44,12 +60,11 @@ def __init__(self, rag, res_dict): def update(self, update_message: dict): res = self.put(f'/chats/{self.id}', - update_message) + update_message) res = res.json() if res.get("code") != 0: raise Exception(res["message"]) - def create_session(self, name: str = "New session") -> Session: res = self.post(f"/chats/{self.id}/sessions", {"name": name}) res = res.json() @@ -57,9 +72,10 @@ def create_session(self, name: str = "New session") -> Session: return Session(self.rag, res['data']) raise Exception(res["message"]) - def list_sessions(self,page: int = 1, page_size: int = 30, orderby: str = "create_time", desc: bool = True, + def list_sessions(self, page: int = 1, page_size: int = 30, orderby: str = "create_time", desc: bool = True, id: str = None, name: str = None) -> list[Session]: - res = self.get(f'/chats/{self.id}/sessions',{"page": page, "page_size": page_size, "orderby": orderby, "desc": desc, "id": id, "name": name} ) + res = self.get(f'/chats/{self.id}/sessions', + {"page": page, "page_size": page_size, "orderby": orderby, "desc": desc, "id": id, "name": name}) res = res.json() if res.get("code") == 0: result_list = [] @@ -68,7 +84,7 @@ def list_sessions(self,page: int = 1, page_size: int = 30, orderby: str = "creat return result_list raise Exception(res["message"]) - def delete_sessions(self,ids: list[str] | None = None): + def delete_sessions(self, ids: list[str] | None = None): res = self.rm(f"/chats/{self.id}/sessions", {"ids": ids}) res = res.json() if res.get("code") != 0: diff --git a/sdk/python/ragflow_sdk/modules/chunk.py b/sdk/python/ragflow_sdk/modules/chunk.py index 960c87df6fb..4471b58afd2 100644 --- a/sdk/python/ragflow_sdk/modules/chunk.py +++ b/sdk/python/ragflow_sdk/modules/chunk.py @@ -1,3 +1,19 @@ +# +# Copyright 2025 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 .base import Base @@ -18,11 +34,8 @@ def __init__(self, rag, res_dict): res_dict.pop(k) super().__init__(rag, res_dict) - - def update(self,update_message:dict): - res = self.put(f"/datasets/{self.dataset_id}/documents/{self.document_id}/chunks/{self.id}",update_message) + def update(self, update_message: dict): + res = self.put(f"/datasets/{self.dataset_id}/documents/{self.document_id}/chunks/{self.id}", update_message) res = res.json() - if res.get("code") != 0 : + if res.get("code") != 0: raise Exception(res["message"]) - - diff --git a/sdk/python/ragflow_sdk/modules/dataset.py b/sdk/python/ragflow_sdk/modules/dataset.py index 043a600ef06..57d76d3aefa 100644 --- a/sdk/python/ragflow_sdk/modules/dataset.py +++ b/sdk/python/ragflow_sdk/modules/dataset.py @@ -1,3 +1,19 @@ +# +# Copyright 2025 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 .document import Document from .base import Base @@ -29,48 +45,51 @@ def __init__(self, rag, res_dict): def update(self, update_message: dict): res = self.put(f'/datasets/{self.id}', - update_message) + update_message) res = res.json() if res.get("code") != 0: raise Exception(res["message"]) - def upload_documents(self,document_list: list[dict]): + def upload_documents(self, document_list: list[dict]): url = f"/datasets/{self.id}/documents" - files = [("file",(ele["display_name"],ele["blob"])) for ele in document_list] - res = self.post(path=url,json=None,files=files) + files = [("file", (ele["display_name"], ele["blob"])) for ele in document_list] + res = self.post(path=url, json=None, files=files) res = res.json() if res.get("code") == 0: - doc_list=[] + doc_list = [] for doc in res["data"]: - document = Document(self.rag,doc) + document = Document(self.rag, doc) doc_list.append(document) return doc_list raise Exception(res.get("message")) - def list_documents(self, id: str | None = None, keywords: str | None = None, page: int = 1, page_size: int = 30, orderby: str = "create_time", desc: bool = True): - res = self.get(f"/datasets/{self.id}/documents",params={"id": id,"keywords": keywords,"page": page,"page_size": page_size,"orderby": orderby,"desc": desc}) + def list_documents(self, id: str | None = None, keywords: str | None = None, page: int = 1, page_size: int = 30, + orderby: str = "create_time", desc: bool = True): + res = self.get(f"/datasets/{self.id}/documents", + params={"id": id, "keywords": keywords, "page": page, "page_size": page_size, "orderby": orderby, + "desc": desc}) res = res.json() documents = [] if res.get("code") == 0: for document in res["data"].get("docs"): - documents.append(Document(self.rag,document)) + documents.append(Document(self.rag, document)) return documents raise Exception(res["message"]) - def delete_documents(self,ids: list[str] | None = None): - res = self.rm(f"/datasets/{self.id}/documents",{"ids":ids}) + def delete_documents(self, ids: list[str] | None = None): + res = self.rm(f"/datasets/{self.id}/documents", {"ids": ids}) res = res.json() if res.get("code") != 0: raise Exception(res["message"]) - def async_parse_documents(self,document_ids): - res = self.post(f"/datasets/{self.id}/chunks",{"document_ids":document_ids}) + def async_parse_documents(self, document_ids): + res = self.post(f"/datasets/{self.id}/chunks", {"document_ids": document_ids}) res = res.json() if res.get("code") != 0: raise Exception(res.get("message")) - def async_cancel_parse_documents(self,document_ids): - res = self.rm(f"/datasets/{self.id}/chunks",{"document_ids":document_ids}) + def async_cancel_parse_documents(self, document_ids): + res = self.rm(f"/datasets/{self.id}/chunks", {"document_ids": document_ids}) res = res.json() if res.get("code") != 0: raise Exception(res.get("message")) diff --git a/sdk/python/ragflow_sdk/modules/document.py b/sdk/python/ragflow_sdk/modules/document.py index 743016b2355..bb3211d2420 100644 --- a/sdk/python/ragflow_sdk/modules/document.py +++ b/sdk/python/ragflow_sdk/modules/document.py @@ -1,3 +1,19 @@ +# +# Copyright 2025 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. +# + import json from .base import Base from .chunk import Chunk @@ -32,7 +48,6 @@ def __init__(self, rag, res_dict): res_dict.pop(k) super().__init__(rag, res_dict) - def update(self, update_message: dict): res = self.put(f'/datasets/{self.dataset_id}/documents/{self.id}', update_message) @@ -48,29 +63,28 @@ def download(self): except json.JSONDecodeError: return res.content - - def list_chunks(self,page=1, page_size=30, keywords=""): - data={"keywords": keywords,"page":page,"page_size":page_size} + def list_chunks(self, page=1, page_size=30, keywords=""): + data = {"keywords": keywords, "page": page, "page_size": page_size} res = self.get(f'/datasets/{self.dataset_id}/documents/{self.id}/chunks', data) res = res.json() if res.get("code") == 0: - chunks=[] + chunks = [] for data in res["data"].get("chunks"): - chunk = Chunk(self.rag,data) + chunk = Chunk(self.rag, data) chunks.append(chunk) return chunks raise Exception(res.get("message")) def add_chunk(self, content: str, important_keywords: list[str] = [], questions: list[str] = []): res = self.post(f'/datasets/{self.dataset_id}/documents/{self.id}/chunks', - {"content":content,"important_keywords":important_keywords, "questions": questions}) + {"content": content, "important_keywords": important_keywords, "questions": questions}) res = res.json() if res.get("code") == 0: - return Chunk(self.rag,res["data"].get("chunk")) + return Chunk(self.rag, res["data"].get("chunk")) raise Exception(res.get("message")) - def delete_chunks(self,ids:list[str] | None = None): - res = self.rm(f"/datasets/{self.dataset_id}/documents/{self.id}/chunks",{"chunk_ids":ids}) + def delete_chunks(self, ids: list[str] | None = None): + res = self.rm(f"/datasets/{self.dataset_id}/documents/{self.id}/chunks", {"chunk_ids": ids}) res = res.json() - if res.get("code")!=0: - raise Exception(res.get("message")) \ No newline at end of file + if res.get("code") != 0: + raise Exception(res.get("message")) diff --git a/sdk/python/ragflow_sdk/modules/session.py b/sdk/python/ragflow_sdk/modules/session.py index dcfc3392be3..9a1a7fd3dbc 100644 --- a/sdk/python/ragflow_sdk/modules/session.py +++ b/sdk/python/ragflow_sdk/modules/session.py @@ -1,3 +1,19 @@ +# +# Copyright 2025 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. +# + import json from .base import Base @@ -8,8 +24,8 @@ def __init__(self, rag, res_dict): self.id = None self.name = "New session" self.messages = [{"role": "assistant", "content": "Hi! I am your assistant,can I help you?"}] - for key,value in res_dict.items(): - if key =="chat_id" and value is not None: + for key, value in res_dict.items(): + if key == "chat_id" and value is not None: self.chat_id = None self.__session_type = "chat" if key == "agent_id" and value is not None: @@ -17,11 +33,11 @@ def __init__(self, rag, res_dict): self.__session_type = "agent" super().__init__(rag, res_dict) - def ask(self, question="",stream=True,**kwargs): + def ask(self, question="", stream=True, **kwargs): if self.__session_type == "agent": - res=self._ask_agent(question,stream) + res = self._ask_agent(question, stream) elif self.__session_type == "chat": - res=self._ask_chat(question,stream,**kwargs) + res = self._ask_chat(question, stream, **kwargs) for line in res.iter_lines(): line = line.decode("utf-8") if line.startswith("{"): @@ -44,25 +60,26 @@ def ask(self, question="",stream=True,**kwargs): message = Message(self.rag, temp_dict) yield message - def _ask_chat(self, question: str, stream: bool,**kwargs): - json_data={"question": question, "stream": True,"session_id":self.id} + def _ask_chat(self, question: str, stream: bool, **kwargs): + json_data = {"question": question, "stream": True, "session_id": self.id} json_data.update(kwargs) res = self.post(f"/chats/{self.chat_id}/completions", json_data, stream=stream) return res - def _ask_agent(self,question:str,stream:bool): + def _ask_agent(self, question: str, stream: bool): res = self.post(f"/agents/{self.agent_id}/completions", - {"question": question, "stream": True,"session_id":self.id}, stream=stream) + {"question": question, "stream": True, "session_id": self.id}, stream=stream) return res - def update(self,update_message): + def update(self, update_message): res = self.put(f"/chats/{self.chat_id}/sessions/{self.id}", - update_message) + update_message) res = res.json() if res.get("code") != 0: raise Exception(res.get("message")) + class Message(Base): def __init__(self, rag, res_dict): self.content = "Hi! I am your assistant,can I help you?" diff --git a/sdk/python/test/conftest.py b/sdk/python/test/conftest.py index 463d0a88133..423ee3d3198 100644 --- a/sdk/python/test/conftest.py +++ b/sdk/python/test/conftest.py @@ -1,41 +1,61 @@ +# +# Copyright 2025 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. +# + import os import pytest import requests - HOST_ADDRESS = os.getenv('HOST_ADDRESS', 'http://127.0.0.1:9380') + # def generate_random_email(): # return 'user_' + ''.join(random.choices(string.ascii_lowercase + string.digits, k=8))+'@1.com' def generate_email(): return 'user_123@1.com' + EMAIL = generate_email() # password is "123" -PASSWORD='''ctAseGvejiaSWWZ88T/m4FQVOpQyUvP+x7sXtdv3feqZACiQleuewkUi35E16wSd5C5QcnkkcV9cYc8TKPTRZlxappDuirxghxoOvFcJxFU4ixLsD +PASSWORD = '''ctAseGvejiaSWWZ88T/m4FQVOpQyUvP+x7sXtdv3feqZACiQleuewkUi35E16wSd5C5QcnkkcV9cYc8TKPTRZlxappDuirxghxoOvFcJxFU4ixLsD fN33jCHRoDUW81IH9zjij/vaw8IbVyb6vuwg6MX6inOEBRRzVbRYxXOu1wkWY6SsI8X70oF9aeLFp/PzQpjoe/YbSqpTq8qqrmHzn9vO+yvyYyvmDsphXe X8f7fp9c7vUsfOCkM+gHY3PadG+QHa7KI7mzTKgUTZImK6BZtfRBATDTthEUbbaTewY4H0MnWiCeeDhcbeQao6cFy1To8pE3RpmxnGnS8BsBn8w==''' + def register(): url = HOST_ADDRESS + "/v1/user/register" name = "user" - register_data = {"email":EMAIL,"nickname":name,"password":PASSWORD} - res = requests.post(url=url,json=register_data) + register_data = {"email": EMAIL, "nickname": name, "password": PASSWORD} + res = requests.post(url=url, json=register_data) res = res.json() if res.get("code") != 0: raise Exception(res.get("message")) + def login(): url = HOST_ADDRESS + "/v1/user/login" - login_data = {"email":EMAIL,"password":PASSWORD} - response=requests.post(url=url,json=login_data) + login_data = {"email": EMAIL, "password": PASSWORD} + response = requests.post(url=url, json=login_data) res = response.json() - if res.get("code")!=0: + if res.get("code") != 0: raise Exception(res.get("message")) auth = response.headers["Authorization"] return auth + @pytest.fixture(scope="session") def get_api_key_fixture(): try: @@ -45,12 +65,13 @@ def get_api_key_fixture(): auth = login() url = HOST_ADDRESS + "/v1/system/new_token" auth = {"Authorization": auth} - response = requests.post(url=url,headers=auth) + response = requests.post(url=url, headers=auth) res = response.json() if res.get("code") != 0: raise Exception(res.get("message")) return res["data"].get("token") + @pytest.fixture(scope="session") def get_auth(): try: @@ -60,6 +81,7 @@ def get_auth(): auth = login() return auth + @pytest.fixture(scope="session") def get_email(): return EMAIL diff --git a/sdk/python/test/test_frontend_api/common.py b/sdk/python/test/test_frontend_api/common.py index 1a8c174c53d..19aa6df456e 100644 --- a/sdk/python/test/test_frontend_api/common.py +++ b/sdk/python/test/test_frontend_api/common.py @@ -1,3 +1,19 @@ +# +# Copyright 2025 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. +# + import os import requests diff --git a/sdk/python/test/test_frontend_api/get_email.py b/sdk/python/test/test_frontend_api/get_email.py index 923b82d2d21..181094f5add 100644 --- a/sdk/python/test/test_frontend_api/get_email.py +++ b/sdk/python/test/test_frontend_api/get_email.py @@ -1,3 +1,19 @@ +# +# Copyright 2025 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. +# + def test_get_email(get_email): print("\nEmail account:",flush=True) print(f"{get_email}\n",flush=True) \ No newline at end of file diff --git a/sdk/python/test/test_frontend_api/test_dataset.py b/sdk/python/test/test_frontend_api/test_dataset.py index fe2de715a8c..3baaf4e8ca1 100644 --- a/sdk/python/test/test_frontend_api/test_dataset.py +++ b/sdk/python/test/test_frontend_api/test_dataset.py @@ -1,3 +1,19 @@ +# +# Copyright 2025 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 common import create_dataset, list_dataset, rm_dataset, update_dataset, DATASET_NAME_LIMIT import re import random @@ -121,7 +137,8 @@ def test_update_different_params_dataset_success(get_auth): print(f"found {len(dataset_list)} datasets") dataset_id = dataset_list[0] - json_req = {"kb_id": dataset_id, "name": "test_update_dataset", "description": "test", "permission": "me", "parser_id": "presentation", + json_req = {"kb_id": dataset_id, "name": "test_update_dataset", "description": "test", "permission": "me", + "parser_id": "presentation", "language": "spanish"} res = update_dataset(get_auth, json_req) assert res.get("code") == 0, f"{res.get('message')}" @@ -164,4 +181,3 @@ def test_update_different_params_dataset_fail(get_auth): res = rm_dataset(get_auth, dataset_id) assert res.get("code") == 0, f"{res.get('message')}" print(f"{len(dataset_list)} datasets are deleted") - diff --git a/sdk/python/test/test_sdk_api/common.py b/sdk/python/test/test_sdk_api/common.py index a5bc8ad32bc..fe6aa88b7b1 100644 --- a/sdk/python/test/test_sdk_api/common.py +++ b/sdk/python/test/test_sdk_api/common.py @@ -1,2 +1,19 @@ +# +# Copyright 2025 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. +# + import os -HOST_ADDRESS=os.getenv('HOST_ADDRESS', 'http://127.0.0.1:9380') \ No newline at end of file + +HOST_ADDRESS = os.getenv('HOST_ADDRESS', 'http://127.0.0.1:9380') diff --git a/sdk/python/test/test_sdk_api/get_email.py b/sdk/python/test/test_sdk_api/get_email.py index 923b82d2d21..7238922b703 100644 --- a/sdk/python/test/test_sdk_api/get_email.py +++ b/sdk/python/test/test_sdk_api/get_email.py @@ -1,3 +1,19 @@ +# +# Copyright 2025 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. +# + def test_get_email(get_email): - print("\nEmail account:",flush=True) - print(f"{get_email}\n",flush=True) \ No newline at end of file + print("\nEmail account:", flush=True) + print(f"{get_email}\n", flush=True) diff --git a/sdk/python/test/test_sdk_api/t_agent.py b/sdk/python/test/test_sdk_api/t_agent.py index aa330e52bc9..2fcd0e535e7 100644 --- a/sdk/python/test/test_sdk_api/t_agent.py +++ b/sdk/python/test/test_sdk_api/t_agent.py @@ -1,11 +1,28 @@ -from ragflow_sdk import RAGFlow,Agent +# +# Copyright 2025 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 ragflow_sdk import RAGFlow, Agent from common import HOST_ADDRESS import pytest + @pytest.mark.skip(reason="") def test_list_agents_with_success(get_api_key_fixture): - API_KEY=get_api_key_fixture - rag = RAGFlow(API_KEY,HOST_ADDRESS) + API_KEY = get_api_key_fixture + rag = RAGFlow(API_KEY, HOST_ADDRESS) rag.list_agents() @@ -13,7 +30,7 @@ def test_list_agents_with_success(get_api_key_fixture): def test_converse_with_agent_with_success(get_api_key_fixture): API_KEY = "ragflow-BkOGNhYjIyN2JiODExZWY5MzVhMDI0Mm" agent_id = "ebfada2eb2bc11ef968a0242ac120006" - rag = RAGFlow(API_KEY,HOST_ADDRESS) + rag = RAGFlow(API_KEY, HOST_ADDRESS) lang = "Chinese" file = "How is the weather tomorrow?" - Agent.ask(agent_id=agent_id,rag=rag,lang=lang,file=file) + Agent.ask(agent_id=agent_id, rag=rag, lang=lang, file=file) diff --git a/sdk/python/test/test_sdk_api/t_chat.py b/sdk/python/test/test_sdk_api/t_chat.py index d1670ad8c0c..5b9ed4275a4 100644 --- a/sdk/python/test/test_sdk_api/t_chat.py +++ b/sdk/python/test/test_sdk_api/t_chat.py @@ -1,6 +1,23 @@ +# +# Copyright 2025 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 ragflow_sdk import RAGFlow from common import HOST_ADDRESS + def test_create_chat_with_name(get_api_key_fixture): API_KEY = get_api_key_fixture rag = RAGFlow(API_KEY, HOST_ADDRESS) @@ -8,10 +25,10 @@ def test_create_chat_with_name(get_api_key_fixture): display_name = "ragflow.txt" with open("test_data/ragflow.txt", "rb") as file: blob = file.read() - document = {"display_name":display_name,"blob":blob} + document = {"display_name": display_name, "blob": blob} documents = [] documents.append(document) - docs= kb.upload_documents(documents) + docs = kb.upload_documents(documents) for doc in docs: doc.add_chunk("This is a test to add chunk") rag.create_chat("test_create_chat", dataset_ids=[kb.id]) @@ -50,6 +67,7 @@ def test_delete_chats_with_success(get_api_key_fixture): chat = rag.create_chat("test_delete_chat", dataset_ids=[kb.id]) rag.delete_chats(ids=[chat.id]) + def test_list_chats_with_success(get_api_key_fixture): API_KEY = get_api_key_fixture rag = RAGFlow(API_KEY, HOST_ADDRESS) @@ -66,5 +84,3 @@ def test_list_chats_with_success(get_api_key_fixture): rag.create_chat("test_list_1", dataset_ids=[kb.id]) rag.create_chat("test_list_2", dataset_ids=[kb.id]) rag.list_chats() - - diff --git a/sdk/python/test/test_sdk_api/t_chunk.py b/sdk/python/test/test_sdk_api/t_chunk.py index a07e682e9cc..df2bfcad315 100644 --- a/sdk/python/test/test_sdk_api/t_chunk.py +++ b/sdk/python/test/test_sdk_api/t_chunk.py @@ -1,13 +1,30 @@ +# +# Copyright 2025 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 ragflow_sdk import RAGFlow from common import HOST_ADDRESS from time import sleep + def test_parse_document_with_txt(get_api_key_fixture): API_KEY = get_api_key_fixture rag = RAGFlow(API_KEY, HOST_ADDRESS) ds = rag.create_dataset(name="test_parse_document") name = 'ragflow_test.txt' - with open("test_data/ragflow_test.txt", "rb") as file : + with open("test_data/ragflow_test.txt", "rb") as file: blob = file.read() docs = ds.upload_documents([{"display_name": name, "blob": blob}]) doc = docs[0] @@ -21,14 +38,15 @@ def test_parse_document_with_txt(get_api_key_fixture): raise Exception("Run time ERROR: Document parsing did not complete in time.") ''' + def test_parse_and_cancel_document(get_api_key_fixture): API_KEY = get_api_key_fixture rag = RAGFlow(API_KEY, HOST_ADDRESS) ds = rag.create_dataset(name="test_parse_and_cancel_document") name = 'ragflow_test.txt' - with open("test_data/ragflow_test.txt", "rb") as file : + with open("test_data/ragflow_test.txt", "rb") as file: blob = file.read() - docs=ds.upload_documents([{"display_name": name, "blob": blob}]) + docs = ds.upload_documents([{"display_name": name, "blob": blob}]) doc = docs[0] ds.async_parse_documents(document_ids=[doc.id]) sleep(1) @@ -60,6 +78,7 @@ def test_bulk_parse_documents(get_api_key_fixture): raise Exception("Run time ERROR: Bulk document parsing did not complete in time.") ''' + def test_list_chunks_with_success(get_api_key_fixture): API_KEY = get_api_key_fixture rag = RAGFlow(API_KEY, HOST_ADDRESS) @@ -73,7 +92,7 @@ def test_list_chunks_with_success(get_api_key_fixture): {'display_name': f'chunk_{i}.txt', 'blob': chunk} for i, chunk in enumerate(chunks) ] ''' - documents =[{"display_name":"test_list_chunks_with_success.txt","blob":blob}] + documents = [{"display_name": "test_list_chunks_with_success.txt", "blob": blob}] docs = ds.upload_documents(documents) ids = [doc.id for doc in docs] ds.async_parse_documents(ids) @@ -103,7 +122,7 @@ def test_add_chunk_with_success(get_api_key_fixture): {'display_name': f'chunk_{i}.txt', 'blob': chunk} for i, chunk in enumerate(chunks) ] ''' - documents =[{"display_name":"test_list_chunks_with_success.txt","blob":blob}] + documents = [{"display_name": "test_list_chunks_with_success.txt", "blob": blob}] docs = ds.upload_documents(documents) doc = docs[0] doc.add_chunk(content="This is a chunk addition test") @@ -122,7 +141,7 @@ def test_delete_chunk_with_success(get_api_key_fixture): {'display_name': f'chunk_{i}.txt', 'blob': chunk} for i, chunk in enumerate(chunks) ] ''' - documents =[{"display_name":"test_delete_chunk_with_success.txt","blob":blob}] + documents = [{"display_name": "test_delete_chunk_with_success.txt", "blob": blob}] docs = ds.upload_documents(documents) doc = docs[0] chunk = doc.add_chunk(content="This is a chunk addition test") @@ -143,13 +162,14 @@ def test_update_chunk_content(get_api_key_fixture): {'display_name': f'chunk_{i}.txt', 'blob': chunk} for i, chunk in enumerate(chunks) ] ''' - documents =[{"display_name":"test_update_chunk_content_with_success.txt","blob":blob}] + documents = [{"display_name": "test_update_chunk_content_with_success.txt", "blob": blob}] docs = ds.upload_documents(documents) doc = docs[0] chunk = doc.add_chunk(content="This is a chunk addition test") # For Elasticsearch, the chunk is not searchable in shot time (~2s). sleep(3) - chunk.update({"content":"This is a updated content"}) + chunk.update({"content": "This is a updated content"}) + def test_update_chunk_available(get_api_key_fixture): API_KEY = get_api_key_fixture @@ -164,13 +184,13 @@ def test_update_chunk_available(get_api_key_fixture): {'display_name': f'chunk_{i}.txt', 'blob': chunk} for i, chunk in enumerate(chunks) ] ''' - documents =[{"display_name":"test_update_chunk_available_with_success.txt","blob":blob}] + documents = [{"display_name": "test_update_chunk_available_with_success.txt", "blob": blob}] docs = ds.upload_documents(documents) doc = docs[0] chunk = doc.add_chunk(content="This is a chunk addition test") # For Elasticsearch, the chunk is not searchable in shot time (~2s). sleep(3) - chunk.update({"available":0}) + chunk.update({"available": 0}) def test_retrieve_chunks(get_api_key_fixture): @@ -186,11 +206,11 @@ def test_retrieve_chunks(get_api_key_fixture): {'display_name': f'chunk_{i}.txt', 'blob': chunk} for i, chunk in enumerate(chunks) ] ''' - documents =[{"display_name":"test_retrieve_chunks.txt","blob":blob}] + documents = [{"display_name": "test_retrieve_chunks.txt", "blob": blob}] docs = ds.upload_documents(documents) doc = docs[0] doc.add_chunk(content="This is a chunk addition test") - rag.retrieve(dataset_ids=[ds.id],document_ids=[doc.id]) + rag.retrieve(dataset_ids=[ds.id], document_ids=[doc.id]) rag.delete_datasets(ids=[ds.id]) # test different parameters for the retrieval diff --git a/sdk/python/test/test_sdk_api/t_dataset.py b/sdk/python/test/test_sdk_api/t_dataset.py index 288474409f8..7163e445cad 100644 --- a/sdk/python/test/test_sdk_api/t_dataset.py +++ b/sdk/python/test/test_sdk_api/t_dataset.py @@ -1,13 +1,31 @@ +# +# Copyright 2025 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 ragflow_sdk import RAGFlow import random import pytest from common import HOST_ADDRESS + def test_create_dataset_with_name(get_api_key_fixture): API_KEY = get_api_key_fixture rag = RAGFlow(API_KEY, HOST_ADDRESS) rag.create_dataset("test_create_dataset_with_name") + def test_create_dataset_with_duplicated_name(get_api_key_fixture): API_KEY = get_api_key_fixture rag = RAGFlow(API_KEY, HOST_ADDRESS) @@ -16,12 +34,15 @@ def test_create_dataset_with_duplicated_name(get_api_key_fixture): rag.create_dataset("test_create_dataset_with_duplicated_name") assert str(exc_info.value) == "Duplicated dataset name in creating dataset." + def test_create_dataset_with_random_chunk_method(get_api_key_fixture): API_KEY = get_api_key_fixture rag = RAGFlow(API_KEY, HOST_ADDRESS) - valid_chunk_methods = ["naive","manual","qa","table","paper","book","laws","presentation","picture","one","knowledge_graph","email"] + valid_chunk_methods = ["naive", "manual", "qa", "table", "paper", "book", "laws", "presentation", "picture", "one", + "knowledge_graph", "email"] random_chunk_method = random.choice(valid_chunk_methods) - rag.create_dataset("test_create_dataset_with_random_chunk_method",chunk_method=random_chunk_method) + rag.create_dataset("test_create_dataset_with_random_chunk_method", chunk_method=random_chunk_method) + def test_create_dataset_with_invalid_parameter(get_api_key_fixture): API_KEY = get_api_key_fixture @@ -30,7 +51,7 @@ def test_create_dataset_with_invalid_parameter(get_api_key_fixture): "knowledge_graph", "email", "tag"] chunk_method = "invalid_chunk_method" with pytest.raises(Exception) as exc_info: - rag.create_dataset("test_create_dataset_with_invalid_chunk_method",chunk_method=chunk_method) + rag.create_dataset("test_create_dataset_with_invalid_chunk_method", chunk_method=chunk_method) assert str(exc_info.value) == f"'{chunk_method}' is not in {valid_chunk_methods}" diff --git a/sdk/python/test/test_sdk_api/t_document.py b/sdk/python/test/test_sdk_api/t_document.py index 056963aa0fd..733b9bb5a5b 100644 --- a/sdk/python/test/test_sdk_api/t_document.py +++ b/sdk/python/test/test_sdk_api/t_document.py @@ -1,17 +1,34 @@ +# +# Copyright 2025 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 ragflow_sdk import RAGFlow from common import HOST_ADDRESS import pytest + def test_upload_document_with_success(get_api_key_fixture): API_KEY = get_api_key_fixture rag = RAGFlow(API_KEY, HOST_ADDRESS) ds = rag.create_dataset(name="test_upload_document") blob = b"Sample document content for test." with open("test_data/ragflow.txt", "rb") as file: - blob_2=file.read() + blob_2 = file.read() document_infos = [] - document_infos.append({"display_name": "test_1.txt","blob": blob}) - document_infos.append({"display_name": "test_2.txt","blob": blob_2}) + document_infos.append({"display_name": "test_1.txt", "blob": blob}) + document_infos.append({"display_name": "test_2.txt", "blob": blob_2}) ds.upload_documents(document_infos) @@ -20,8 +37,8 @@ def test_update_document_with_success(get_api_key_fixture): rag = RAGFlow(API_KEY, HOST_ADDRESS) ds = rag.create_dataset(name="test_update_document") blob = b"Sample document content for test." - document_infos=[{"display_name":"test.txt","blob":blob}] - docs=ds.upload_documents(document_infos) + document_infos = [{"display_name": "test.txt", "blob": blob}] + docs = ds.upload_documents(document_infos) doc = docs[0] doc.update({"chunk_method": "manual", "name": "manual.txt"}) @@ -31,10 +48,10 @@ def test_download_document_with_success(get_api_key_fixture): rag = RAGFlow(API_KEY, HOST_ADDRESS) ds = rag.create_dataset(name="test_download_document") blob = b"Sample document content for test." - document_infos=[{"display_name": "test_1.txt","blob": blob}] - docs=ds.upload_documents(document_infos) + document_infos = [{"display_name": "test_1.txt", "blob": blob}] + docs = ds.upload_documents(document_infos) doc = docs[0] - with open("test_download.txt","wb+") as file: + with open("test_download.txt", "wb+") as file: file.write(doc.download()) @@ -43,7 +60,7 @@ def test_list_documents_in_dataset_with_success(get_api_key_fixture): rag = RAGFlow(API_KEY, HOST_ADDRESS) ds = rag.create_dataset(name="test_list_documents") blob = b"Sample document content for test." - document_infos = [{"display_name": "test.txt","blob":blob}] + document_infos = [{"display_name": "test.txt", "blob": blob}] ds.upload_documents(document_infos) ds.list_documents(keywords="test", page=1, page_size=12) @@ -54,113 +71,128 @@ def test_delete_documents_in_dataset_with_success(get_api_key_fixture): ds = rag.create_dataset(name="test_delete_documents") name = "test_delete_documents.txt" blob = b"Sample document content for test." - document_infos=[{"display_name": name, "blob": blob}] + document_infos = [{"display_name": name, "blob": blob}] docs = ds.upload_documents(document_infos) ds.delete_documents([docs[0].id]) + # upload and parse the document with different in different parse method. def test_upload_and_parse_pdf_documents_with_general_parse_method(get_api_key_fixture): API_KEY = get_api_key_fixture rag = RAGFlow(API_KEY, HOST_ADDRESS) ds = rag.create_dataset(name="test_pdf_document") with open("test_data/test.pdf", "rb") as file: - blob=file.read() - document_infos = [{"display_name": "test.pdf","blob": blob}] - docs=ds.upload_documents(document_infos) + blob = file.read() + document_infos = [{"display_name": "test.pdf", "blob": blob}] + docs = ds.upload_documents(document_infos) doc = docs[0] ds.async_parse_documents([doc.id]) + def test_upload_and_parse_docx_documents_with_general_parse_method(get_api_key_fixture): API_KEY = get_api_key_fixture rag = RAGFlow(API_KEY, HOST_ADDRESS) ds = rag.create_dataset(name="test_docx_document") with open("test_data/test.docx", "rb") as file: - blob=file.read() - document_infos = [{"display_name": "test.docx","blob": blob}] - docs=ds.upload_documents(document_infos) + blob = file.read() + document_infos = [{"display_name": "test.docx", "blob": blob}] + docs = ds.upload_documents(document_infos) doc = docs[0] ds.async_parse_documents([doc.id]) + + def test_upload_and_parse_excel_documents_with_general_parse_method(get_api_key_fixture): API_KEY = get_api_key_fixture rag = RAGFlow(API_KEY, HOST_ADDRESS) ds = rag.create_dataset(name="test_excel_document") with open("test_data/test.xlsx", "rb") as file: - blob=file.read() - document_infos = [{"display_name": "test.xlsx","blob": blob}] - docs=ds.upload_documents(document_infos) + blob = file.read() + document_infos = [{"display_name": "test.xlsx", "blob": blob}] + docs = ds.upload_documents(document_infos) doc = docs[0] ds.async_parse_documents([doc.id]) + + def test_upload_and_parse_ppt_documents_with_general_parse_method(get_api_key_fixture): API_KEY = get_api_key_fixture rag = RAGFlow(API_KEY, HOST_ADDRESS) ds = rag.create_dataset(name="test_ppt_document") with open("test_data/test.ppt", "rb") as file: - blob=file.read() - document_infos = [{"display_name": "test.ppt","blob": blob}] - docs=ds.upload_documents(document_infos) + blob = file.read() + document_infos = [{"display_name": "test.ppt", "blob": blob}] + docs = ds.upload_documents(document_infos) doc = docs[0] ds.async_parse_documents([doc.id]) + + def test_upload_and_parse_image_documents_with_general_parse_method(get_api_key_fixture): API_KEY = get_api_key_fixture rag = RAGFlow(API_KEY, HOST_ADDRESS) ds = rag.create_dataset(name="test_image_document") with open("test_data/test.jpg", "rb") as file: - blob=file.read() - document_infos = [{"display_name": "test.jpg","blob": blob}] - docs=ds.upload_documents(document_infos) + blob = file.read() + document_infos = [{"display_name": "test.jpg", "blob": blob}] + docs = ds.upload_documents(document_infos) doc = docs[0] ds.async_parse_documents([doc.id]) + + def test_upload_and_parse_txt_documents_with_general_parse_method(get_api_key_fixture): API_KEY = get_api_key_fixture rag = RAGFlow(API_KEY, HOST_ADDRESS) ds = rag.create_dataset(name="test_txt_document") with open("test_data/test.txt", "rb") as file: - blob=file.read() - document_infos = [{"display_name": "test.txt","blob": blob}] - docs=ds.upload_documents(document_infos) + blob = file.read() + document_infos = [{"display_name": "test.txt", "blob": blob}] + docs = ds.upload_documents(document_infos) doc = docs[0] ds.async_parse_documents([doc.id]) + + def test_upload_and_parse_md_documents_with_general_parse_method(get_api_key_fixture): API_KEY = get_api_key_fixture rag = RAGFlow(API_KEY, HOST_ADDRESS) ds = rag.create_dataset(name="test_md_document") with open("test_data/test.md", "rb") as file: - blob=file.read() - document_infos = [{"display_name": "test.md","blob": blob}] - docs=ds.upload_documents(document_infos) + blob = file.read() + document_infos = [{"display_name": "test.md", "blob": blob}] + docs = ds.upload_documents(document_infos) doc = docs[0] ds.async_parse_documents([doc.id]) + def test_upload_and_parse_json_documents_with_general_parse_method(get_api_key_fixture): API_KEY = get_api_key_fixture rag = RAGFlow(API_KEY, HOST_ADDRESS) ds = rag.create_dataset(name="test_json_document") with open("test_data/test.json", "rb") as file: - blob=file.read() - document_infos = [{"display_name": "test.json","blob": blob}] - docs=ds.upload_documents(document_infos) + blob = file.read() + document_infos = [{"display_name": "test.json", "blob": blob}] + docs = ds.upload_documents(document_infos) doc = docs[0] ds.async_parse_documents([doc.id]) + @pytest.mark.skip(reason="") def test_upload_and_parse_eml_documents_with_general_parse_method(get_api_key_fixture): API_KEY = get_api_key_fixture rag = RAGFlow(API_KEY, HOST_ADDRESS) ds = rag.create_dataset(name="test_eml_document") with open("test_data/test.eml", "rb") as file: - blob=file.read() - document_infos = [{"display_name": "test.eml","blob": blob}] - docs=ds.upload_documents(document_infos) + blob = file.read() + document_infos = [{"display_name": "test.eml", "blob": blob}] + docs = ds.upload_documents(document_infos) doc = docs[0] ds.async_parse_documents([doc.id]) + def test_upload_and_parse_html_documents_with_general_parse_method(get_api_key_fixture): API_KEY = get_api_key_fixture rag = RAGFlow(API_KEY, HOST_ADDRESS) ds = rag.create_dataset(name="test_html_document") with open("test_data/test.html", "rb") as file: - blob=file.read() - document_infos = [{"display_name": "test.html","blob": blob}] - docs=ds.upload_documents(document_infos) + blob = file.read() + document_infos = [{"display_name": "test.html", "blob": blob}] + docs = ds.upload_documents(document_infos) doc = docs[0] - ds.async_parse_documents([doc.id]) \ No newline at end of file + ds.async_parse_documents([doc.id]) diff --git a/sdk/python/test/test_sdk_api/t_session.py b/sdk/python/test/test_sdk_api/t_session.py index c4c064b84f4..40932fdad08 100644 --- a/sdk/python/test/test_sdk_api/t_session.py +++ b/sdk/python/test/test_sdk_api/t_session.py @@ -1,4 +1,20 @@ -from ragflow_sdk import RAGFlow,Agent +# +# Copyright 2025 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 ragflow_sdk import RAGFlow, Agent from common import HOST_ADDRESS import pytest @@ -10,13 +26,13 @@ def test_create_session_with_success(get_api_key_fixture): display_name = "ragflow.txt" with open("test_data/ragflow.txt", "rb") as file: blob = file.read() - document = {"display_name":display_name,"blob":blob} + document = {"display_name": display_name, "blob": blob} documents = [] documents.append(document) - docs= kb.upload_documents(documents) + docs = kb.upload_documents(documents) for doc in docs: doc.add_chunk("This is a test to add chunk") - assistant=rag.create_chat("test_create_session", dataset_ids=[kb.id]) + assistant = rag.create_chat("test_create_session", dataset_ids=[kb.id]) assistant.create_session() @@ -38,7 +54,7 @@ def test_create_conversation_with_success(get_api_key_fixture): question = "What is AI" for ans in session.ask(question): pass - + # assert not ans.content.startswith("**ERROR**"), "Please check this error." @@ -49,13 +65,13 @@ def test_delete_sessions_with_success(get_api_key_fixture): display_name = "ragflow.txt" with open("test_data/ragflow.txt", "rb") as file: blob = file.read() - document = {"display_name":display_name,"blob":blob} + document = {"display_name": display_name, "blob": blob} documents = [] documents.append(document) - docs= kb.upload_documents(documents) + docs = kb.upload_documents(documents) for doc in docs: doc.add_chunk("This is a test to add chunk") - assistant=rag.create_chat("test_delete_session", dataset_ids=[kb.id]) + assistant = rag.create_chat("test_delete_session", dataset_ids=[kb.id]) session = assistant.create_session() assistant.delete_sessions(ids=[session.id]) @@ -85,33 +101,36 @@ def test_list_sessions_with_success(get_api_key_fixture): display_name = "ragflow.txt" with open("test_data/ragflow.txt", "rb") as file: blob = file.read() - document = {"display_name":display_name,"blob":blob} + document = {"display_name": display_name, "blob": blob} documents = [] documents.append(document) - docs= kb.upload_documents(documents) + docs = kb.upload_documents(documents) for doc in docs: doc.add_chunk("This is a test to add chunk") - assistant=rag.create_chat("test_list_session", dataset_ids=[kb.id]) + assistant = rag.create_chat("test_list_session", dataset_ids=[kb.id]) assistant.create_session("test_1") assistant.create_session("test_2") assistant.list_sessions() + @pytest.mark.skip(reason="") def test_create_agent_session_with_success(get_api_key_fixture): API_KEY = "ragflow-BkOGNhYjIyN2JiODExZWY5MzVhMDI0Mm" - rag = RAGFlow(API_KEY,HOST_ADDRESS) + rag = RAGFlow(API_KEY, HOST_ADDRESS) Agent.create_session("2e45b5209c1011efa3e90242ac120006", rag) + @pytest.mark.skip(reason="") def test_create_agent_conversation_with_success(get_api_key_fixture): API_KEY = "ragflow-BkOGNhYjIyN2JiODExZWY5MzVhMDI0Mm" - rag = RAGFlow(API_KEY,HOST_ADDRESS) + rag = RAGFlow(API_KEY, HOST_ADDRESS) session = Agent.create_session("2e45b5209c1011efa3e90242ac120006", rag) session.ask("What is this job") + @pytest.mark.skip(reason="") def test_list_agent_sessions_with_success(get_api_key_fixture): API_KEY = "ragflow-BkOGNhYjIyN2JiODExZWY5MzVhMDI0Mm" agent_id = "2710f2269b4611ef8fdf0242ac120006" - rag = RAGFlow(API_KEY,HOST_ADDRESS) - Agent.list_sessions(agent_id,rag) + rag = RAGFlow(API_KEY, HOST_ADDRESS) + Agent.list_sessions(agent_id, rag)