Skip to content

Commit 403e2d5

Browse files
YeuolytakatostkurokoboNovice Leezxhlyh
authored
Introduce Plugins (langgenius#13836)
Signed-off-by: yihong0618 <[email protected]> Signed-off-by: -LAN- <[email protected]> Signed-off-by: xhe <[email protected]> Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: takatost <[email protected]> Co-authored-by: kurokobo <[email protected]> Co-authored-by: Novice Lee <[email protected]> Co-authored-by: zxhlyh <[email protected]> Co-authored-by: AkaraChen <[email protected]> Co-authored-by: Yi <[email protected]> Co-authored-by: Joel <[email protected]> Co-authored-by: JzoNg <[email protected]> Co-authored-by: twwu <[email protected]> Co-authored-by: Hiroshi Fujita <[email protected]> Co-authored-by: AkaraChen <[email protected]> Co-authored-by: NFish <[email protected]> Co-authored-by: Wu Tianwei <[email protected]> Co-authored-by: 非法操作 <[email protected]> Co-authored-by: Novice <[email protected]> Co-authored-by: Hiroki Nagai <[email protected]> Co-authored-by: Gen Sato <[email protected]> Co-authored-by: eux <[email protected]> Co-authored-by: huangzhuo1949 <[email protected]> Co-authored-by: huangzhuo <[email protected]> Co-authored-by: lotsik <[email protected]> Co-authored-by: crazywoola <[email protected]> Co-authored-by: nite-knite <[email protected]> Co-authored-by: Jyong <[email protected]> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: gakkiyomi <[email protected]> Co-authored-by: CN-P5 <[email protected]> Co-authored-by: CN-P5 <[email protected]> Co-authored-by: Chuehnone <[email protected]> Co-authored-by: yihong <[email protected]> Co-authored-by: Kevin9703 <[email protected]> Co-authored-by: -LAN- <[email protected]> Co-authored-by: Boris Feld <[email protected]> Co-authored-by: mbo <[email protected]> Co-authored-by: mabo <[email protected]> Co-authored-by: Warren Chen <[email protected]> Co-authored-by: JzoNgKVO <[email protected]> Co-authored-by: jiandanfeng <[email protected]> Co-authored-by: zhu-an <[email protected]> Co-authored-by: zhaoqingyu.1075 <[email protected]> Co-authored-by: 海狸大師 <[email protected]> Co-authored-by: Xu Song <[email protected]> Co-authored-by: rayshaw001 <[email protected]> Co-authored-by: Ding Jiatong <[email protected]> Co-authored-by: Bowen Liang <[email protected]> Co-authored-by: JasonVV <[email protected]> Co-authored-by: le0zh <[email protected]> Co-authored-by: zhuxinliang <[email protected]> Co-authored-by: k-zaku <[email protected]> Co-authored-by: luckylhb90 <[email protected]> Co-authored-by: hobo.l <[email protected]> Co-authored-by: jiangbo721 <[email protected]> Co-authored-by: 刘江波 <[email protected]> Co-authored-by: Shun Miyazawa <[email protected]> Co-authored-by: EricPan <[email protected]> Co-authored-by: crazywoola <[email protected]> Co-authored-by: sino <[email protected]> Co-authored-by: Jhvcc <[email protected]> Co-authored-by: lowell <[email protected]> Co-authored-by: Boris Polonsky <[email protected]> Co-authored-by: Ademílson Tonato <[email protected]> Co-authored-by: Ademílson Tonato <[email protected]> Co-authored-by: IWAI, Masaharu <[email protected]> Co-authored-by: Yueh-Po Peng (Yabi) <[email protected]> Co-authored-by: Jason <[email protected]> Co-authored-by: Xin Zhang <[email protected]> Co-authored-by: yjc980121 <[email protected]> Co-authored-by: heyszt <[email protected]> Co-authored-by: Abdullah AlOsaimi <[email protected]> Co-authored-by: Abdullah AlOsaimi <[email protected]> Co-authored-by: Yingchun Lai <[email protected]> Co-authored-by: Hash Brown <[email protected]> Co-authored-by: zuodongxu <[email protected]> Co-authored-by: Masashi Tomooka <[email protected]> Co-authored-by: aplio <[email protected]> Co-authored-by: Obada Khalili <[email protected]> Co-authored-by: Nam Vu <[email protected]> Co-authored-by: Kei YAMAZAKI <[email protected]> Co-authored-by: TechnoHouse <[email protected]> Co-authored-by: Riddhimaan-Senapati <[email protected]> Co-authored-by: MaFee921 <[email protected]> Co-authored-by: te-chan <[email protected]> Co-authored-by: HQidea <[email protected]> Co-authored-by: Joshbly <[email protected]> Co-authored-by: xhe <[email protected]> Co-authored-by: weiwenyan-dev <[email protected]> Co-authored-by: ex_wenyan.wei <[email protected]> Co-authored-by: engchina <[email protected]> Co-authored-by: engchina <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: 呆萌闷油瓶 <[email protected]> Co-authored-by: Kemal <[email protected]> Co-authored-by: Lazy_Frog <[email protected]> Co-authored-by: Yi Xiao <[email protected]> Co-authored-by: Steven sun <[email protected]> Co-authored-by: steven <[email protected]> Co-authored-by: Kalo Chin <[email protected]> Co-authored-by: Katy Tao <[email protected]> Co-authored-by: depy <[email protected]> Co-authored-by: 胡春东 <[email protected]> Co-authored-by: Junjie.M <[email protected]> Co-authored-by: MuYu <[email protected]> Co-authored-by: Naoki Takashima <[email protected]> Co-authored-by: Summer-Gu <[email protected]> Co-authored-by: Fei He <[email protected]> Co-authored-by: ybalbert001 <[email protected]> Co-authored-by: Yuanbo Li <[email protected]> Co-authored-by: douxc <[email protected]> Co-authored-by: liuzhenghua <[email protected]> Co-authored-by: Wu Jiayang <[email protected]> Co-authored-by: Your Name <[email protected]> Co-authored-by: kimjion <[email protected]> Co-authored-by: AugNSo <[email protected]> Co-authored-by: llinvokerl <[email protected]> Co-authored-by: liusurong.lsr <[email protected]> Co-authored-by: Vasu Negi <[email protected]> Co-authored-by: Hundredwz <[email protected]> Co-authored-by: Xiyuan Chen <[email protected]>
1 parent 222df44 commit 403e2d5

File tree

3,292 files changed

+68478
-283733
lines changed

Some content is hidden

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

3,292 files changed

+68478
-283733
lines changed

.devcontainer/post_create_command.sh

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
#!/bin/bash
22

3-
cd web && npm install
3+
4+
cd web && pnpm install
45
pipx install poetry
56

67
echo 'alias start-api="cd /workspaces/dify/api && poetry run python -m flask run --host 0.0.0.0 --port=5001 --debug"' >> ~/.bashrc
78
echo 'alias start-worker="cd /workspaces/dify/api && poetry run python -m celery -A app.celery worker -P gevent -c 1 --loglevel INFO -Q dataset,generation,mail,ops_trace,app_deletion"' >> ~/.bashrc
8-
echo 'alias start-web="cd /workspaces/dify/web && npm run dev"' >> ~/.bashrc
9+
echo 'alias start-web="cd /workspaces/dify/web && pnpm dev"' >> ~/.bashrc
910
echo 'alias start-containers="cd /workspaces/dify/docker && docker-compose -f docker-compose.middleware.yaml -p dify up -d"' >> ~/.bashrc
1011
echo 'alias stop-containers="cd /workspaces/dify/docker && docker-compose -f docker-compose.middleware.yaml -p dify down"' >> ~/.bashrc
1112

.github/workflows/api-tests.yml

-6
Original file line numberDiff line numberDiff line change
@@ -50,15 +50,9 @@ jobs:
5050
- name: Run Unit tests
5151
run: poetry run -P api bash dev/pytest/pytest_unit_tests.sh
5252

53-
- name: Run ModelRuntime
54-
run: poetry run -P api bash dev/pytest/pytest_model_runtime.sh
55-
5653
- name: Run dify config tests
5754
run: poetry run -P api python dev/pytest/pytest_config_tests.py
5855

59-
- name: Run Tool
60-
run: poetry run -P api bash dev/pytest/pytest_tools.sh
61-
6256
- name: Run mypy
6357
run: |
6458
poetry run -C api python -m mypy --install-types --non-interactive .

.github/workflows/db-migration-test.yml

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ on:
44
pull_request:
55
branches:
66
- main
7+
- plugins/beta
78
paths:
89
- api/migrations/**
910
- .github/workflows/db-migration-test.yml

.github/workflows/style.yml

+8-2
Original file line numberDiff line numberDiff line change
@@ -72,17 +72,23 @@ jobs:
7272
with:
7373
files: web/**
7474

75+
- name: Install pnpm
76+
uses: pnpm/action-setup@v4
77+
with:
78+
version: 10
79+
run_install: false
80+
7581
- name: Setup NodeJS
7682
uses: actions/setup-node@v4
7783
if: steps.changed-files.outputs.any_changed == 'true'
7884
with:
7985
node-version: 20
80-
cache: yarn
86+
cache: pnpm
8187
cache-dependency-path: ./web/package.json
8288

8389
- name: Web dependencies
8490
if: steps.changed-files.outputs.any_changed == 'true'
85-
run: yarn install --frozen-lockfile
91+
run: pnpm install --frozen-lockfile
8692

8793
- name: Web style check
8894
if: steps.changed-files.outputs.any_changed == 'true'

.github/workflows/tool-test-sdks.yaml

+3-3
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,10 @@ jobs:
3535
with:
3636
node-version: ${{ matrix.node-version }}
3737
cache: ''
38-
cache-dependency-path: 'yarn.lock'
38+
cache-dependency-path: 'pnpm-lock.yaml'
3939

4040
- name: Install Dependencies
41-
run: yarn install
41+
run: pnpm install
4242

4343
- name: Test
44-
run: yarn test
44+
run: pnpm test

.github/workflows/translate-i18n-base-on-english.yml

+2-2
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,11 @@ jobs:
3939

4040
- name: Install dependencies
4141
if: env.FILES_CHANGED == 'true'
42-
run: yarn install --frozen-lockfile
42+
run: pnpm install --frozen-lockfile
4343

4444
- name: Run npm script
4545
if: env.FILES_CHANGED == 'true'
46-
run: npm run auto-gen-i18n
46+
run: pnpm run auto-gen-i18n
4747

4848
- name: Create Pull Request
4949
if: env.FILES_CHANGED == 'true'

.github/workflows/web-tests.yml

+3-3
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,13 @@ jobs:
3737
if: steps.changed-files.outputs.any_changed == 'true'
3838
with:
3939
node-version: 20
40-
cache: yarn
40+
cache: pnpm
4141
cache-dependency-path: ./web/package.json
4242

4343
- name: Install dependencies
4444
if: steps.changed-files.outputs.any_changed == 'true'
45-
run: yarn install --frozen-lockfile
45+
run: pnpm install --frozen-lockfile
4646

4747
- name: Run tests
4848
if: steps.changed-files.outputs.any_changed == 'true'
49-
run: yarn test
49+
run: pnpm test

.gitignore

+7
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,7 @@ docker/volumes/pgvector/data/*
176176
docker/volumes/pgvecto_rs/data/*
177177
docker/volumes/couchbase/*
178178
docker/volumes/oceanbase/*
179+
docker/volumes/plugin_daemon/*
179180
!docker/volumes/oceanbase/init.d
180181

181182
docker/nginx/conf.d/default.conf
@@ -194,3 +195,9 @@ api/.vscode
194195

195196
.idea/
196197
.vscode
198+
199+
# pnpm
200+
/.pnpm-store
201+
202+
# plugin migrate
203+
plugins.jsonl

api/.dockerignore

+5
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,19 @@
11
.env
22
*.env.*
33

4+
storage/generate_files/*
45
storage/privkeys/*
6+
storage/tools/*
7+
storage/upload_files/*
58

69
# Logs
710
logs
811
*.log*
912

1013
# jetbrains
1114
.idea
15+
.mypy_cache
16+
.ruff_cache
1217

1318
# venv
1419
.venv

api/.env.example

+16-1
Original file line numberDiff line numberDiff line change
@@ -409,7 +409,6 @@ MAX_VARIABLE_SIZE=204800
409409
APP_MAX_EXECUTION_TIME=1200
410410
APP_MAX_ACTIVE_REQUESTS=0
411411

412-
413412
# Celery beat configuration
414413
CELERY_BEAT_SCHEDULER_TIME=1
415414

@@ -422,6 +421,22 @@ POSITION_PROVIDER_PINS=
422421
POSITION_PROVIDER_INCLUDES=
423422
POSITION_PROVIDER_EXCLUDES=
424423

424+
# Plugin configuration
425+
PLUGIN_DAEMON_KEY=lYkiYYT6owG+71oLerGzA7GXCgOT++6ovaezWAjpCjf+Sjc3ZtU+qUEi
426+
PLUGIN_DAEMON_URL=http://127.0.0.1:5002
427+
PLUGIN_REMOTE_INSTALL_PORT=5003
428+
PLUGIN_REMOTE_INSTALL_HOST=localhost
429+
PLUGIN_MAX_PACKAGE_SIZE=15728640
430+
INNER_API_KEY=QaHbTe77CtuXmsfyhR7+vRjI/+XbV1AaFy691iy+kGDv2Jvy0/eAh8Y1
431+
INNER_API_KEY_FOR_PLUGIN=QaHbTe77CtuXmsfyhR7+vRjI/+XbV1AaFy691iy+kGDv2Jvy0/eAh8Y1
432+
433+
# Marketplace configuration
434+
MARKETPLACE_ENABLED=true
435+
MARKETPLACE_API_URL=https://marketplace.dify.ai
436+
437+
# Endpoint configuration
438+
ENDPOINT_URL_TEMPLATE=http://localhost:5002/e/{hook_id}
439+
425440
# Reset password token expiry minutes
426441
RESET_PASSWORD_TOKEN_EXPIRY_MINUTES=5
427442

api/Dockerfile

+4
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,10 @@ ENV PATH="${VIRTUAL_ENV}/bin:${PATH}"
7373
# Download nltk data
7474
RUN python -c "import nltk; nltk.download('punkt'); nltk.download('averaged_perceptron_tagger')"
7575

76+
ENV TIKTOKEN_CACHE_DIR=/app/api/.tiktoken_cache
77+
78+
RUN python -c "import tiktoken; tiktoken.encoding_for_model('gpt2')"
79+
7680
# Copy source code
7781
COPY . /app/api/
7882

api/commands.py

+70-3
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
from models.model import Account, App, AppAnnotationSetting, AppMode, Conversation, MessageAnnotation
2626
from models.provider import Provider, ProviderModel
2727
from services.account_service import RegisterService, TenantService
28+
from services.plugin.data_migration import PluginDataMigration
29+
from services.plugin.plugin_migration import PluginMigration
2830

2931

3032
@click.command("reset-password", help="Reset the account password.")
@@ -524,7 +526,7 @@ def add_qdrant_doc_id_index(field: str):
524526
)
525527
)
526528

527-
except Exception as e:
529+
except Exception:
528530
click.echo(click.style("Failed to create Qdrant client.", fg="red"))
529531

530532
click.echo(click.style(f"Index creation complete. Created {create_count} collection indexes.", fg="green"))
@@ -593,7 +595,7 @@ def upgrade_db():
593595

594596
click.echo(click.style("Database migration successful!", fg="green"))
595597

596-
except Exception as e:
598+
except Exception:
597599
logging.exception("Failed to execute database migration")
598600
finally:
599601
lock.release()
@@ -639,7 +641,7 @@ def fix_app_site_missing():
639641
account = accounts[0]
640642
print("Fixing missing site for app {}".format(app.id))
641643
app_was_created.send(app, account=account)
642-
except Exception as e:
644+
except Exception:
643645
failed_app_ids.append(app_id)
644646
click.echo(click.style("Failed to fix missing site for app {}".format(app_id), fg="red"))
645647
logging.exception(f"Failed to fix app related site missing issue, app_id: {app_id}")
@@ -649,3 +651,68 @@ def fix_app_site_missing():
649651
break
650652

651653
click.echo(click.style("Fix for missing app-related sites completed successfully!", fg="green"))
654+
655+
656+
@click.command("migrate-data-for-plugin", help="Migrate data for plugin.")
657+
def migrate_data_for_plugin():
658+
"""
659+
Migrate data for plugin.
660+
"""
661+
click.echo(click.style("Starting migrate data for plugin.", fg="white"))
662+
663+
PluginDataMigration.migrate()
664+
665+
click.echo(click.style("Migrate data for plugin completed.", fg="green"))
666+
667+
668+
@click.command("extract-plugins", help="Extract plugins.")
669+
@click.option("--output_file", prompt=True, help="The file to store the extracted plugins.", default="plugins.jsonl")
670+
@click.option("--workers", prompt=True, help="The number of workers to extract plugins.", default=10)
671+
def extract_plugins(output_file: str, workers: int):
672+
"""
673+
Extract plugins.
674+
"""
675+
click.echo(click.style("Starting extract plugins.", fg="white"))
676+
677+
PluginMigration.extract_plugins(output_file, workers)
678+
679+
click.echo(click.style("Extract plugins completed.", fg="green"))
680+
681+
682+
@click.command("extract-unique-identifiers", help="Extract unique identifiers.")
683+
@click.option(
684+
"--output_file",
685+
prompt=True,
686+
help="The file to store the extracted unique identifiers.",
687+
default="unique_identifiers.json",
688+
)
689+
@click.option(
690+
"--input_file", prompt=True, help="The file to store the extracted unique identifiers.", default="plugins.jsonl"
691+
)
692+
def extract_unique_plugins(output_file: str, input_file: str):
693+
"""
694+
Extract unique plugins.
695+
"""
696+
click.echo(click.style("Starting extract unique plugins.", fg="white"))
697+
698+
PluginMigration.extract_unique_plugins_to_file(input_file, output_file)
699+
700+
click.echo(click.style("Extract unique plugins completed.", fg="green"))
701+
702+
703+
@click.command("install-plugins", help="Install plugins.")
704+
@click.option(
705+
"--input_file", prompt=True, help="The file to store the extracted unique identifiers.", default="plugins.jsonl"
706+
)
707+
@click.option(
708+
"--output_file", prompt=True, help="The file to store the installed plugins.", default="installed_plugins.jsonl"
709+
)
710+
def install_plugins(input_file: str, output_file: str):
711+
"""
712+
Install plugins.
713+
"""
714+
click.echo(click.style("Starting install plugins.", fg="white"))
715+
716+
PluginMigration.install_plugins(input_file, output_file)
717+
718+
click.echo(click.style("Install plugins completed.", fg="green"))

api/configs/feature/__init__.py

+60
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,60 @@ class CodeExecutionSandboxConfig(BaseSettings):
134134
)
135135

136136

137+
class PluginConfig(BaseSettings):
138+
"""
139+
Plugin configs
140+
"""
141+
142+
PLUGIN_DAEMON_URL: HttpUrl = Field(
143+
description="Plugin API URL",
144+
default="http://localhost:5002",
145+
)
146+
147+
PLUGIN_DAEMON_KEY: str = Field(
148+
description="Plugin API key",
149+
default="plugin-api-key",
150+
)
151+
152+
INNER_API_KEY_FOR_PLUGIN: str = Field(description="Inner api key for plugin", default="inner-api-key")
153+
154+
PLUGIN_REMOTE_INSTALL_HOST: str = Field(
155+
description="Plugin Remote Install Host",
156+
default="localhost",
157+
)
158+
159+
PLUGIN_REMOTE_INSTALL_PORT: PositiveInt = Field(
160+
description="Plugin Remote Install Port",
161+
default=5003,
162+
)
163+
164+
PLUGIN_MAX_PACKAGE_SIZE: PositiveInt = Field(
165+
description="Maximum allowed size for plugin packages in bytes",
166+
default=15728640,
167+
)
168+
169+
PLUGIN_MAX_BUNDLE_SIZE: PositiveInt = Field(
170+
description="Maximum allowed size for plugin bundles in bytes",
171+
default=15728640 * 12,
172+
)
173+
174+
175+
class MarketplaceConfig(BaseSettings):
176+
"""
177+
Configuration for marketplace
178+
"""
179+
180+
MARKETPLACE_ENABLED: bool = Field(
181+
description="Enable or disable marketplace",
182+
default=True,
183+
)
184+
185+
MARKETPLACE_API_URL: HttpUrl = Field(
186+
description="Marketplace API URL",
187+
default="https://marketplace.dify.ai",
188+
)
189+
190+
137191
class EndpointConfig(BaseSettings):
138192
"""
139193
Configuration for various application endpoints and URLs
@@ -160,6 +214,10 @@ class EndpointConfig(BaseSettings):
160214
default="",
161215
)
162216

217+
ENDPOINT_URL_TEMPLATE: str = Field(
218+
description="Template url for endpoint plugin", default="http://localhost:5002/e/{hook_id}"
219+
)
220+
163221

164222
class FileAccessConfig(BaseSettings):
165223
"""
@@ -793,6 +851,8 @@ class FeatureConfig(
793851
AuthConfig, # Changed from OAuthConfig to AuthConfig
794852
BillingConfig,
795853
CodeExecutionSandboxConfig,
854+
PluginConfig,
855+
MarketplaceConfig,
796856
DataSetConfig,
797857
EndpointConfig,
798858
FileAccessConfig,

api/configs/packaging/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ class PackagingInfo(BaseSettings):
99

1010
CURRENT_VERSION: str = Field(
1111
description="Dify version",
12-
default="0.15.3",
12+
default="1.0.0",
1313
)
1414

1515
COMMIT_SHA: str = Field(

0 commit comments

Comments
 (0)