Skip to content

Commit 1097bf3

Browse files
committed
Merge branch 'plugins/beta' into dev/plugin-deploy
2 parents 4920821 + beebba0 commit 1097bf3

File tree

368 files changed

+5103
-3438
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

368 files changed

+5103
-3438
lines changed

.github/actions/setup-poetry/action.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ inputs:
88
poetry-version:
99
description: Poetry version to set up
1010
required: true
11-
default: '1.8.4'
11+
default: '2.0.1'
1212
poetry-lockfile:
1313
description: Path to the Poetry lockfile to restore cache from
1414
required: true

.github/workflows/api-tests.yml

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -43,19 +43,17 @@ jobs:
4343
run: poetry install -C api --with dev
4444

4545
- name: Check dependencies in pyproject.toml
46-
run: poetry run -C api bash dev/pytest/pytest_artifacts.sh
46+
run: poetry run -P api bash dev/pytest/pytest_artifacts.sh
4747

4848
- name: Run Unit tests
49-
run: poetry run -C api bash dev/pytest/pytest_unit_tests.sh
49+
run: poetry run -P api bash dev/pytest/pytest_unit_tests.sh
5050

5151
- name: Run dify config tests
52-
run: poetry run -C api python dev/pytest/pytest_config_tests.py
52+
run: poetry run -P api python dev/pytest/pytest_config_tests.py
5353

5454
- name: Run mypy
5555
run: |
56-
pushd api
57-
poetry run python -m mypy --install-types --non-interactive .
58-
popd
56+
poetry run -C api python -m mypy --install-types --non-interactive .
5957
6058
- name: Set up dotenvs
6159
run: |
@@ -75,4 +73,4 @@ jobs:
7573
ssrf_proxy
7674
7775
- name: Run Workflow
78-
run: poetry run -C api bash dev/pytest/pytest_workflow.sh
76+
run: poetry run -P api bash dev/pytest/pytest_workflow.sh

.github/workflows/style.yml

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,12 +39,12 @@ jobs:
3939
if: steps.changed-files.outputs.any_changed == 'true'
4040
run: |
4141
poetry run -C api ruff --version
42-
poetry run -C api ruff check ./api
43-
poetry run -C api ruff format --check ./api
42+
poetry run -C api ruff check ./
43+
poetry run -C api ruff format --check ./
4444
4545
- name: Dotenv check
4646
if: steps.changed-files.outputs.any_changed == 'true'
47-
run: poetry run -C api dotenv-linter ./api/.env.example ./web/.env.example
47+
run: poetry run -P api dotenv-linter ./api/.env.example ./web/.env.example
4848

4949
- name: Lint hints
5050
if: failure()
@@ -87,7 +87,35 @@ jobs:
8787

8888
- name: Web style check
8989
if: steps.changed-files.outputs.any_changed == 'true'
90-
run: echo "${{ steps.changed-files.outputs.all_changed_files }}" | sed 's|web/||g' | xargs pnpm eslint # wait for next lint support eslint v9
90+
run: yarn run lint
91+
92+
docker-compose-template:
93+
name: Docker Compose Template
94+
runs-on: ubuntu-latest
95+
96+
steps:
97+
- name: Checkout code
98+
uses: actions/checkout@v4
99+
100+
- name: Check changed files
101+
id: changed-files
102+
uses: tj-actions/changed-files@v45
103+
with:
104+
files: |
105+
docker/generate_docker_compose
106+
docker/.env.example
107+
docker/docker-compose-template.yaml
108+
docker/docker-compose.yaml
109+
110+
- name: Generate Docker Compose
111+
if: steps.changed-files.outputs.any_changed == 'true'
112+
run: |
113+
cd docker
114+
./generate_docker_compose
115+
116+
- name: Check for changes
117+
if: steps.changed-files.outputs.any_changed == 'true'
118+
run: git diff --exit-code
91119

92120

93121
docker-compose-template:

.github/workflows/vdb-tests.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,4 +70,4 @@ jobs:
7070
tidb
7171
7272
- name: Test Vector Stores
73-
run: poetry run -C api bash dev/pytest/pytest_vdb.sh
73+
run: poetry run -P api bash dev/pytest/pytest_vdb.sh

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,3 +197,6 @@ api/.vscode
197197

198198
# pnpm
199199
/.pnpm-store
200+
201+
# plugin migrate
202+
plugins.jsonl

api/.env.example

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -422,8 +422,7 @@ POSITION_PROVIDER_INCLUDES=
422422
POSITION_PROVIDER_EXCLUDES=
423423

424424
# Plugin configuration
425-
PLUGIN_API_KEY=lYkiYYT6owG+71oLerGzA7GXCgOT++6ovaezWAjpCjf+Sjc3ZtU+qUEi
426-
PLUGIN_API_URL=http://127.0.0.1:5002
425+
PLUGIN_DAEMON_KEY=lYkiYYT6owG+71oLerGzA7GXCgOT++6ovaezWAjpCjf+Sjc3ZtU+qUEi
427426
PLUGIN_DAEMON_URL=http://127.0.0.1:5002
428427
PLUGIN_REMOTE_INSTALL_PORT=5003
429428
PLUGIN_REMOTE_INSTALL_HOST=localhost
@@ -436,7 +435,7 @@ MARKETPLACE_ENABLED=true
436435
MARKETPLACE_API_URL=https://marketplace.dify.ai
437436

438437
# Endpoint configuration
439-
ENDPOINT_URL_TEMPLATE=http://localhost/e/{hook_id}
438+
ENDPOINT_URL_TEMPLATE=http://localhost:5002/e/{hook_id}
440439

441440
# Reset password token expiry minutes
442441
RESET_PASSWORD_TOKEN_EXPIRY_MINUTES=5

api/.ruff.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,12 @@ ignore = [
5353
"FURB152", # math-constant
5454
"UP007", # non-pep604-annotation
5555
"UP032", # f-string
56+
"UP045", # non-pep604-annotation-optional
5657
"B005", # strip-with-multi-characters
5758
"B006", # mutable-argument-default
5859
"B007", # unused-loop-control-variable
5960
"B026", # star-arg-unpacking-after-keyword-arg
61+
"B903", # class-as-data-structure
6062
"B904", # raise-without-from-inside-except
6163
"B905", # zip-without-explicit-strict
6264
"N806", # non-lowercase-variable-in-function

api/Dockerfile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ FROM python:3.12-slim-bookworm AS base
44
WORKDIR /app/api
55

66
# Install Poetry
7-
ENV POETRY_VERSION=1.8.4
7+
ENV POETRY_VERSION=2.0.1
88

99
# if you located in China, you can use aliyun mirror to speed up
1010
# RUN pip install --no-cache-dir poetry==${POETRY_VERSION} -i https://mirrors.aliyun.com/pypi/simple/
@@ -55,6 +55,7 @@ RUN apt-get update \
5555
&& echo "deb http://deb.debian.org/debian testing main" > /etc/apt/sources.list \
5656
&& apt-get update \
5757
# For Security
58+
# && apt-get install -y --no-install-recommends expat=2.6.4-1 libldap-2.5-0=2.5.19+dfsg-1 perl=5.40.0-8 libsqlite3-0=3.46.1-1 zlib1g=1:1.3.dfsg+really1.3.1-1+b1 \
5859
# install a chinese font to support the use of tools like matplotlib
5960
&& apt-get install -y fonts-noto-cjk \
6061
&& apt-get autoremove -y \

api/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,5 +79,5 @@
7979
2. Run the tests locally with mocked system environment variables in `tool.pytest_env` section in `pyproject.toml`
8080

8181
```bash
82-
poetry run -C api bash dev/pytest/pytest_all_tests.sh
82+
poetry run -P api bash dev/pytest/pytest_all_tests.sh
8383
```

api/configs/feature/__init__.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -141,10 +141,10 @@ class PluginConfig(BaseSettings):
141141

142142
PLUGIN_DAEMON_URL: HttpUrl = Field(
143143
description="Plugin API URL",
144-
default="http://plugin:5002",
144+
default="http://localhost:5002",
145145
)
146146

147-
PLUGIN_API_KEY: str = Field(
147+
PLUGIN_DAEMON_KEY: str = Field(
148148
description="Plugin API key",
149149
default="plugin-api-key",
150150
)
@@ -200,7 +200,7 @@ class EndpointConfig(BaseSettings):
200200
)
201201

202202
CONSOLE_WEB_URL: str = Field(
203-
description="Base URL for the console web interface," "used for frontend references and CORS configuration",
203+
description="Base URL for the console web interface,used for frontend references and CORS configuration",
204204
default="",
205205
)
206206

api/configs/feature/hosted_service/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ class HostedFetchAppTemplateConfig(BaseSettings):
181181
"""
182182

183183
HOSTED_FETCH_APP_TEMPLATES_MODE: str = Field(
184-
description="Mode for fetching app templates: remote, db, or builtin" " default to remote,",
184+
description="Mode for fetching app templates: remote, db, or builtin default to remote,",
185185
default="remote",
186186
)
187187

api/controllers/console/admin.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ def post(self):
5959
with Session(db.engine) as session:
6060
app = session.execute(select(App).filter(App.id == args["app_id"])).scalar_one_or_none()
6161
if not app:
62-
raise NotFound(f'App \'{args["app_id"]}\' is not found')
62+
raise NotFound(f"App '{args['app_id']}' is not found")
6363

6464
site = app.site
6565
if not site:

api/controllers/console/app/audio.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
from core.errors.error import ModelCurrentlyNotSupportError, ProviderTokenNotInitError, QuotaExceededError
2323
from core.model_runtime.errors.invoke import InvokeError
2424
from libs.login import login_required
25-
from models.model import AppMode
25+
from models import App, AppMode
2626
from services.audio_service import AudioService
2727
from services.errors.audio import (
2828
AudioTooLargeServiceError,
@@ -79,7 +79,7 @@ class ChatMessageTextApi(Resource):
7979
@login_required
8080
@account_initialization_required
8181
@get_app_model
82-
def post(self, app_model):
82+
def post(self, app_model: App):
8383
from werkzeug.exceptions import InternalServerError
8484

8585
try:
@@ -98,9 +98,13 @@ def post(self, app_model):
9898
and app_model.workflow.features_dict
9999
):
100100
text_to_speech = app_model.workflow.features_dict.get("text_to_speech")
101+
if text_to_speech is None:
102+
raise ValueError("TTS is not enabled")
101103
voice = args.get("voice") or text_to_speech.get("voice")
102104
else:
103105
try:
106+
if app_model.app_model_config is None:
107+
raise ValueError("AppModelConfig not found")
104108
voice = args.get("voice") or app_model.app_model_config.text_to_speech_dict.get("voice")
105109
except Exception:
106110
voice = None

api/controllers/console/datasets/data_source.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ def get(self):
135135
data_source_info = json.loads(document.data_source_info)
136136
exist_page_ids.append(data_source_info["notion_page_id"])
137137
# get all authorized pages
138-
data_source_bindings = session.execute(
138+
data_source_bindings = session.scalars(
139139
select(DataSourceOauthBinding).filter_by(
140140
tenant_id=current_user.current_tenant_id, provider="notion", disabled=False
141141
)

api/controllers/console/datasets/datasets.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -52,12 +52,12 @@ def get(self):
5252
# provider = request.args.get("provider", default="vendor")
5353
search = request.args.get("keyword", default=None, type=str)
5454
tag_ids = request.args.getlist("tag_ids")
55-
55+
include_all = request.args.get("include_all", default="false").lower() == "true"
5656
if ids:
5757
datasets, total = DatasetService.get_datasets_by_ids(ids, current_user.current_tenant_id)
5858
else:
5959
datasets, total = DatasetService.get_datasets(
60-
page, limit, current_user.current_tenant_id, current_user, search, tag_ids
60+
page, limit, current_user.current_tenant_id, current_user, search, tag_ids, include_all
6161
)
6262

6363
# check embedding setting
@@ -457,7 +457,7 @@ def post(self):
457457
)
458458
except LLMBadRequestError:
459459
raise ProviderNotInitializeError(
460-
"No Embedding Model available. Please configure a valid provider " "in the Settings -> Model Provider."
460+
"No Embedding Model available. Please configure a valid provider in the Settings -> Model Provider."
461461
)
462462
except ProviderTokenNotInitError as ex:
463463
raise ProviderNotInitializeError(ex.description)
@@ -619,8 +619,7 @@ def get(self):
619619
vector_type = dify_config.VECTOR_STORE
620620
match vector_type:
621621
case (
622-
VectorType.MILVUS
623-
| VectorType.RELYT
622+
VectorType.RELYT
624623
| VectorType.PGVECTOR
625624
| VectorType.TIDB_VECTOR
626625
| VectorType.CHROMA
@@ -645,6 +644,7 @@ def get(self):
645644
| VectorType.TIDB_ON_QDRANT
646645
| VectorType.LINDORM
647646
| VectorType.COUCHBASE
647+
| VectorType.MILVUS
648648
):
649649
return {
650650
"retrieval_method": [

api/controllers/console/datasets/datasets_document.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -362,8 +362,7 @@ def post(self):
362362
)
363363
except InvokeAuthorizationError:
364364
raise ProviderNotInitializeError(
365-
"No Embedding Model available. Please configure a valid provider "
366-
"in the Settings -> Model Provider."
365+
"No Embedding Model available. Please configure a valid provider in the Settings -> Model Provider."
367366
)
368367
except ProviderTokenNotInitError as ex:
369368
raise ProviderNotInitializeError(ex.description)
@@ -540,8 +539,7 @@ def get(self, dataset_id, batch):
540539
return response.model_dump(), 200
541540
except LLMBadRequestError:
542541
raise ProviderNotInitializeError(
543-
"No Embedding Model available. Please configure a valid provider "
544-
"in the Settings -> Model Provider."
542+
"No Embedding Model available. Please configure a valid provider in the Settings -> Model Provider."
545543
)
546544
except ProviderTokenNotInitError as ex:
547545
raise ProviderNotInitializeError(ex.description)

api/controllers/console/datasets/datasets_segments.py

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -168,8 +168,7 @@ def patch(self, dataset_id, document_id, action):
168168
)
169169
except LLMBadRequestError:
170170
raise ProviderNotInitializeError(
171-
"No Embedding Model available. Please configure a valid provider "
172-
"in the Settings -> Model Provider."
171+
"No Embedding Model available. Please configure a valid provider in the Settings -> Model Provider."
173172
)
174173
except ProviderTokenNotInitError as ex:
175174
raise ProviderNotInitializeError(ex.description)
@@ -217,8 +216,7 @@ def post(self, dataset_id, document_id):
217216
)
218217
except LLMBadRequestError:
219218
raise ProviderNotInitializeError(
220-
"No Embedding Model available. Please configure a valid provider "
221-
"in the Settings -> Model Provider."
219+
"No Embedding Model available. Please configure a valid provider in the Settings -> Model Provider."
222220
)
223221
except ProviderTokenNotInitError as ex:
224222
raise ProviderNotInitializeError(ex.description)
@@ -267,8 +265,7 @@ def patch(self, dataset_id, document_id, segment_id):
267265
)
268266
except LLMBadRequestError:
269267
raise ProviderNotInitializeError(
270-
"No Embedding Model available. Please configure a valid provider "
271-
"in the Settings -> Model Provider."
268+
"No Embedding Model available. Please configure a valid provider in the Settings -> Model Provider."
272269
)
273270
except ProviderTokenNotInitError as ex:
274271
raise ProviderNotInitializeError(ex.description)
@@ -368,9 +365,9 @@ def post(self, dataset_id, document_id):
368365
result = []
369366
for index, row in df.iterrows():
370367
if document.doc_form == "qa_model":
371-
data = {"content": row[0], "answer": row[1]}
368+
data = {"content": row.iloc[0], "answer": row.iloc[1]}
372369
else:
373-
data = {"content": row[0]}
370+
data = {"content": row.iloc[0]}
374371
result.append(data)
375372
if len(result) == 0:
376373
raise ValueError("The CSV file is empty.")
@@ -437,8 +434,7 @@ def post(self, dataset_id, document_id, segment_id):
437434
)
438435
except LLMBadRequestError:
439436
raise ProviderNotInitializeError(
440-
"No Embedding Model available. Please configure a valid provider "
441-
"in the Settings -> Model Provider."
437+
"No Embedding Model available. Please configure a valid provider in the Settings -> Model Provider."
442438
)
443439
except ProviderTokenNotInitError as ex:
444440
raise ProviderNotInitializeError(ex.description)

api/controllers/console/explore/conversation.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ def get(self, installed_app):
3232

3333
pinned = None
3434
if "pinned" in args and args["pinned"] is not None:
35-
pinned = True if args["pinned"] == "true" else False
35+
pinned = args["pinned"] == "true"
3636

3737
try:
3838
with Session(db.engine) as session:

api/controllers/inner_api/wraps.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ def decorated(*args, **kwargs):
6565
def plugin_inner_api_only(view):
6666
@wraps(view)
6767
def decorated(*args, **kwargs):
68-
if not dify_config.PLUGIN_API_KEY:
68+
if not dify_config.PLUGIN_DAEMON_KEY:
6969
abort(404)
7070

7171
# get header 'X-Inner-Api-Key'

api/controllers/service_api/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,4 @@
77

88
from . import index
99
from .app import app, audio, completion, conversation, file, message, workflow
10-
from .dataset import dataset, document, hit_testing, segment
10+
from .dataset import dataset, document, hit_testing, segment, upload_file

api/controllers/service_api/dataset/dataset.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,11 @@ def get(self, tenant_id):
3131
# provider = request.args.get("provider", default="vendor")
3232
search = request.args.get("keyword", default=None, type=str)
3333
tag_ids = request.args.getlist("tag_ids")
34+
include_all = request.args.get("include_all", default="false").lower() == "true"
3435

35-
datasets, total = DatasetService.get_datasets(page, limit, tenant_id, current_user, search, tag_ids)
36+
datasets, total = DatasetService.get_datasets(
37+
page, limit, tenant_id, current_user, search, tag_ids, include_all
38+
)
3639
# check embedding setting
3740
provider_manager = ProviderManager()
3841
configurations = provider_manager.get_configurations(tenant_id=current_user.current_tenant_id)

0 commit comments

Comments
 (0)