Compare commits

...

2561 Commits

Author SHA1 Message Date
Asuka Minato
070cd79c39 test: use real plugin runtime objects 2026-10-07 00:10:53 +09:00
Codex
1d912fee41 test: specify marketplace response payload types 2026-10-07 00:07:16 +09:00
Asuka Minato
e92ffbdf50 test: use real marketplace and Nacos responses 2026-10-07 00:07:16 +09:00
huhupy
519ef8b8c2 fix(web): share query-core in vinext development (#43269) 2026-10-06 14:04:30 +00:00
Lucien
0cd3824608 fix(nodejs-client): avoid retrying write requests after transport failures (#43079) 2026-10-06 14:03:35 +00:00
Lucien
869c1dbf07 fix(php-sdk): send conversation renames to the name endpoint (#43075) 2026-10-06 13:57:09 +00:00
lin-hongkuan
2738bad1fe fix(api): keep workflow log cleanup in one transaction (#37897)
Co-authored-by: Byron Wang <byron@dify.ai>
2026-10-06 13:34:26 +00:00
dependabot[bot]
a4cefbe669 chore(deps): bump the storage group in /api with 4 updates (#43500)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-10-06 13:21:03 +00:00
dependabot[bot]
1f5afb5a48 chore(deps): bump pypdf from 6.16.1 to 6.19.0 in /dify-agent (#43463)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-10-06 13:18:50 +00:00
dependabot[bot]
9d285e38eb chore(deps): bump pypdf from 6.16.1 to 6.19.0 in /api (#43464)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-10-06 13:17:42 +00:00
dependabot[bot]
9ce90a4075 chore(deps): bump the google group in /api with 2 updates (#43495)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-10-06 13:17:23 +00:00
Asuka Minato
a5eea69efc test: construct configured SQLAlchemy repositories (#43384) 2026-10-06 12:31:31 +00:00
Asuka Minato
8260acf04b test: use real model configuration entities (#43383) 2026-10-06 12:31:30 +00:00
Asuka Minato
5ea0b59bdd test: exercise real agent model assembly (#43382) 2026-10-06 12:31:29 +00:00
Asuka Minato
0753e6480b test: use real Watercrawl and Jina responses (#43381) 2026-10-06 12:31:28 +00:00
Asuka Minato
1aeba1c6bc test: use concrete agent resource task boundaries (#43380) 2026-10-06 11:54:07 +00:00
Asuka Minato
642bfe40eb test: use real app describe fixtures (#43379) 2026-10-06 11:54:06 +00:00
Asuka Minato
10c5da16f3 test: use real firecrawl auth responses (#43378) 2026-10-06 11:54:05 +00:00
Asuka Minato
3b093f881f test: use concrete notion import adapters (#43377)
Co-authored-by: Codex <codex@openai.com>
2026-10-06 11:54:03 +00:00
Eddy ZHANG
a212b1b0b1 refactor(api): enable strict typing for Firecrawl extractor tests (#43599) 2026-10-06 09:25:12 +00:00
Byron.wang
8023189566 fix: use caller session for Qdrant annotation bindings (#43543) 2026-10-06 07:58:58 +00:00
Eddy ZHANG
d73c93d2cf refactor(api): enable strict typing for CSV sanitizer tests (#43598) 2026-10-06 06:09:48 +00:00
非法操作
63d2af7d27 refactor(api): use project HTTP errors in Explore controllers (#43481)
Co-authored-by: Byron.wang <byron@dify.ai>
2026-10-05 15:23:32 +00:00
KenXiong
81f627cfa1 refactor(api): decouple console API-based extension management (#43340)
Co-authored-by: !潤弘資訊熊冠詠 <RT025232@rtc.ruentex.corp>
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-05 15:04:09 +00:00
Asuka Minato
e160419159 test: use real data source auth gateways (#43376) 2026-10-05 14:21:54 +00:00
Asuka Minato
22cce965f3 test: use real web passport gateways (#43375) 2026-10-05 14:21:53 +00:00
Asuka Minato
ea9a3dbb4b test: use real workflow file runtime boundaries (#43374) 2026-10-05 14:21:52 +00:00
Asuka Minato
fd99ce64c9 test: use concrete archive adapter boundaries (#43373) 2026-10-05 14:21:51 +00:00
Asuka Minato
64f028564e test: use concrete parent context boundaries (#43372)
Co-authored-by: Codex <codex@openai.com>
2026-10-05 14:21:50 +00:00
Asuka Minato
4214abf28f test: use concrete agent account boundaries (#43371) 2026-10-05 14:21:49 +00:00
Asuka Minato
f4027ad6ef test: use concrete workflow tool recorders (#43370) 2026-10-05 14:21:48 +00:00
Asuka Minato
9d01361c91 test: use real tool variable pools and encryption (#43368) 2026-10-05 14:21:47 +00:00
Asuka Minato
7d13952e24 test: use real tool runtime callbacks (#43367) 2026-10-05 14:21:46 +00:00
Eddy ZHANG
54486a14c1 refactor(api): enable strict typing for dataset docstore tests (#43511) 2026-10-05 09:13:41 +00:00
Eddy ZHANG
3be01cbb7a refactor(api): enable strict typing for website crawl controller tests (#43507) 2026-10-05 06:29:18 +00:00
Eddy ZHANG
de09a17ba9 refactor(api): enable strict typing for RAG pipeline wraps tests (#43501) 2026-10-05 03:06:18 +00:00
dependabot[bot]
cf957564d8 chore(deps): bump the github-actions-dependencies group with 2 updates (#43493)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-10-05 03:05:36 +00:00
dependabot[bot]
5c0c9dfff0 chore(deps): bump opentelemetry-propagator-b3 from 1.44.0 to 1.45.0 in /api in the opentelemetry group (#43497)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-10-05 01:39:10 +00:00
Eddy ZHANG
e92d13220f refactor(api): enable strict typing for service API hit testing tests (#43485) 2026-10-05 00:30:13 +00:00
Asuka Minato
70ef9cbd5d test: use real dataset tool callbacks and sessions (#43366) 2026-10-04 11:38:25 +00:00
Asuka Minato
f0266537cb test: use real tool model and encryption fixtures (#43365) 2026-10-04 11:38:24 +00:00
Asuka Minato
16bbfc50bd test: use real HTTP responses and plugin tool clients (#43364) 2026-10-04 11:38:23 +00:00
Asuka Minato
1cbb6dc385 test: guard spec-based mock constructors with ast-grep (#43232)
Co-authored-by: Codex <codex@openai.com>
2026-10-03 15:44:24 +00:00
Asuka Minato
09e372b237 test: use real object storage SDK responses (#43231) 2026-10-03 15:44:24 +00:00
Asuka Minato
c687d0dc6f test: exercise collaboration leader and session storage (#43230) 2026-10-03 15:44:23 +00:00
Asuka Minato
8222397ea9 test: use real collaboration visibility state (#43229) 2026-10-03 10:12:10 +00:00
Asuka Minato
01f632d059 test: use real collaboration request state (#43228) 2026-10-03 10:12:10 +00:00
Asuka Minato
98c9a6a23a test: use real human input stream dependencies (#43227) 2026-10-03 10:12:09 +00:00
Asuka Minato
c12c01b8be test: persist human input event forms in SQLite (#43226) 2026-10-03 10:12:08 +00:00
Asuka Minato
7f4e357418 test: use real email registration adapters (#43225)
Co-authored-by: Codex <codex@openai.com>
2026-10-03 10:12:07 +00:00
Asuka Minato
43af5082d3 test: use real account change email adapters (#43224) 2026-10-03 03:16:11 +00:00
Asuka Minato
f2755a79c7 test: use real account services in controller fixtures (#43223) 2026-10-03 03:16:10 +00:00
Asuka Minato
e6e4cd9406 test: use concrete integration execution fixtures (#43222) 2026-10-03 03:16:09 +00:00
Asuka Minato
b7bf3f8a29 test: use real rerank model instances (#43221) 2026-10-03 03:16:09 +00:00
Asuka Minato
0f611811c2 test: use real pipeline and retriever fixtures (#43220) 2026-10-03 01:51:56 +00:00
Stream
efcf73b4da fix(test): reset shared Redis mock method history (#43437) 2026-10-03 01:13:46 +00:00
Stream
daadf78c02 test(account): strengthen Redis command assertions (#43436) 2026-10-03 01:12:58 +00:00
-LAN-
baf6888007 test(api): stabilize shared fixtures and type-check scopes (#42801) 2026-10-02 23:48:13 +00:00
-LAN-
4b89972f55 fix(redis): reject subscription close signals when receiving (#42799) 2026-10-02 18:50:56 +00:00
Chengmian Liu
a2427050e1 fix(api): survive DST transitions when computing the next cron run (#43357) 2026-10-02 18:08:31 +00:00
Asuka Minato
f3074ced5b test: use real statistic query repositories (#43219) 2026-10-02 13:53:39 +00:00
Asuka Minato
1dbf027277 test: use real account activation adapters (#43218) 2026-10-02 13:53:38 +00:00
Asuka Minato
9f0e3a4c17 test: use real account deletion adapters (#43217) 2026-10-02 13:53:37 +00:00
Asuka Minato
a54589a672 test: compose real datasource credential repositories (#43216) 2026-10-02 13:53:36 +00:00
Asuka Minato
ba28e3ad82 test: use real stream subscriptions for workflow dispatch (#43213) 2026-10-02 13:53:35 +00:00
Asuka Minato
49a4a13846 test: exercise real file uploads and web app icon queries (#43212) 2026-10-02 13:53:33 +00:00
Asuka Minato
934427ce16 test: use concrete knowledge node adapters and source records (#43211) 2026-10-02 13:53:32 +00:00
Asuka Minato
f100adf0ea test: use concrete workflow composition dependencies (#43210) 2026-10-02 13:53:31 +00:00
kr1shna-exe
63094c91ba refactor(api): enable strict typing for migration tests (#43347) 2026-10-02 13:12:13 +00:00
kr1shna-exe
9f617f9d3f refactor(api): enable strict typing for agent controller tests (#43342) 2026-10-02 13:07:45 +00:00
KenXiong
30eadcc9e5 refactor(api): adopt with_session in audio controllers (#37403) (#43322)
Co-authored-by: !潤弘資訊熊冠詠 <RT025232@rtc.ruentex.corp>
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-02 13:03:06 +00:00
Asuka Minato
bf62165e22 test: use real plugin upload ownership and storage adapters (#43209) 2026-10-02 12:21:08 +00:00
Asuka Minato
c797b8e99e test: deliver real uploaded and tool files from local storage (#43208) 2026-10-02 12:21:07 +00:00
Asuka Minato
fa4f49df00 test: construct real repositories and Redis composition fixtures (#43207) 2026-10-02 12:21:06 +00:00
Asuka Minato
6cca398f1c test: use real repositories for human input node fixtures (#43206) 2026-10-02 12:21:05 +00:00
Asuka Minato
b4ae43986c test: persist human input forms across graph pause and resume (#43205) 2026-10-02 12:21:04 +00:00
Asuka Minato
c05a1c4e9a test: persist real human input forms in callback tests (#43204) 2026-10-02 11:59:33 +00:00
Asuka Minato
84cc8ef77a test: use persisted message files and local preview storage (#43203) 2026-10-02 11:59:32 +00:00
Asuka Minato
f2e13873b5 test: use concrete model instances in LLM utility tests (#43202) 2026-10-02 11:59:31 +00:00
Asuka Minato
a0c004d877 test: exercise onboarding retries with real database sessions (#43200) 2026-10-02 11:59:30 +00:00
Asuka Minato
14cd89ded5 test: persist account initialization and avatar ownership fixtures (#43199) 2026-10-02 11:59:29 +00:00
Asuka Minato
8055521b49 test: exercise real compliance and deletion rate limiters (#43198) 2026-10-02 11:03:16 +00:00
Asuka Minato
aff59ef19a test: use real LLM provider dependencies and recording file saver (#43197) 2026-10-02 11:03:05 +00:00
Asuka Minato
f93bec4ea5 test: use concrete LLM execution dependencies (#43195) 2026-10-02 11:03:04 +00:00
Asuka Minato
087dd1d1ae test: construct real dependencies for graph test nodes (#43194) 2026-10-02 11:03:03 +00:00
Asuka Minato
1b86126ab1 test: use real Redis clients in catalog fixtures (#43193) 2026-10-02 11:03:03 +00:00
yyh
ca27376211 fix(agent): preserve prompt copy confirmation (#43327) 2026-10-02 05:46:37 +00:00
Asuka Minato
c0fa5c3bcd test: use real tool file adapters (#43192) 2026-10-02 05:28:46 +00:00
Asuka Minato
46f32a7d22 test: replace session specs with real sessions (#43190) 2026-10-02 05:28:45 +00:00
Asuka Minato
5c6f46c952 test: use real model results and workflow execution values (#43189) 2026-10-02 05:28:44 +00:00
Asuka Minato
e23c02340a test: exercise tenant indexing queue serialization (#43188) 2026-10-02 05:28:44 +00:00
Asuka Minato
b3188a299b test: use persisted account query fixtures (#43187) 2026-10-02 05:28:43 +00:00
Asuka Minato
570552c6fa test: use real account education adapters (#43184) 2026-10-02 02:54:24 +00:00
Asuka Minato
636e0f0ace test: persist account password and profile fixtures (#43183) 2026-10-02 02:54:23 +00:00
Asuka Minato
fecc3af674 test: use concrete LLM memory and file fixtures (#43182) 2026-10-02 02:54:22 +00:00
Asuka Minato
0b9b0db408 test: use real node variable pools and lifecycle events (#43179) 2026-10-02 02:54:21 +00:00
Asuka Minato
a2b0b2a143 test: exercise real website request conversion (#43178) 2026-10-02 02:54:20 +00:00
Asuka Minato
0fa381f3e7 test: use validated workflow invocation entities (#43176) 2026-10-02 02:54:19 +00:00
Asuka Minato
d28b99ef6d test: use real generation events and trace managers (#43175) 2026-10-02 02:54:18 +00:00
Asuka Minato
38f1ecdd3b test: construct real LLM generation dependencies (#43174) 2026-10-02 02:54:17 +00:00
Asuka Minato
a0330a756f test: use real workflow state and command channels (#43173) 2026-10-02 02:54:17 +00:00
Asuka Minato
723aeb8b10 test: use real agent runtime dependencies (#43171) 2026-10-02 02:54:16 +00:00
Asuka Minato
cba5e5503a test: replace tool transformation spec mocks with concrete fixtures (#43170) 2026-10-02 02:54:15 +00:00
Asuka Minato
4c640ff898 test: exercise account Redis command serialization (#43169) 2026-10-02 02:14:14 +00:00
yyh
0bd950fd01 fix(ui): align menu semantics and focus behavior (#43325) 2026-10-01 15:22:26 +00:00
dependabot[bot]
f004f6b67d chore(deps): bump pyjwt from 2.14.0 to 2.15.0 in /api (#43318)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-10-01 10:27:08 +00:00
dependabot[bot]
50695cbf92 chore(deps): bump litellm from 1.89.3 to 1.89.7 in /api (#43317)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-10-01 10:26:41 +00:00
dependabot[bot]
23e13a5e93 chore(deps): bump urllib3 from 2.7.0 to 2.8.0 in /api (#43316)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-10-01 10:25:51 +00:00
Asuka Minato
6423a83b78 test: use real Redis clients for tokens tasks and setup locks (#43168)
Co-authored-by: Byron Wang <byron@dify.ai>
2026-10-01 09:57:56 +00:00
dependabot[bot]
4534c37aa7 chore(deps): bump urllib3 from 2.7.0 to 2.8.0 in /dify-agent (#43314)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-10-01 09:55:12 +00:00
yyh
431c185706 fix(web): upgrade Next.js to 16.3.8 for September security fixes (#43320) 2026-10-01 03:25:06 +00:00
yyh
5260f0eee6 refactor(web): move monitoring date range picker to app components (#43295) 2026-10-01 03:23:40 +00:00
wangxiaolei
9fa987a550 fix: fix migrate permission not exclude admin and owner (#43311) 2026-10-01 02:04:16 +00:00
Asuka Minato
1beefc2b50 test: use real upload streams and document values (#43167) 2026-10-01 02:02:02 +00:00
yyh
1a918ea407 fix(dify-ui): use default cursor for form labels (#43287) 2026-09-30 16:11:44 +00:00
yyh
fac6179309 fix(workflow): restore compact node panel title alignment (#43286) 2026-09-30 16:11:16 +00:00
yyh
3c17c90bea fix(ui): expose slider values and unify class name resolution (#43293) 2026-09-30 16:10:57 +00:00
Chiranjeevi Balawat
5e3065ec7d refactor(api): remove redundant casts and enable strict type checks for bundle archive maintenance tests (#43270)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 09:12:24 +00:00
Joel
71e5b353b1 chore(web): improve pricing plans accessibility (SNP-885) (#43279) 2026-09-30 08:48:05 +00:00
Joel
9988dcc720 chore(web): improve agent monitoring accessibility (SNP-897) (#43274)
Co-authored-by: Byron.wang <byron@dify.ai>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-09-30 07:27:40 +00:00
Byron.wang
95373bc4fd refactor(api): consolidate account modules and shared errors (#42570)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-09-30 07:26:44 +00:00
Byron.wang
6decc78fd5 refactor(api): move web authentication into application services (#41318)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-09-30 06:47:17 +00:00
yyh
bf41e733ba fix(workflow): preserve inline agent dialog during suspense (#43273) 2026-09-30 06:33:59 +00:00
yyh
d7600ad9a7 fix(app): preserve sidebar header layout while loading (#43271) 2026-09-30 06:32:30 +00:00
Asuka Minato
52d586a7b4 test: use SQLite repository for human input uploads (#43166) 2026-09-30 06:21:03 +00:00
Asuka Minato
4433d56a88 test: exercise human input submissions with SQLite repository (#43165) 2026-09-30 06:21:02 +00:00
Asuka Minato
db317bf9a1 test: use real HTTP clients and creator responses (#43164) 2026-09-30 06:21:01 +00:00
Asuka Minato
1642281176 test: exercise real telemetry queues and trace managers (#43162) 2026-09-30 06:21:01 +00:00
Asuka Minato
8edc40e2f1 test: use real moderation configuration and queues (#43161) 2026-09-30 06:18:22 +00:00
Asuka Minato
fe49d123c0 test: use real schema namespaces and registries (#43160) 2026-09-30 06:18:21 +00:00
Asuka Minato
5ab572e0a7 test: use real MCP auth and session fixtures (#43159) 2026-09-30 06:18:21 +00:00
Asuka Minato
2cb6431582 test: use real prompt model and memory fixtures (#43158) 2026-09-30 06:17:54 +00:00
yyh
e48680f32b fix(ui): compose drawer close controls with IconButton (#43267) 2026-09-30 06:06:37 +00:00
yyh
a743a9150f refactor(app): move sidebar details to the route query (#43264) 2026-09-30 06:04:54 +00:00
yyh
2f6b14525e fix(workflow): isolate run records while preserving selected tabs (#43263) 2026-09-30 04:35:56 +00:00
yyh
df016cd309 refactor(logs): pass app identity into log inspectors (#43261) 2026-09-30 04:35:56 +00:00
yyh
d5c3fb9ecd refactor(logs): scope page data and replay to the owning app (#43260) 2026-09-30 04:35:55 +00:00
yyh
0effc36f45 refactor(access-config): scope app permissions to the page query (#43259) 2026-09-30 04:35:54 +00:00
yyh
28697d9587 refactor(overview): read app detail from the route query (#43258) 2026-09-30 04:35:54 +00:00
Asuka Minato
ea38e484b8 test: use real document extractor file fixtures (#43156) 2026-09-30 03:44:01 +00:00
Asuka Minato
5bae0bb010 test: use real MCP request and transport fixtures (#43155) 2026-09-30 03:44:00 +00:00
Asuka Minato
51fa4a25f9 test: use real structured output model fixtures (#43154) 2026-09-30 03:43:59 +00:00
Joel
b4cb02ccb9 fix: make OAuth client info card span form width (#43256) 2026-09-30 03:36:07 +00:00
Sourav Rajvi
77ec1b2027 chore(deps): bump c12 to 4.0.0-rc.2 (#43103) 2026-09-30 03:01:48 +00:00
dependabot[bot]
68726eb097 chore(deps): bump pyjwt from 2.13.0 to 2.14.0 in /api (#43254)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-30 02:59:22 +00:00
Asuka Minato
b4dd2c4886 test: use real Easy UI stream fixtures (#43153) 2026-09-30 02:56:54 +00:00
Joel
cf02d52d0d fix(e2e): align Agent v2 workflow access link locator (#43255) 2026-09-30 02:32:54 +00:00
Xiyuan Chen
a4524c215f feat(cli): difyctl v2 over the server catalog (#42608)
Co-authored-by: yunlu.wen <yunlu.wen@dify.ai>
2026-09-30 01:58:58 +00:00
yyh
96abb8ea22 fix(dify-ui): make native form story locators locale-independent (#43250) 2026-09-30 01:03:29 +00:00
Joel
216151ffa7 chore: address Access Point accessibility issues (#43196)
Co-authored-by: yyh <92089059+lyzno1@users.noreply.github.com>
2026-09-29 14:29:54 +00:00
Stephen Zhou
7b0660b45b docs: refresh project guides and fix generated API tables (#43239) 2026-09-29 13:53:30 +00:00
yyh
a4f949f173 test(web): wait for command palette focus before pasting (#43236) 2026-09-29 12:24:09 +00:00
yyh
0ed392fb62 chore(dify-ui): align authoring rules and dependency optimization (#43233) 2026-09-29 11:58:49 +00:00
Joel
3f0032f20b chore(web): address WCAG A/AA issues on agent logs page (SNP-896) (#43215) 2026-09-29 10:28:23 +00:00
Coding On Star
bfd5636bf0 fix(web): hide installed plugins from workflow marketplace selectors (#43191)
Co-authored-by: CodingOnStar <hanxujiang@dify.com>
2026-09-29 10:18:11 +00:00
Taranum Wasu
f79ed842fa fix(web): render a message in OAuth callback without opener (#43053)
Co-authored-by: Taranum01 <taranumwasu@users.noreply.github.com>
Co-authored-by: Taranum01 <taranum01@users.noreply.github.com>
2026-09-29 10:02:45 +00:00
Byron.wang
a67cd87eb0 refactor(api): establish dataset application boundaries (#41729)
Co-authored-by: Jyong <jyong@dify.ai>
2026-09-29 08:42:31 +00:00
Joel
c005932db9 chore(web): address Agent Configure WCAG issues (SNP-894) (#43172) 2026-09-29 08:36:34 +00:00
Stephen Zhou
af7f6abb95 perf(api): disable unused SDK pytest plugins (#43125) 2026-09-29 07:47:43 +00:00
Aniket Kumar
2a1211baa5 test: pin ZIP timestamp in roster archive helper (#43122) 2026-09-29 07:28:43 +00:00
Stephen Zhou
3813c4d552 perf(api): reuse auth matrix routes and batch test data setup (#43128) 2026-09-29 07:26:31 +00:00
yyh
8fc8178ff7 fix(web): align Agent template avatar and translations (#43163) 2026-09-29 07:26:28 +00:00
Asuka Minato
fb0e55f5e7 test: replace plugin model client spec mocks with a recording fake (#43152) 2026-09-29 07:08:49 +00:00
Asuka Minato
fb9b97b26d test: use a real Phoenix tracer and in-memory exporter (#43151) 2026-09-29 07:08:48 +00:00
Asuka Minato
80b34b5ab6 test: use real trace records and SDK span values (#43150) 2026-09-29 07:08:47 +00:00
Asuka Minato
8db1712ccd test: construct real datasource plugin and message fixtures (#43149) 2026-09-29 07:08:46 +00:00
Asuka Minato
6dc9de24d8 test: use real datasource provider fixtures (#43148) 2026-09-29 07:08:45 +00:00
Asuka Minato
9c11e36cc5 test: use real app models in integration fixtures (#43147) 2026-09-29 07:08:44 +00:00
Asuka Minato
1d02154638 test: validate real document configuration entities (#43145) 2026-09-29 07:08:44 +00:00
Asuka Minato
b4bc25cab6 test: compose application services with real Redis wrappers (#43144) 2026-09-29 07:08:43 +00:00
Asuka Minato
948fd166dd test: use real tool runtimes responses and plugin entities (#43142) 2026-09-29 07:08:42 +00:00
Asuka Minato
38f42f357e test: replace agent and upload ORM spec mocks with real models (#43141) 2026-09-29 07:08:41 +00:00
Stephen Zhou
f24586323b perf(api): avoid numbered temporary directories for test databases (#43127) 2026-09-29 06:56:39 +00:00
Denis Ermakov
bc0279572e fix(web): surface SSO login request failures to the user (#43076)
Co-authored-by: SquabbyZ <43177939+SquabbyZ@users.noreply.github.com>
2026-09-29 06:52:02 +00:00
Joel
20d9f15933 chore(web): improve agents roster accessibility (SNP-893) (#43140) 2026-09-29 06:40:29 +00:00
yyh
d42276a5c0 refactor(goto-anything): simplify command context and execution (#43136) 2026-09-29 06:37:41 +00:00
yyh
5c4489911c feat(goto-anything): improve command discovery and keyboard navigation (#43133) 2026-09-29 06:37:40 +00:00
Lucien
657624154d fix(web): preserve dataset uploads after returning to source step (#43080) 2026-09-29 05:50:16 +00:00
Stephen Zhou
be8744264f perf(api): reuse controller OpenAPI documents in schema tests (#43120) 2026-09-29 03:28:43 +00:00
Wu Tianwei
0fec636da5 fix(web): protect workspace admins in resource access (#43118) 2026-09-29 03:07:15 +00:00
Stephen Zhou
ce27ef9dc3 ci: reduce main CI orchestration scheduling overhead (#43114) 2026-09-29 03:05:39 +00:00
Stephen Zhou
f7e5946d81 ci: overlap core E2E startup with web build preparation (#43116) 2026-09-29 02:54:26 +00:00
yyh
90f7fbd468 feat(ui): redesign date and time pickers (#43090) 2026-09-29 02:14:10 +00:00
Harsh Kashyap
1545517fe8 ci(test): gate new session-mock assignments in api unit tests (#42854)
Co-authored-by: Harsh Kashyap <Harsh23Kashyap@users.noreply.github.com>
Co-authored-by: Harsh Kashyap <harsh@harshkashyap.dev>
2026-09-29 02:11:45 +00:00
KUNAL KAKDE
1b9ddf9ae5 docs(api): align audio-to-text supported formats in service-openapi (#41891)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-09-29 02:09:09 +00:00
Denis Ermakov
9bb9935f44 refactor(models): remove implicit-session Account tenant setters (#43064) 2026-09-29 02:03:34 +00:00
Denis Ermakov
1ff3d3db68 refactor(console): dep-inject the activation payload with @model_validate (#43056) 2026-09-29 02:01:34 +00:00
Denis Ermakov
18fea7ff0d chore(api): remove redundant str() on StringUUID ids (#43061) 2026-09-29 02:00:16 +00:00
Stephen Zhou
357f697b16 chore(web): upgrade vinext and Vite+ to 1.0.0 (#43110) 2026-09-29 01:53:48 +00:00
杨俊波
e6f1d77ed5 feat: tool fallback observability (#42596)
Co-authored-by: liuns-yang <liuns-yang@users.noreply.github.com>
Co-authored-by: Crazywoola <100913391+crazywoola@users.noreply.github.com>
2026-09-28 11:10:48 +00:00
Yunlu Wen
4f8bf32b72 feat: support host style in archive s3 client (#43066) 2026-09-28 11:06:38 +00:00
invalid w
d8187b6e51 chore(web): resolve eslint error for node/panel components in CustomNode renderer (#42470) 2026-09-28 09:58:53 +00:00
Stephen Zhou
51940eac9c perf(web): lazy-load SVG code block previews (#42951) 2026-09-28 09:26:33 +00:00
林玮 (Jade Lin)
005f019a80 feat: support New Agent templates and trials (#42837)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: yyh <yuanyouhuilyz@gmail.com>
Co-authored-by: yyh <92089059+lyzno1@users.noreply.github.com>
2026-09-28 09:21:50 +00:00
Stephen Zhou
5f6bb5e6d3 perf(workflow): lazy load node configuration panels (#42970) 2026-09-28 09:07:08 +00:00
Joel
7020120197 chore: improve Custom Endpoint accessibility (SNP-876) (#43060) 2026-09-28 08:59:34 +00:00
Harsh Kashyap
fe5dfd756f fix(web): skip shiki WASM engine load for plain-text fences (#42957)
Co-authored-by: Harsh Kashyap <harsh@harshkashyap.dev>
Co-authored-by: Stephen Zhou <38493346+hyoban@users.noreply.github.com>
2026-09-28 08:54:54 +00:00
Stephen Zhou
4808976d0c fix(web): reset frontend session after logout (#43055) 2026-09-28 08:17:49 +00:00
Joel
1b21b8220d chore(web): focus node panel on keyboard open (SNP-877) (#43047) 2026-09-28 07:52:39 +00:00
Denis Ermakov
bf55d1f6a6 refactor: pass db.session explicitly to instruction_modify_legacy (#37403) (#43045) 2026-09-28 07:38:08 +00:00
Keith
855842410a refactor(models): remove implicit-session AppModelConfig.annotation_reply_dict (#43024) 2026-09-28 07:36:44 +00:00
huhupy
33b2f09325 fix(web): correct knowledge document information fields (#42885) 2026-09-28 07:32:51 +00:00
非法操作
4713c3853b refactor(api): bound suggested question runtime sessions (#42968) 2026-09-28 07:31:24 +00:00
非法操作
89e6b71b2d refactor(api): migrate console suggested questions to shared runtime (#43033) 2026-09-28 07:31:17 +00:00
平衡世界的BOY
27cdf50c7d fix(web): improve snippet run panel accessibility (#43028) 2026-09-28 07:00:30 +00:00
Joel
2b88685fbd chore: improve a11y of trigger integration, agent strategy and extension page (#43023) 2026-09-28 06:41:17 +00:00
yyh
52dcf83de6 refactor(web): scope app UI sessions to their owners (#42984) 2026-09-28 06:39:19 +00:00
yyh
a4a18e0652 refactor(web): separate AppIcon display from picker triggers (#43041) 2026-09-28 06:34:04 +00:00
林玮 (Jade Lin)
6441436b0c feat(api): include Site settings in App DSL (#42863) 2026-09-28 06:17:44 +00:00
Byron.wang
0c5f2507d0 refactor(api): separate app MCP server service and persistence (#42850) 2026-09-28 06:03:58 +00:00
qielanci
2515cf5b48 fix(api): use plain Session in MCP controller to avoid closed transactionFix/mcp plain session (#43038) 2026-09-28 05:44:11 +00:00
Stephen Zhou
5283462286 chore(deps): update compatible workspace dependencies (#43031) 2026-09-28 04:37:37 +00:00
yyh
f95edc85f5 refactor(web): consume generated app detail contracts (#42982) 2026-09-28 04:35:06 +00:00
Stephen Zhou
f3107fee3f fix(tooling): resolve standalone TypeScript checks (#43029) 2026-09-28 03:36:07 +00:00
yyh
c42ee2fbac refactor(api): align app model config write contract (#42979) 2026-09-28 03:22:37 +00:00
Stephen Zhou
fc5053edf0 chore(web): upgrade vinext and align Vite+ configuration (#43021) 2026-09-28 03:04:45 +00:00
Taranum Wasu
d8ec14027e fix(api): mark async workflow trigger log FAILED when dispatch raises (#42148) (#43009)
Co-authored-by: Taranum01 <taranum01@users.noreply.github.com>
2026-09-28 02:57:05 +00:00
非法操作
96f444e3c6 refactor(api): separate history queries from prompt rendering (#42967) 2026-09-28 02:51:58 +00:00
非法操作
9d4629c946 refactor(api): share installed app suggested questions runtime (#42933) 2026-09-28 02:51:38 +00:00
Stephen Zhou
11f6a350f1 fix(tooling): align Vite+ configuration and upgrade toolchain (#43019) 2026-09-28 02:32:25 +00:00
huoex1222-hub
1366cadbb4 fix(api): report batch count as the progress denominator in Vector (#43005)
Co-authored-by: huoenxi <15811355218@139.com>
2026-09-28 02:29:58 +00:00
henrydev23
174a908786 chore(api): remove unnecessary str calls in openapi controllers (#42931) 2026-09-28 02:17:48 +00:00
dependabot[bot]
2062d5e892 chore(deps-dev): bump the dev group in /api with 7 updates (#43017)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-28 02:13:04 +00:00
非法操作
fb7b00365c refactor(api): separate suggested question model preparation and invocation (#42966) 2026-09-28 02:07:36 +00:00
非法操作
1c535791cb refactor(api): use HTTPStatus throughout Explore controllers (#42891) 2026-09-28 02:07:12 +00:00
dependabot[bot]
090f7d923c chore(deps): bump the github-actions-dependencies group with 3 updates (#43013)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-28 02:07:08 +00:00
非法操作
3dce05e09e refactor(api): group installed and trial app services (#42878) 2026-09-28 02:07:02 +00:00
jeongeun
a154a4d674 refactor(api): inject TextToSpeechVoiceQuery into agent TTS voices via the decorator (#43006)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 01:54:28 +00:00
ly303550688
934662cc48 fix(api): resolve ob_vector_memory_limit_percentage by index (#42846)
Co-authored-by: yangl <303550688@qq.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-09-28 01:52:22 +00:00
Keith
b470071c4c chore: remove mypy from backend type checks (#42917) 2026-09-28 01:52:05 +00:00
yyh
d6c96ce1a5 refactor(web): redesign icon picker and clarify autocomplete highlighting (#43007) 2026-09-28 01:35:36 +00:00
Taranum Wasu
60744157d8 fix(api): fall back to tool name when MCP tool title is null (#42453) (#43010)
Co-authored-by: Taranum01 <taranum01@users.noreply.github.com>
2026-09-28 01:35:22 +00:00
dependabot[bot]
43f64090e1 chore(deps): bump the storage group across 1 directory with 4 updates (#42813)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-28 01:29:39 +00:00
dependabot[bot]
12f65f887a chore(deps): bump google-cloud-aiplatform from 2.1.3 to 2.2.0 in /api in the google group (#43012)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-28 01:27:11 +00:00
Sourav Rajvi
725611b2e9 test: drop redundant created_at/updated_at in unit tests (#42989) (#42990) 2026-09-26 18:10:34 +00:00
destire-mio
e6fa1a1dd0 refactor(models): pass session into Conversation.app (#42975)
Co-authored-by: destire-mio <248462155+destire-mio@users.noreply.github.com>
2026-09-26 17:29:35 +00:00
yyh
414cce2f70 refactor(web): align hotkeys with command ownership (#42974) 2026-09-26 12:37:36 +00:00
Stefan Yoshovski
7a7dc6011a fix(agent-v2): use icon_url for image avatars in the configure preview (#42977)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: yyh <yuanyouhuilyz@gmail.com>
2026-09-26 12:36:08 +00:00
Bruce-Yii
3960b57102 fix(web): resolve pdf worker url under the configured base path (#42956)
Co-authored-by: Bruce-Yii <298228875+Bruce-Yii@users.noreply.github.com>
2026-09-26 05:32:07 +00:00
yyh
698ecd3e62 refactor(dify-ui): narrow checkbox public API (#42953) 2026-09-26 04:52:26 +00:00
yyh
f4602cc1fe refactor(web): refine detail sidebar states and preview (#42938) 2026-09-25 15:46:20 +00:00
yyh
2d813b2a87 fix(web): preserve detail sidebar state during SSR (#42936) 2026-09-25 15:46:19 +00:00
Andy yang
d86435ee1e fix(workflow): coerce non-uuid variable ids and warn on skipped branches (#42750)
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Crazywoola <100913391+crazywoola@users.noreply.github.com>
2026-09-25 08:16:41 +00:00
chenbd123
f6a1878ceb fix(api): improve Vastbase vector store with Graph_Index and BM25 full-text (#42922)
Co-authored-by: chenbd123 <188698064+chenbd123@users.noreply.github.com>
2026-09-25 16:13:50 +08:00
haochen
e5b5a1cc4c fix(mail): preserve send results when SMTP cleanup fails (#42903)
Co-authored-by: Zhangchenhao-111 <285911435+Zhangchenhao-111@users.noreply.github.com>
2026-09-25 02:34:20 +00:00
Mitsunao Miyamoto
6824611958 docs(ja-JP): fix grammar and mistranslations in Japanese README (#42895) 2026-09-25 02:30:57 +00:00
Mitsunao Miyamoto
672d2e2bb7 fix(i18n): fix typos and untranslated strings in Japanese translations (#42893) 2026-09-25 02:30:42 +00:00
林玮 (Jade Lin)
0755abe47f fix(agent): allow package imports with missing plugins (#42913) 2026-09-25 02:30:27 +00:00
zyileven
50589420b1 fix(web): preserve model context when adding load-balancing credentials (#42910) 2026-09-25 02:28:51 +00:00
gn
90e590e48d chore(api): remove unnecessary str() calls in controllers/openapi/workspaces (#42932) 2026-09-25 02:09:31 +00:00
yyh
a7f890129e fix(web): isolate home template cards beneath sticky header (#42906) 2026-09-24 11:54:41 +00:00
Joel
18e0cb102b fix(web): improve data source integrations accessibility (SNP-872) (#42911) 2026-09-24 09:47:16 +00:00
yyh
7ee0f6af7e refactor(web): remove synthetic app detail SSO field (#42888) 2026-09-24 09:06:19 +00:00
yyh
54c2928734 refactor(web): scope app info modal state to its view (#42882) 2026-09-24 08:53:50 +00:00
yyh
ef33df5e22 refactor(api): tighten app detail response schema (#42876) 2026-09-24 08:53:49 +00:00
Yunlu Wen
edf1a57b7b refactor: move rbac enable check to check_dataset_permission (#42907)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-09-24 08:41:12 +00:00
Joel
4c2f022bb2 fix(web): improve a11y of tool integrations (#42898) 2026-09-24 07:59:07 +00:00
Stephen Zhou
bba6aad652 perf(web): streamline vinext i18n build analysis (#42902) 2026-09-24 07:53:42 +00:00
github-actions[bot]
0e4ecfa890 chore(i18n): sync translations with en-US (#42890)
Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Co-authored-by: yyh <92089059+lyzno1@users.noreply.github.com>
2026-09-24 07:20:07 +00:00
Asuka Minato
a405b00a3f test: run workflow archiver coverage on SQLite (#40718) 2026-09-24 07:18:13 +00:00
yyh
a1622aea28 fix(i18n): pin sync source and link originating PR (#42896) 2026-09-24 07:12:56 +00:00
Joel
102497957d fix(web): improve model provider accessibility (#42866) 2026-09-24 06:59:59 +00:00
呆萌闷油瓶
74af4f2308 perf(api): reduce knowledge retrieval latency (#42673) 2026-09-24 06:50:36 +00:00
Stephen Zhou
989ba1a78f perf(web): isolate roster upload and generation translations (#42879) 2026-09-24 06:28:48 +00:00
Byron.wang
635143cb88 refactor(api): thin console app controllers and separate application boundaries (#42671)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-09-24 06:17:38 +00:00
Stephen Zhou
24c6815889 perf(web): split workflow translations by rendering boundary (#42877) 2026-09-24 04:24:20 +00:00
Stephen Zhou
ddb9f1ba8c perf(web): split shared translation namespaces by feature (#42874) 2026-09-24 04:24:20 +00:00
Stephen Zhou
b9f1ddaff4 perf(web): avoid implicit i18n namespace loading (#42873) 2026-09-24 04:24:19 +00:00
Asuka Minato
97c0aaa005 test: remove duplicate node output integration coverage (#40717) 2026-09-24 03:37:45 +00:00
Asuka Minato
98b7e92191 test: run draft variable coverage on SQLite (#40716) 2026-09-24 03:37:25 +00:00
yyh
8778c6b985 fix(web): close agent slash menu on immediate focus exit (#42867) 2026-09-24 03:35:59 +00:00
yyh
b7d4cbf00f fix(deps): upgrade cron-parser to 5.7.0 (#42865) 2026-09-24 03:12:34 +00:00
Joel
570317ecde fix(web): hide divider-only Markdown content (#42860) 2026-09-24 03:08:38 +00:00
非法操作
bd08f6b0e3 refactor(api): migrate installed app audio to shared runtime (#42056) 2026-09-24 02:56:38 +00:00
Stephen Zhou
8785f45e93 chore(deps): enable automatic pnpm deduplication (#42862) 2026-09-24 02:49:56 +00:00
落尘
5df8a4c89c fix(api): close failed SSE connection before MCP fallback (#42761) 2026-09-24 02:44:23 +00:00
Stephen Zhou
8300811b8c perf(web): replace runtime pinyin with provider initials lookup (#42861) 2026-09-24 02:32:05 +00:00
Stephen Zhou
28ed561740 ci(web): highlight Vinext bundle size changes (#42858) 2026-09-24 02:04:37 +00:00
非法操作
ff27ef544e refactor(web): migrate account name and avatar updates to profile API (#42843) 2026-09-24 02:02:50 +00:00
Stephen Zhou
7feebe3405 fix(web): defer Amplitude SDK loading until analytics consent (#42857) 2026-09-24 01:48:27 +00:00
Stephen Zhou
2f9fa672d0 ci(web): skip bundle comments for minor size changes (#42856) 2026-09-24 01:28:45 +00:00
非法操作
70e973b9ab refactor(api): isolate installed app messages (#42016) 2026-09-24 01:08:56 +00:00
Nehal kanak kuniyil thottathil
580a4165f2 refactor(api): inject InstalledAppsListQuery via the decorator (#42769)
Co-authored-by: Asuka Minato <i@asukaminato.eu.org>
2026-09-23 20:21:11 +00:00
Dorian
7cc0898f58 refactor(models): pass session into Conversation.to_dict and Message.to_dict (#42834)
Co-authored-by: Dorian <dorian0326@users.noreply.github.com>
2026-09-23 19:47:44 +00:00
Stephen Zhou
e43ea0986e ci(web): report Vinext bundles using Rolldown analysis (#42849) 2026-09-23 14:06:57 +00:00
Stephen Zhou
e9550e50d0 fix(web): reduce chart and syntax highlighting bundles (#42845) 2026-09-23 12:32:31 +00:00
Sourav Rajvi
200da319f2 refactor(web): defer tldts load for MCP favicon URL blur (#42486) 2026-09-23 11:48:40 +00:00
非法操作
4144850837 refactor(api): use route decorators in trial controller (#42815) 2026-09-23 11:47:53 +00:00
Stephen Zhou
d3d3248e3b fix(web): lazy-load markdown chart and music renderers (#42840) 2026-09-23 11:32:00 +00:00
Weike Zhang
f832cff60c fix(api): keep creator access to datasets created via console upload and RAG pipeline (#42507)
Co-authored-by: weike-zhang <wangweike@gmail.com>
Co-authored-by: Crazywoola <100913391+crazywoola@users.noreply.github.com>
2026-09-23 11:27:54 +00:00
非法操作
53aa73e416 refactor(api): isolate installed app conversations (#41971) 2026-09-23 11:11:33 +00:00
Stephen Zhou
16100f839f fix(web): preserve i18n translation type safety (#42839) 2026-09-23 11:04:16 +00:00
Joel
67c0157d00 fix(web): improve dataset document segment accessibility (#42833)
Co-authored-by: yyh <yuanyouhuilyz@gmail.com>
Co-authored-by: yyh <92089059+lyzno1@users.noreply.github.com>
2026-09-23 10:56:41 +00:00
Stephen Zhou
eb7235f17c refactor(web): generate type-safe i18n resources (#42835) 2026-09-23 10:25:38 +00:00
yyh
5f66253fab fix(explore): improve template preview states and accessibility (#42830) 2026-09-23 09:57:19 +00:00
zyileven
699489b95f fix(web): localize workflow statuses across logs and run details (#42699)
Co-authored-by: XiaoBa Yu <xb1823725853@gmail.com>
2026-09-23 09:34:51 +00:00
非法操作
d1391c2ed5 refactor(api): isolate installed app management (#41957) 2026-09-23 09:24:22 +00:00
Joel
518bd238f5 fix: improve document list accessibility (#42826) 2026-09-23 09:22:34 +00:00
XiaoBa
f6561d8cc0 fix(api): enforce dataset operation permissions (#42758) 2026-09-23 09:03:16 +00:00
Taranum Wasu
486bcb0b08 fix(tools): translate PluginNotFoundError to ToolProviderNotFoundError (#41837)
Co-authored-by: Taranum01 <taranumwasu@users.noreply.github.com>
2026-09-23 08:59:58 +00:00
yyh
236b90a90c fix(home): search templates by name and description (#42828) 2026-09-23 08:57:02 +00:00
林玮 (Jade Lin)
6f636b2f49 fix(api): resolve provider credential aliases (#42790) 2026-09-23 08:53:03 +00:00
林玮 (Jade Lin)
11883543d1 fix(api): include node plugins in DSL dependencies (#42816) 2026-09-23 08:53:02 +00:00
Byron.wang
8b7f903cff refactor(api): centralize API key management (#42489)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-09-23 08:38:48 +00:00
yyh
1a09485013 chore(deps): upgrade shadcn lint and cn (#42818) 2026-09-23 08:35:55 +00:00
Wu Tianwei
efac2084e1 fix(workflow): sync imported graph with collaboration state (#42817) 2026-09-23 08:31:05 +00:00
Stephen Zhou
7f4a5c2413 refactor(web): load and stream translation namespaces on demand (#42812) 2026-09-23 08:30:08 +00:00
非法操作
f0078b7935 refactor(api): migrate installed app workflow and task control (#41912) 2026-09-23 08:25:37 +00:00
Joel
14d8eecea6 fix: improve dataset settings accessibility (#42796) 2026-09-23 08:19:22 +00:00
非法操作
bc94f7ead5 refactor(api): migrate installed app chat generation (#41905) 2026-09-23 08:01:39 +00:00
Neo1Noir
0a428a52e6 fix(web): remove a Code node output variable once the removal is confirmed (#42678) 2026-09-23 07:52:25 +00:00
非法操作
3bf5f2c47e refactor(api): isolate installed app completion generation (#41894) 2026-09-23 07:38:37 +00:00
Byron.wang
584b62adc5 fix(test): return inserted primary keys from add_texts (#41037) 2026-09-23 07:34:04 +00:00
LII
286ee05711 test: sync Redis subscriptions before publishing in test_topic_isolation (#42674)
Co-authored-by: GyberExperiment <themacroeconomicdao@tuta.io>
Co-authored-by: -LAN- <laipz8200@outlook.com>
2026-09-23 07:20:45 +00:00
-LAN-
3113343c4d refactor(rag): remove unused splitter tokenization (#42804) 2026-09-23 07:20:39 +00:00
-LAN-
1d76929d5a test(api): remove duplicate and implementation-only coverage (#42803) 2026-09-23 07:18:02 +00:00
dependabot[bot]
401490c033 chore(deps-dev): bump the dev group in /api with 15 updates (#42616)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: -LAN- <laipz8200@outlook.com>
2026-09-23 07:13:17 +00:00
Wu Tianwei
2fa4c57026 fix(web): gray preview-only agent cards (#42809) 2026-09-23 07:06:10 +00:00
Joel
79e962d664 fix: improve retrieval testing accessibility (#42785) 2026-09-23 07:04:49 +00:00
非法操作
9daff34bb5 refactor(api): migrate explore task stop admission (#41874) 2026-09-23 06:53:44 +00:00
yyh
4af693ccef fix(agent): initialize model in new agent snapshot (#42781) 2026-09-23 06:51:40 +00:00
Byron.wang
16d3302bff refactor(api): isolate OAuth device flow orchestration (#41361) 2026-09-23 06:36:48 +00:00
yyh
792d154608 refactor(web): remove redundant root locale fallback (#42791) 2026-09-23 06:11:43 +00:00
yyh
d08f554ff4 fix(app): align package import and export feedback (#42732) 2026-09-23 06:11:21 +00:00
Xin Zhang
e11a20ace4 fix: handle missing optional tracing dependencies (#42724) 2026-09-23 05:58:01 +00:00
yyh
1aafa481f3 test(e2e): align Agent v2 publish scenarios with guidance (#42787) 2026-09-23 05:35:43 +00:00
yyh
9c210ea670 fix(web): keep copy tooltip visible after click (#42789) 2026-09-23 05:35:28 +00:00
非法操作
0c36f4a104 refactor(api): remove legacy Baichuan prompt handling (#42779) 2026-09-23 05:12:46 +00:00
Stephen Zhou
5f899e428a fix(web): declare translation namespace dependencies (#42784) 2026-09-23 04:43:00 +00:00
yyh
232f29c355 chore: migrate workspace to Vitest 5 (#42782) 2026-09-23 04:13:42 +00:00
平衡世界的BOY
1bbb604d32 fix(web): make human input button style selector accessible (#42747) 2026-09-23 03:42:22 +00:00
Joel
960bea8bae fix(web): initialize empty agent models from workspace defaults (#42736) 2026-09-23 02:51:25 +00:00
Samuel K Quansah
654a49d1bc fix(otel): fix typo Convertions -> conventions in ext_otel resource comment (#42771) 2026-09-23 10:51:22 +08:00
非法操作
75ba8d1dc4 refactor(api): isolate installed app admission for saved messages and parameters (#41872) 2026-09-23 02:33:34 +00:00
yyh
d566192843 fix(web): upgrade Next.js to 16.3.6 for CVE-2026-94545 (#42772) 2026-09-23 02:22:15 +00:00
非法操作
c592610ed3 refactor: isolate saved message persistence (#41857) 2026-09-23 02:05:01 +00:00
Fatih Farhat Asshidiq
2480e5a274 docs: add Indonesian translation of README (docs/id-ID/README.md) (#42768)
Signed-off-by: imanecdoche <kazokuhairy@gmail.com>
2026-09-23 09:46:33 +08:00
yetuge
f547ef8726 docs(api): align node execution repository docstrings with signatures (#42763) 2026-09-23 09:41:49 +08:00
yetuge
639d410108 docs(tasks): align trigger task docstrings with signatures (#42765) 2026-09-23 09:41:39 +08:00
yyh
c9e59a5590 fix(web): use concise accessible names for infotips (#42751)
Co-authored-by: zhsama <torvalds@linux.do>
2026-09-23 01:02:21 +00:00
盐粒 Yanli
0f6a6227f5 feat(agent): add output routes to Agent v2 (#42599)
Co-authored-by: zhsama <torvalds@linux.do>
2026-09-22 21:28:07 +00:00
xuan
a068c47ea9 refactor: pass db.session explicitly to get_message_data (#37403) (#42753) 2026-09-22 15:22:41 +00:00
Miku_Tog
bacf0c761f refactor(api): pass active session to from_db in ApiToolManageService… (#42602) 2026-09-22 15:10:11 +00:00
Stephen Zhou
3a017e8ccc perf(ci): reuse coverage XML totals for API summary (#42745) 2026-09-22 11:31:21 +00:00
Stephen Zhou
1fc040183c chore: replace tsx with native Node TypeScript execution (#42742) 2026-09-22 11:23:20 +00:00
Byron.wang
5b6e850b25 refactor(api): thin console app controllers (#42511) 2026-09-22 11:23:19 +00:00
Byron.wang
ce2eaab9f7 refactor(api): move app-scoped end users behind application services (#41398) 2026-09-22 11:20:45 +00:00
Coding On Star
9badde4d65 fix(marketplace): support single-page carousel navigation (#42743)
Co-authored-by: CodingOnStar <hanxujiang@dify.com>
2026-09-22 11:12:18 +00:00
Xiyuan Chen
dfc3bbe513 feat(openapi): publish the op catalog, per-mode run ops and server-built hints on /openapi/v1 (#42487)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-09-22 10:44:50 +00:00
Stephen Zhou
dced031c95 fix(web): remove extra divider beside home navigation (#42738) 2026-09-22 10:29:03 +00:00
yyh
509f3407a5 chore: enforce erasable syntax in shared tsconfig (#42735) 2026-09-22 09:53:25 +00:00
Joel
963a28b497 fix: improve accessibility in legacy knowledge creation (#42726) 2026-09-22 09:37:03 +00:00
Coding On Star
db9b9b8993 fix: download preview images instead of opening a new tab (#42419)
Co-authored-by: CodingOnStar <hanxujiang@dify.com>
Co-authored-by: CodingOnStar <hanxujiang@jianghanxudeMacBook-Pro-2.local>
2026-09-22 09:11:19 +00:00
Asuka Minato
f117048f41 test: run message cleanup coverage on SQLite (#40715) 2026-09-22 08:29:00 +00:00
Yunlu Wen
1ea81f33ff chore(deps): bump setuptools, pydantic-settings, guzzle for CVE fixes (#42717)
Co-authored-by: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-22 08:27:58 +00:00
yyh
54cc748a36 feat(agent): add publish success guidance (#42645)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Jingyi <jingyi.qi@dify.ai>
2026-09-22 08:17:07 +00:00
yyh
0cc53efe06 refactor(files): migrate supported format queries to generated contracts (#42727) 2026-09-22 08:14:04 +00:00
yyh
8253405c0b refactor(plugins): migrate readme queries to generated contracts (#42725) 2026-09-22 08:14:03 +00:00
wangxiaolei
7ed4ab0b32 chore: remove app and dataset detail rbac check (#42729) 2026-09-22 08:08:24 +00:00
Coding On Star
c3d5b5fa4d fix(web): open Marketplace details externally for self-hosted editions (#42576)
Co-authored-by: CodingOnStar <hanxujiang@dify.com>
2026-09-22 08:00:15 +00:00
yyh
a78f716216 fix(ui): preserve Base UI callback and ref contracts (#42721) 2026-09-22 07:31:59 +00:00
yyh
c1316dd30a refactor(web): migrate custom React icons to Iconify CSS (#42716) 2026-09-22 07:10:38 +00:00
非法操作
27ea5e5790 refactor(api): migrate trial audio through shared app audio (#42672) 2026-09-22 06:42:30 +00:00
yyh
cb044daf60 refactor(web): use standard sizes for icon actions (#42684) 2026-09-22 06:20:45 +00:00
yyh
26d4b9ead8 refactor(datasources): migrate catalog consumers to generated queries (#42713) 2026-09-22 05:55:00 +00:00
yyh
67ab356116 refactor(explore): migrate catalog consumers to generated queries (#42702) 2026-09-22 05:55:00 +00:00
yyh
4192299ad4 refactor(plugins): migrate agent strategy queries to generated contracts (#42696) 2026-09-22 05:54:59 +00:00
yyh
6d358eb680 refactor(plugins): migrate endpoint queries to generated contracts (#42685) 2026-09-22 05:54:58 +00:00
Stephen Zhou
f7dbed5d86 ci: reduce Redis middleware readiness polling delay (#42710) 2026-09-22 05:16:23 +00:00
Stephen Zhou
93c8b0fe18 ci: prepare core E2E browsers alongside web builds (#42706) 2026-09-22 05:16:23 +00:00
Stephen Zhou
ab666bc448 ci: avoid redundant E2E dependency cache saves (#42695) 2026-09-22 05:16:22 +00:00
非法操作
2da0db7df5 refactor(api): isolate trial app and workflow detail previews (#42659)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-09-22 05:03:49 +00:00
Yunlu Wen
6f61401a91 feat(agent): export agent trajectory with a separated tracer (#42651) 2026-09-22 04:35:33 +00:00
yyh
404ba6a805 refactor(web): simplify equivalent regular expressions (#42703) 2026-09-22 04:08:37 +00:00
yyh
7a590a5b41 refactor: clear small lint suppression scopes (#42701) 2026-09-22 04:08:36 +00:00
Stephen Zhou
01b64254de chore: revert "chore(deps): upgrade vinext and simplify CSS asset aliases" (#42700) 2026-09-22 04:03:42 +00:00
yyh
fe09df3afb refactor(web): use Number.isNaN for numeric guards (#42692) 2026-09-22 03:51:14 +00:00
yyh
1ff8a5ff4f refactor(web): replace constructor parameter properties (#42691) 2026-09-22 03:51:13 +00:00
yyh
a50918dfe8 refactor(web): consolidate duplicate type imports (#42690) 2026-09-22 03:51:13 +00:00
yyh
86cfb29b28 refactor(web): replace suppressed string enums with const objects (#42689) 2026-09-22 03:51:12 +00:00
Neo1Noir
a7b1151a2c fix(web): persist reranking_enable for Hybrid Search datasets (#42563) 2026-09-22 03:38:01 +00:00
非法操作
89ffe391be refactor(api): isolate trial preview queries and admission (#42644) 2026-09-22 03:35:02 +00:00
Stephen Zhou
6fa4c9458a chore(deps): upgrade vinext and simplify CSS asset aliases (#42688) 2026-09-22 03:33:25 +00:00
Xx.Zhao
139ce49430 fix(web): refresh provider credentials after editing (#42679) 2026-09-22 03:20:17 +00:00
非法操作
f25c4a3eaf refactor(api): share suggested questions runtime for trial apps (#42635) 2026-09-22 03:10:37 +00:00
yyh
befb18a86f refactor(ui): align Infotip hints and enforce content styling contracts (#42682) 2026-09-22 03:09:19 +00:00
yyh
bfcd0fdb39 refactor(ui): expose compound Infotip primitives and migrate consumers (#42681) 2026-09-22 03:09:18 +00:00
非法操作
206cf8fb94 refactor(api): isolate trial file upload admission and actors (#42625) 2026-09-22 02:43:22 +00:00
非法操作
a6b41ac6d1 refactor(api): isolate trial generation admission and execution (#42130) 2026-09-22 01:55:33 +00:00
Hao Sun
151680eef9 ci: add deterministic pull request size labels (#42615)
Co-authored-by: surbadest <surbadest@users.noreply.github.com>
2026-09-22 01:40:46 +00:00
chenshiyang
d6491af103 fix(web): resolve tilde-alias SVG URLs at build time (#42654)
Co-authored-by: Stephen Zhou <38493346+hyoban@users.noreply.github.com>
2026-09-21 13:33:07 +00:00
Stephen Zhou
11be5332bb refactor(i18n): align analysis with Vite environment graphs (#42656) 2026-09-21 13:17:54 +00:00
林玮 (Jade Lin)
a625c62a1d fix(web): skip parameter rules for unavailable models (#42660) 2026-09-21 12:33:26 +00:00
yyh
fb2dba0cf7 chore(web): enforce tooltip styling with shadcn lint (#42667) 2026-09-21 11:45:05 +00:00
yyh
e811c23d37 fix: normalize field label spacing (#42670) 2026-09-21 11:43:01 +00:00
yyh
4ee8095161 fix: correct schedule trigger labels and theme colors (#42665) 2026-09-21 10:47:05 +00:00
Joel
8fb2741963 fix(web): preserve model warnings when reset is unavailable (#42663) 2026-09-21 10:32:56 +00:00
yyh
905afb5be1 fix(ui): align tooltip surfaces with design tokens (#42661) 2026-09-21 10:31:07 +00:00
Joel
f7b594bf79 fix: keep unset agent web app descriptions no fallback (#42662) 2026-09-21 10:22:11 +00:00
zxhlyh
863ce1d70d fix(skills): fix import, tags, duplication, model selection, and TXT icons (#42653) 2026-09-21 09:57:39 +00:00
Ultronen
9089ed40b9 refactor(dataset): replace available_segment_count property with get_available_segment_count(session) (#42523)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Asuka Minato <i@asukaminato.eu.org>
2026-09-21 09:57:27 +00:00
Stream
ad7849a82b chore(api): add union-type and default-param rules to AGENTS.md (#42652) 2026-09-21 09:49:30 +00:00
Wu Tianwei
9a0961a4a9 fix(web): align access point permissions (#42648) 2026-09-21 08:33:38 +00:00
yyh
1dfa8733a5 fix(i18n): avoid hiding the app during hydration (#42647) 2026-09-21 08:15:40 +00:00
Joel
05df951373 fix: rag pipeline accessibility (#42589) 2026-09-21 08:15:03 +00:00
Stephen Zhou
bbaaaf980f fix(web): align icon picker with updated design (#42636) 2026-09-21 07:59:11 +00:00
zyssyz123
af4f19840c feat(agent): record E2B sandbox runtime usage (#42554) 2026-09-21 07:11:12 +00:00
林玮 (Jade Lin)
1fa3245e83 fix(app): include image icons in app packages (#42626) 2026-09-21 06:32:21 +00:00
dependabot[bot]
6ba3d29f07 chore(deps): bump google-cloud-aiplatform from 2.1.0 to 2.1.3 in /api in the google group (#42610)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-21 06:18:59 +00:00
yyh
bf100beb97 refactor(web): let primitives own local interaction state (#42633) 2026-09-21 06:17:07 +00:00
yyh
22aff66cc0 fix(dify-ui): preserve state-aware styling callbacks (#42631) 2026-09-21 05:56:21 +00:00
林玮 (Jade Lin)
11038c5936 fix(agent): auto-rename duplicate package imports (#42623) 2026-09-21 05:54:22 +00:00
林玮 (Jade Lin)
99df0ca07f fix(api): mark unavailable legacy DSL agent assets as missing (#42622) 2026-09-21 05:54:14 +00:00
Sourav Rajvi
f9129bc500 fix(api): grant in-run tool files to later workflow nodes (#41300) 2026-09-21 05:39:04 +00:00
盐粒 Yanli
2a66bf6f09 refactor(workflow): prepare inputs by entry node type 🤖🤖🤖 (#42595) 2026-09-21 05:26:23 +00:00
Baki Burak Öğün
ee0efe0bdb fix(i18n): check placeholder and tag parity in i18n:check (#42532)
Signed-off-by: Baki Burak Öğün <63836730+bakiburakogun@users.noreply.github.com>
2026-09-21 05:17:54 +00:00
yyh
679785b67e fix(web): align app creation and pricing separators (#42629) 2026-09-21 05:12:47 +00:00
Stephen Zhou
57c140144a ci(web): check image compression savings and support local fixes (#42618) 2026-09-21 05:10:06 +00:00
zyssyz123
d2c2e39ba7 fix(agent): preserve sandbox file errors in stdout 🤖🤖🤖 (#42624) 2026-09-21 04:34:28 +00:00
yyh
3e787d11cc feat(ui): replace legacy Divider with semantic Separator (#42627) 2026-09-21 04:28:29 +00:00
林玮 (Jade Lin)
e78ce4db64 feat(app): package inline agents in workflow and chatflow exports (#42579) 2026-09-21 02:54:43 +00:00
yyh
efd1fb0967 fix(web): migrate legacy plain tabs to Dify UI (#42620) 2026-09-21 02:51:58 +00:00
dependabot[bot]
08a9d40096 chore(deps): bump flask-compress from 1.24 to 1.25 in /api in the flask group (#42609)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-21 02:28:09 +00:00
Sourav Rajvi
126dee3da6 chore(web): optimize in-site notification header background asset (#42479)
Co-authored-by: Stephen Zhou <38493346+hyoban@users.noreply.github.com>
2026-09-21 02:13:42 +00:00
dependabot[bot]
bfa243aecf chore(deps): bump the github-actions-dependencies group with 4 updates (#42612)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-21 01:51:00 +00:00
github-actions[bot]
38be7489ec chore(i18n): sync translations with en-US (#42600)
Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
2026-09-21 00:54:09 +00:00
yyh
e2bdeec273 refactor(web): encapsulate agent version restore interaction (#42597) 2026-09-20 14:14:57 +00:00
Stephen Zhou
de8433277f refactor(i18n): scope and validate sign-in translation namespaces (#42506) 2026-09-20 14:14:06 +00:00
Stephen Zhou
dace5ba264 refactor(i18n): use shared namespaces for reusable UI (#42504) 2026-09-20 14:14:05 +00:00
Stephen Zhou
bf189daea9 ci(api): balance unit shards with shared test timings (#42593) 2026-09-20 13:42:38 +00:00
Stephen Zhou
e6f0c8908c ci: run controllers separately with two unit test shards (#42587) 2026-09-20 13:42:37 +00:00
Stephen Zhou
7f018fce7b ci: shard API unit test files before collection (#42586) 2026-09-20 13:42:36 +00:00
Stephen Zhou
6f61b91b6b test(api): avoid real waits in retry and collection tests (#42585) 2026-09-20 13:42:35 +00:00
Stephen Zhou
57b9d73efe ci: retain API unit test reports (#42583) 2026-09-20 13:42:34 +00:00
Asuka Minato
3a0acfedbb test: clarify container boundaries for storage and Redis (#40714) 2026-09-20 10:39:00 +00:00
Xin Zhang
d96867fa58 chore(deps): bump gitpython from 3.1.59 to 3.1.62 in /api (#42584) 2026-09-20 10:09:43 +00:00
Joel
bc38ce59f7 fix: load Agent text-to-speech voices from the dedicated endpoint (#42575)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: 林玮 (Jade Lin) <linw1995@icloud.com>
2026-09-20 10:03:25 +00:00
XiaoBa
039bf03a31 fix(api): align dataset RBAC permission checks (#42392)
Co-authored-by: Crazywoola <100913391+crazywoola@users.noreply.github.com>
2026-09-20 09:39:32 +00:00
Joel
90f0494c81 fix(e2e): confirm Agent v2 version restoration tests (#42581) 2026-09-20 09:30:54 +00:00
Stephen Zhou
d02666d632 ci: reduce API test middleware readiness and shutdown waits (#42578) 2026-09-20 09:21:04 +00:00
林玮 (Jade Lin)
8e5b097011 fix(api): remove omitted tenant default models (#42572)
Co-authored-by: Joel <iamjoel007@gmail.com>
2026-09-20 09:19:51 +00:00
林玮 (Jade Lin)
2a3cf7edf5 feat(app): default exports to ifpkg across app types (#42552) 2026-09-20 08:36:40 +00:00
非法操作
ecadd45886 fix(workflow): preserve LLM prompts and model changes in collaboration (#42124) 2026-09-20 08:25:01 +00:00
Stephen Zhou
90df30cce9 ci: run API integration tests without sharding (#42573) 2026-09-20 08:18:18 +00:00
Wu Tianwei
2590d90769 fix(web): align Web App launch permissions (#42574) 2026-09-20 07:58:58 +00:00
Bruce-Yii
b2a5b3beba fix(rag): preserve Notion mention and equation text (#42171) 2026-09-20 07:53:31 +00:00
Stephen Zhou
6bb5e525d3 ci: speed up integration database cleanup with tmpfs (#42558) 2026-09-20 07:26:05 +00:00
Joel
8dd33b88d8 feat: add agent version restore (#42567) 2026-09-20 07:23:37 +00:00
yyh
dec1658200 fix(workflow): preserve change node menu semantics and focus (#42568) 2026-09-20 07:04:42 +00:00
林玮 (Jade Lin)
b53e5f23c6 fix(agent): require paid plan for version restore (#42551) 2026-09-20 06:12:32 +00:00
yyh
e95698d2cd fix(web): keep workflow panel resize focus indicator continuous (#42565) 2026-09-20 06:05:47 +00:00
Wu Tianwei
78d338fe11 fix(dataset): disable chunk actions without edit permission (#42561) 2026-09-20 06:00:16 +00:00
Joel
77cdee1f5b chore: improve accessibility on the datasets list page (#42512) 2026-09-20 05:34:27 +00:00
yyh
6f9cb382c4 refactor(web): standardize lazy ref initialization (#42562) 2026-09-20 05:15:48 +00:00
Sourav Rajvi
f16702de80 fix(web): align nuqs peer context for nuqs-jotai dev resolution (#42517) 2026-09-20 04:31:13 +00:00
Stephen Zhou
3a88bc70a3 chore(ci): speed up E2E preparation and API coverage reporting (#42549) 2026-09-20 04:16:36 +00:00
Asuka Minato
37bece696c chore: use pydantic to verify (#38365)
Co-authored-by: Byron.wang <byron@dify.ai>
2026-09-20 03:42:47 +00:00
yyh
b8a5c112a0 docs: clarify contribution guidelines (#42550) 2026-09-20 03:26:09 +00:00
Stephen Zhou
969a831b5b refactor(i18n): report route namespace dependencies (#42503) 2026-09-20 03:13:49 +00:00
yyh
61dc68c3a7 chore(deps): upgrade foxact and Vite+ (#42546) 2026-09-20 02:52:47 +00:00
william
4da38ea322 chore(models): remove redundant server_default from trigger models (#42519) 2026-09-20 02:47:05 +00:00
william
77d701ae81 chore(models): remove redundant server_default from oauth, source, onboarding and comment models (#42520) 2026-09-20 02:46:17 +00:00
william
6523584762 chore(models): remove redundant server_default from provider, tools and workflow models (#42521) 2026-09-20 02:42:06 +00:00
william
214aacd780 chore(models): remove redundant server_default from account models (#42524) 2026-09-20 02:40:35 +00:00
william
d913f3dd0e chore(models): remove redundant server_default from dataset models (#42525) 2026-09-20 02:38:59 +00:00
william
62e1c53c84 chore(models): remove redundant server_default from app, message and site models (#42526) 2026-09-20 02:36:19 +00:00
yyh
9bd86bf474 fix(agent): correct version history e2e locator and menu styling (#42533) 2026-09-20 02:16:20 +00:00
dependabot[bot]
af36832bbf chore(deps): bump anyio from 4.13.0 to 4.14.2 in /dify-agent (#42527)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-20 02:02:44 +00:00
dependabot[bot]
fad2a6c96f chore(deps): bump anyio from 4.14.1 to 4.14.2 in /api (#42528)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-20 02:02:19 +00:00
Xiyuan Chen
a24135ae83 fix(account): make case-fallback email lookup work in both directions (#42541) 2026-09-20 02:01:55 +00:00
Jeremy Schoemaker
ad9b85932b fix(api): report Service API knowledge list has_more from the page the query served (#42531) 2026-09-20 01:51:25 +00:00
Stephen Zhou
9df3e45719 chore: remove redundant CLAUDE.md symlinks (#42544) 2026-09-20 01:47:56 +00:00
yyh
9e13e339b8 feat(ui): add reusable breadcrumbs and migrate Web navigation (#42534) 2026-09-20 01:40:49 +00:00
Asuka Minato
697a244280 test: migrate core service residuals sessions and ORM models to SQLite (#40547)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-09-19 09:27:05 +00:00
Asuka Minato
3a9636faad test: migrate console snippets sessions and ORM models to SQLite (#40565) 2026-09-19 09:26:43 +00:00
Asuka Minato
ceacf275b1 test: migrate application pipelines sessions and ORM models to SQLite (#40510) 2026-09-19 09:26:25 +00:00
Asuka Minato
ce5dc6f314 chore: add some type (#37173) 2026-09-19 09:26:15 +00:00
Asuka Minato
b520bef0b1 test: move plugin lifecycle coverage to SQLite (#40713)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-09-19 09:25:48 +00:00
Asuka Minato
d7630db953 chore: port WorkflowNodeExecutionOffload to TypeBase (#35633)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-09-19 09:25:31 +00:00
Ingram Z
fae098c6c0 fix(retention): harden V2 archive deletion recovery (#41358) 2026-09-19 07:54:35 +00:00
JessYan
5568aa0ea5 refactor(models): pass session into App.tenant (#42518)
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-18 18:31:45 +00:00
yyh
f12a876730 fix(web): prevent compliance download actions from shrinking (#42515) 2026-09-18 10:32:47 +00:00
yyh
fbe69a114c fix(ui): standardize icon-only controls (#42513) 2026-09-18 10:17:43 +00:00
Sourav Rajvi
d39d9ddb74 fix: wire UV_CACHE_DIR for plugin_daemon (Fixes #42433) (#42481) 2026-09-18 09:42:43 +00:00
Yunlu Wen
dbeebfc15d refactor: reduce ambiguity in mcp queries (#42395)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-09-18 09:17:36 +00:00
林玮 (Jade Lin)
f495581a05 fix: preserve default model display after plugin removal (#42498)
Co-authored-by: Joel <iamjoel007@gmail.com>
2026-09-18 09:17:35 +00:00
林玮 (Jade Lin)
db6a4f5cd3 feat(agent): support exporting published versions (#42485)
Co-authored-by: Joel <iamjoel007@gmail.com>
2026-09-18 08:59:54 +00:00
Xiyuan Chen
bc0636c4db refactor(openapi): route /openapi/v1 auth by subject (#41420)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-09-18 08:42:53 +00:00
Joel
e1ebd90bbe fix: restore full-width OAuth client settings labels (#42508) 2026-09-18 08:40:46 +00:00
wangxiaolei
c4dbc4c830 feat: skill detail page draft content support export (#42502) 2026-09-18 08:18:15 +00:00
yyh
b43889821d feat(agent): align app package import and export experience (#42497) 2026-09-18 07:54:35 +00:00
yyh
a81f6fed67 fix(i18n): complete missing Azerbaijani translations (#42495) 2026-09-18 07:38:54 +00:00
yyh
5fa40f1a5f fix(web): keep agent configure model selection explicit (#42488) 2026-09-18 07:35:05 +00:00
Joel
13c12c1b38 fix(web): show full unavailable model names on hover (#42492) 2026-09-18 07:15:22 +00:00
Joel
a60167b390 feat(web): add copy action to error toasts (#42480)
Co-authored-by: yyh <yuanyouhuilyz@gmail.com>
2026-09-18 07:02:22 +00:00
wangxiaolei
41bc173636 chore: remove skill export dialog (#42491) 2026-09-18 06:50:39 +00:00
Xiyuan Chen
3d436a7e31 refactor(openapi): delete the dead bearer→handler auth adapter (#41311) 2026-09-18 06:27:49 +00:00
Mesrop Harutyunyan
104f3b239b refactor(api): merge duplicated model builders in unit tests (#41549)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-09-18 05:10:25 +00:00
yyh
3b8fc9c9b6 refactor(i18n): colocate runtime and locale resources (#42482) 2026-09-18 04:13:14 +00:00
Keith
21d5e4e020 refactor(models): pass session into WorkflowRun accessors and drop dead ones (#42034) 2026-09-18 04:12:28 +00:00
Yunlu Wen
b85102c8e8 fix: normalize json part before deduplicating (#42196) 2026-09-18 03:56:45 +00:00
yyh
48189fedb4 refactor(ui): separate spinner primitives from loading layouts (#42473) 2026-09-18 03:43:55 +00:00
Stephen Zhou
d2fc434dc9 refactor(i18n): check unused translations in Vite builds (#42467) 2026-09-18 03:25:40 +00:00
Joel
331e618961 chore: improve agent web app accessibility (#42475) 2026-09-18 03:23:49 +00:00
william
26831445d0 refactor(api): update tag name with a single UPDATE statement (#42449) 2026-09-18 03:22:44 +00:00
yyh
d43594822b refactor(i18n): separate runtime and metadata boundaries (#42471) 2026-09-18 03:08:44 +00:00
Stephen Zhou
228541c15d refactor(web): replace emoji-mart with self-hosted Frimousse picker (#42469) 2026-09-18 03:04:57 +00:00
yyh
6d88df5d7c docs: clarify Dify Enterprise offering (#42474) 2026-09-18 02:58:11 +00:00
yyh
6024141c26 fix(i18n): normalize locale inputs before language selection (#42466) 2026-09-18 02:52:26 +00:00
dependabot[bot]
7069c7127b chore(deps): bump soupsieve from 2.8.4 to 2.9 in /api (#42455)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-18 02:42:28 +00:00
yyh
bfa4a8b5e4 refactor(web): remove obsolete maintenance notice (#42464) 2026-09-18 02:31:51 +00:00
Asuka Minato
a504dfee27 ci: Update pyrefly dependency version to 1.3.0 (#42445) 2026-09-18 02:16:47 +00:00
Wu Tianwei
1762181e58 fix(webapp): submit JSON object inputs as objects (#42431) 2026-09-18 02:01:52 +00:00
yyh
9a5bd65e33 fix(web): center agent detail loading indicator (#42457) 2026-09-18 02:00:14 +00:00
Jamal Kamaladdinoglu
f418261c50 feat(i18n): add Azerbaijani (az-AZ) translation (#42291) 2026-09-18 01:39:24 +00:00
yyh
c4d4a42b4c docs: update README enterprise links (#42454) 2026-09-18 01:27:18 +00:00
Dorian
ad9a5be560 refactor(models): pass session into MCPToolProvider.load_user (#42432) 2026-09-17 13:37:27 +00:00
Syrinx.
40f859450a refactor(files): dep-inject query params with @model_validate (#42314) 2026-09-17 12:59:55 +00:00
林玮 (Jade Lin)
223039128f feat(agent): support package imports from external URLs (#42425) 2026-09-17 12:54:40 +00:00
Joel
35e4e4f6bd chore: improve accessibility of basic app orchestration pages (#42428) 2026-09-17 12:11:14 +00:00
zyssyz123
d21518f8fe fix(agent): keep composer reads free of draft mutations (#42427) 2026-09-17 12:02:45 +00:00
wangxiaolei
3edbba21b4 feat: dataset automatic_include_workspace_members should be false (#42430) 2026-09-17 11:00:49 +00:00
wangxiaolei
bfd7ac015f feat: skill support duplicate and export use the latest draft (#42424)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-09-17 09:52:25 +00:00
Joel
99ba5a57de fix(home): match banner image aspect ratio to blog (#42422) 2026-09-17 09:26:13 +00:00
yyh
ee151ee952 fix(e2e): align Agent node selection and workflow triggers (#42421) 2026-09-17 09:20:08 +00:00
Joel
f384f9e7cf chore: improve accessibility of app logs (#42417)
Co-authored-by: yyh <92089059+lyzno1@users.noreply.github.com>
2026-09-17 09:02:59 +00:00
Coding On Star
e18c171f74 fix(marketplace): fix preview overlay and image clipboard actions (#42411)
Co-authored-by: CodingOnStar <hanxujiang@dify.com>
2026-09-17 08:35:49 +00:00
yyh
b107d5abd4 fix(workflow): restore node focus and standardize panel controls (#42410) 2026-09-17 08:01:15 +00:00
Keith
bba566540d refactor(models): drop implicit-session getters on Conversation/Message inputs and model_config (#42335) 2026-09-17 07:59:00 +00:00
林玮 (Jade Lin)
3d7f6f4496 feat(agent): import roster packages through App routes (#42189)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-09-17 07:28:18 +00:00
Joel
5e76fc45b7 chore: improve workflow editor accessibility (#42403) 2026-09-17 07:21:44 +00:00
wangxiaolei
7dad80b1f9 fix: fix upload skill zip has an empty directory (#42407) 2026-09-17 07:17:45 +00:00
林玮 (Jade Lin)
93895fa7fb feat(agent): add roster package export foundation (#42066) 2026-09-17 07:05:02 +00:00
yyh
5e9017dbb8 refactor(web): finish legacy input migration (#42405) 2026-09-17 07:04:27 +00:00
yyh
81aa065608 chore: assign frontend tooling code owners and remove invalid owner (#42409) 2026-09-17 06:55:55 +00:00
Stephen Zhou
81a65bd750 chore(deps): upgrade compatible workspace dependencies (#42397)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-09-17 06:23:43 +00:00
invalid w
cddfe06a86 chore(web): add tooltips to workflow header buttons (#42307) 2026-09-17 06:02:51 +00:00
wangxiaolei
0825e6ca51 fix: fix some skill issues (#42389) 2026-09-17 05:54:38 +00:00
Mesrop Harutyunyan
153cc72f17 fix(web): correct Slovenian display language name (#42361) 2026-09-17 05:53:04 +00:00
JessYan
28e2682986 refactor(models): pass session into App.app_model_config and App.workflow (#42190)
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-17 05:43:18 +00:00
yyh
64deb9c421 docs: update README agent feature description (#42399) 2026-09-17 05:39:40 +00:00
yyh
a14ebae6a4 refactor(web): use Zod validate for boolean form checks (#42398) 2026-09-17 05:20:07 +00:00
yyh
d528dea83e fix(web): remove ineffective Tailwind classes (#42394) 2026-09-17 04:55:31 +00:00
Stephen Zhou
8006e8e13d ci: reduce API unit tests to three shards (#42390) 2026-09-17 04:04:25 +00:00
Stephen Zhou
1203aa72c1 perf(api): avoid duplicate Redis client scans in unit tests (#42379) 2026-09-17 03:45:32 +00:00
Syrinx.
ff18b6de09 refactor(console): dep-inject the snippet draft-variable query with @model_validate (#42315) 2026-09-17 03:42:31 +00:00
Syrinx.
66bf75d1d8 refactor(models): pass session into AppMCPServer.generate_server_code (#42316) 2026-09-17 03:41:45 +00:00
Eddy ZHANG
f66773b63c refactor(api): dep-inject the last three GET query models with @model_validate (#42318) 2026-09-17 03:40:50 +00:00
Keith
4afc3cbd4f refactor(models): drop dead to_dict serializers and remaining global-session accessors on dataset models (#42324)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-09-17 03:39:04 +00:00
xiaodu55
8b3c4db9ac refactor(models): pass session into recommended-app and trial-record accessors (#42325) 2026-09-17 03:38:18 +00:00
Stephen Zhou
f7ed1c0176 fix(ci): preserve system npx in shared web setup (#42382) 2026-09-17 03:26:13 +00:00
陈志谦
47a28bf262 fix(api): align the datasource docstrings with their signatures (#42369)
Signed-off-by: simpleqt <89645338+simpleqt@users.noreply.github.com>
2026-09-17 03:13:48 +00:00
coderdailyone
fea6b6e999 fix(rag): derive url file suffix from content-type media type in load_from_url (#42364)
Co-authored-by: coderdailyone <codecookie@proton.me>
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-17 02:56:58 +00:00
Stephen Zhou
e58e5b0879 ci: shard API unit tests across runners (#42374) 2026-09-17 02:50:31 +00:00
陈志谦
a9227cf6f9 fix: remove duplicated word in the code-regeneration prompt (#42368)
Signed-off-by: simpleqt <89645338+simpleqt@users.noreply.github.com>
2026-09-17 02:35:02 +00:00
Stephen Zhou
bffaccbc95 fix(ci): allow Codecov uploads from fork PRs (#42376) 2026-09-17 02:31:54 +00:00
Pranav Agarwal
b721e438ba fix(api): use inclusive <= for completion-conversation end-time filter (#42321) 2026-09-17 01:43:46 +00:00
yyh
e6b13eaab9 chore: upgrade workspace dependencies and CI actions (#42372) 2026-09-17 01:35:43 +00:00
yyh
9e7856f22b test(web): tighten browser test admission and trim low-value coverage (#42373) 2026-09-17 01:19:03 +00:00
Asuka Minato
9c6c48b50b test: keep API token cache coverage on real Redis (#40712) 2026-09-16 13:41:22 +00:00
Asuka Minato
8b9f3016e6 test: remove duplicate integration-only coverage (#40711) 2026-09-16 13:41:21 +00:00
Asuka Minato
9e4f0fa23a test: isolate parameter extractor model fixtures (#40710) 2026-09-16 13:41:21 +00:00
Lukas Buck
38f9d85d5a fix(api): report has_more from the page the query served (#42323) 2026-09-16 07:45:48 +00:00
Xx.Zhao
6a0039812d fix(agent): validate workspace skill references on publish (#42299) 2026-09-16 03:27:00 +00:00
Sean Sun
a4d74f7c82 refactor(api): pass session explicitly into RBACResourceService (#37403) (#42248)
Co-authored-by: lyfuci <lyfuci11@gmail.com>
2026-09-15 12:45:34 +00:00
Liu Ziming
07dc8ebdbb feat(trace-aliyun): capture HTTP request snapshots and task node types (#42296) 2026-09-15 03:03:43 +00:00
Mesrop Harutyunyan
cb4d8ab5ea perf(api): batch dataset list detail fields (#42279) 2026-09-15 02:33:42 +00:00
Jinsong Zhou
6afe07f944 feat(dify-agent): add OpenShell runtime backend (#41076)
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: Yunlu Wen <yunlu.wen@dify.ai>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-09-14 13:05:16 +00:00
human
a5bc77eaa7 fix(api): delete offload objects outside the DB transaction (#42258) 2026-09-14 10:10:05 +00:00
Richard_0x
6b88a6e0c4 fix(workflow): remap assigner references on snippet insertion (#42229) 2026-09-14 08:55:32 +00:00
dxdx123
fe3600f149 fix(web): prevent dataset tag popup from triggering card navigation (#42269)
Co-authored-by: ding <dingxing@xd.com>
2026-09-14 08:52:14 +00:00
dependabot[bot]
b83f02be9a chore(deps): bump opentelemetry-propagator-b3 from 1.41.1 to 1.44.0 in /api in the opentelemetry group across 1 directory (#41123)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-14 08:51:48 +00:00
Priyansh Nandwana
04dd4d11ec fix(agent): allow a conversation to continue after a cancelled tool call (#41846)
Co-authored-by: Yunlu Wen <yunlu.wen@dify.ai>
2026-09-14 08:44:56 +00:00
Weike Zhang
318964e4dc fix(api): compute annotation list has_more with the effective page size (#41876) 2026-09-14 03:58:22 +00:00
dependabot[bot]
51dd877de9 chore(deps): bump the github-actions-dependencies group with 2 updates (#42260)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-14 02:28:15 +00:00
CoralGarden52
5389f70719 fix(api): avoid per-row MAX(position) queries in batch segment import (#42233) 2026-09-14 02:11:23 +00:00
CoralGarden52
43ac0fce5c fix(rag): cap QA indexing preview results (#42205) 2026-09-13 13:25:14 +00:00
Bruce-Yii
79effdd498 fix(api): preserve literal NA in annotation CSV imports (#42221)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-09-12 04:55:53 +00:00
Bruce-Yii
7f7afc576c fix: ignore blank keyword rows in moderation limit (#42212) 2026-09-12 02:32:19 +00:00
KingPointer
085a79c748 chore(models): add Mapped annotations to EndUser and ApiToken (#42146)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-09-11 17:07:04 +00:00
Jyong
e7981a6f19 fix: allow Knowledge deployment to finish Celery drain (#42201) 2026-09-11 12:46:31 +00:00
Joel
bb02d3efcc fix: exclude installed plugins and localize marketplace search results (#42199) 2026-09-11 09:59:13 +00:00
小小涂涂
92d64db112 docs: sync zh-CN README — observability integrations and "Seeking help" section (#42161) 2026-09-11 09:29:52 +00:00
CoralGarden52
c6c891430c fix(rag): preserve CSV cell text in batch segment import (#42159) 2026-09-11 08:17:13 +00:00
Coding On Star
b769a3469b feat(web): report marketplace utm_source on OAuth registration (#42193)
Co-authored-by: CodingOnStar <hanxujiang@dify.com>
2026-09-11 08:14:31 +00:00
Sourav Rajvi
aa6dceeece fix(web): send model delete params as query string on DELETE (#42162)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-09-11 08:09:48 +00:00
Harsh Kashyap
4cc2f632b8 fix: parse Redis Sentinel and Cluster nodes safely (#42111) 2026-09-11 08:06:32 +00:00
CoralGarden52
5b58f51460 perf(api): batch indexing status segment counts (#42191) 2026-09-11 07:43:16 +00:00
yyh
0cdb9e82c0 fix(web): deduplicate server locale resolution (#42187) 2026-09-11 06:56:42 +00:00
yyh
122f95b976 fix(web): consolidate marketplace logo and correct public asset path (#42185) 2026-09-11 06:19:37 +00:00
yyh
2de83835cd refactor(web): migrate variable configuration inputs (#42179) 2026-09-11 06:16:12 +00:00
yyh
10658e428b fix(web): deduplicate server i18next initialization (#42183) 2026-09-11 06:03:44 +00:00
yyh
6c252e9059 refactor(web): migrate numeric variable constraints to NumberField (#42178) 2026-09-11 04:30:25 +00:00
Coding On Star
bad3a86816 feat(marketplace): use stable template UUID links in the Dify embed (#42172)
Co-authored-by: CodingOnStar <hanxujiang@dify.com>
Co-authored-by: CodingOnStar <hanxujiang@jianghanxudeMacBook-Pro-2.local>
2026-09-11 03:59:30 +00:00
Coding On Star
98d9298828 fix(web): use delivered cover_image for blog banners (#42173)
Co-authored-by: CodingOnStar <hanxujiang@dify.com>
2026-09-11 03:59:26 +00:00
Charles Yao
96c8cc4383 fix(mcp): stop returning opaque 500s from MCP connect/auth (#42177)
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-11 03:46:23 +00:00
Joel
8e022cc3c1 fix: keep agent conversation opener state in sync after saving (#42175) 2026-09-11 03:45:46 +00:00
林玮 (Jade Lin)
cd61738f33 feat(api): normalize additional email providers (#42112) 2026-09-11 02:41:35 +00:00
Baki Burak Öğün
a3b2786b32 fix(i18n): translate the tr-TR labels still left in English (#41825)
Signed-off-by: Baki Burak Öğün <63836730+bakiburakogun@users.noreply.github.com>
2026-09-11 01:47:16 +00:00
Harsh Kashyap
a1bb317892 fix: strip keyword rows in keyword moderation (#42048) 2026-09-11 01:02:22 +00:00
yyh
f0d69e7b39 fix(web): align workflow and agent sidebar identity layouts (#42145) 2026-09-10 11:55:16 +00:00
Bond Zhu
c96bbe2e08 fix(ci): set up Node.js in sync-e2b-template job (#42138) 2026-09-10 09:59:00 +00:00
Joel
d441dd543e chore: restore grid and table accessibility (#42125) 2026-09-10 09:52:11 +00:00
Soroush Ahmadi
a425a127f5 fix(api): require exact match for CSRF whitelist paths (#42118)
Co-authored-by: soroush5 <soroush5@users.noreply.github.com>
2026-09-10 09:49:29 +00:00
wangxiaolei
66f1e6568e fix: fix sample_size not work (#42131) 2026-09-10 09:43:50 +00:00
Yunlu Wen
8387590ace chore: bump version to 1.17.1 (#42129)
Co-authored-by: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-10 09:06:31 +00:00
yyh
2c206d2792 fix(web): delegate overlay initial focus to popup owners (#42121) 2026-09-10 08:25:48 +00:00
Stephen Zhou
b3c978caa6 fix(web): center settings dialog across viewport sizes (#42120) 2026-09-10 07:34:30 +00:00
Joel
1a415d1e02 fix(web): correct form labels, validation feedback, and keyboard navigation (#42096) 2026-09-10 07:30:50 +00:00
yyh
445b194938 fix(ui): let collapsible consumers own trigger styling (#42116) 2026-09-10 07:23:11 +00:00
yyh
44dac4a90d fix(web): preserve web apps navigation focus and disclosure semantics (#42113) 2026-09-10 06:26:54 +00:00
QuantumGhost
798fd5e4c0 fix(api): restore Human Input completion events (#42082) 2026-09-10 06:20:44 +00:00
zyssyz123
c3f603c4dc fix(agent): pin chatflow participant versions across config updates (#42105) 2026-09-10 06:10:16 +00:00
yyh
1dcfe38171 fix(dify-ui): preserve invalid focus colors and remove shadow transitions (#42108) 2026-09-10 05:09:30 +00:00
Asuka Minato
31dfa21f36 test: migrate RAG retrieval sessions and ORM models to SQLite (#40512) 2026-09-10 04:15:40 +00:00
Asuka Minato
3ecceb744b test: move mocked model and tool cases to unit tests (#40708) 2026-09-10 04:14:49 +00:00
Asuka Minato
a43583a4a0 test: migrate agent workspace and publishing sessions and ORM models to SQLite (#40506) 2026-09-10 04:13:53 +00:00
Asuka Minato
c529c3b2f1 test: migrate Service API app sessions and ORM models to SQLite (#40558) 2026-09-10 04:13:36 +00:00
Asuka Minato
e7cfe142bc test: migrate console dataset metadata sessions and ORM models to SQLite (#40520) 2026-09-10 04:12:43 +00:00
Asuka Minato
4e0d7f7f9b test: migrate custom tool provider ORM model to real entity (#40653) 2026-09-10 04:11:52 +00:00
Asuka Minato
d201dc1f09 test: migrate summary index sessions and ORM models to SQLite (#40505) 2026-09-10 04:11:28 +00:00
yyh
f1da874b53 fix(web): remove local search delay and clean up component lifecycles (#42102) 2026-09-10 03:39:46 +00:00
wangxiaolei
63bd623a63 fix: fix agent.id mismatch lead permission keys are empty (#42095) 2026-09-10 03:18:36 +00:00
yyh
3e44b51d7a fix(web): restore content-sized search shortcut keycap (#42097) 2026-09-10 03:15:49 +00:00
yyh
f1d88f79f4 chore(web): upgrade React to 19.3 and adopt browser-only rendering (#42093) 2026-09-10 03:08:38 +00:00
Stephen Zhou
5f02726207 fix(web): stabilize install footer and shortcut initial rendering (#42088)
Co-authored-by: yyh <yuanyouhuilyz@gmail.com>
2026-09-10 02:40:56 +00:00
Zhu Lei
d4d2a4a988 fix(web): prefetch skill feature flag for initial navigation (#41731)
Co-authored-by: Stephen Zhou <38493346+hyoban@users.noreply.github.com>
2026-09-10 02:07:33 +00:00
Tv
90aa225cf0 docs(api): fix working directory instructions for running tests (#42085) 2026-09-10 01:28:15 +00:00
-LAN-
dfe27fc75b chore(codeowners): assign dify-agent to Yanli (#42091) 2026-09-10 00:53:36 +00:00
Evan
8bdf01be3b refactor(api): remove legacy end user type fallback (#39662) 2026-09-09 20:16:48 +00:00
Stephen Zhou
7f59b65b6a feat(nuqs-jotai): bridge nuqs URL state into Jotai (#42086) 2026-09-09 16:11:08 +00:00
Asuka Minato
608b1d10e0 test: split CodeNode validation from sandbox coverage (#40707) 2026-09-09 14:45:16 +00:00
yyh
5feddcb96a fix(ci): refresh E2E runtime path filters (#42079) 2026-09-09 12:04:19 +00:00
Joel
bce802c61f fix: prevent note bold shortcut from toggling the sidebar (#42078) 2026-09-09 10:31:54 +00:00
Joel
9e6c0c20d2 chore: fit the app canvas when create from DSL and preview (#42073)
Co-authored-by: 林玮 (Jade Lin) <linw1995@icloud.com>
2026-09-09 10:22:33 +00:00
dependabot[bot]
e7eb030109 chore(deps): bump the google group across 1 directory with 2 updates (#41121)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-09 10:13:32 +00:00
yyh
40955e72a9 fix(web): align card tag masks with design tokens (#42074) 2026-09-09 09:58:31 +00:00
dependabot[bot]
8c208ad206 chore(deps): bump unstructured from 0.21.5 to 0.24.0 in /dify-agent (#41765)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-09 09:53:12 +00:00
Asuka Minato
4724779fe2 refactor(api): migrate remaining RESTX models to Pydantic (#40399)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Byron Wang <byron@dify.ai>
2026-09-09 09:50:44 +00:00
yyh
f70cea50c9 refactor(web): migrate conversation variable inputs (#42070) 2026-09-09 09:36:24 +00:00
dependabot[bot]
0468eee02f chore(deps): bump gunicorn from 26.1.0 to 26.2.0 in /api in the flask group across 1 directory (#41505)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-09 09:30:17 +00:00
Joel
06f58809f2 fix(web): restore focus after closing overlays (#42068) 2026-09-09 09:27:56 +00:00
Duda Nogueira
647fec55d9 chore(release): Upgrade self-hosted Weaviate to 1.39 (#38214)
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-09 09:19:54 +00:00
dependabot[bot]
a1a1a42c42 chore(deps): bump the storage group across 1 directory with 4 updates (#41893)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-09 09:18:06 +00:00
dependabot[bot]
87b4de1cda chore(deps): bump httpx2 from 2.5.0 to 2.12.0 in /dify-agent (#42011)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-09 09:16:40 +00:00
Coding On Star
8c5dd51446 fix(web): open embedded recommend banner templates in the detail dialog (#42063)
Co-authored-by: CodingOnStar <hanxujiang@dify.com>
2026-09-09 09:15:40 +00:00
dependabot[bot]
1007cf8294 chore(deps): bump httpx2 from 2.5.0 to 2.12.0 in /api (#42012)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-09 09:15:16 +00:00
wangxiaolei
adedbf1f12 fix: fix undo delete operation for webhook trigger node lead the url … (#42069) 2026-09-09 09:02:04 +00:00
github-actions[bot]
57a6ccbd3b chore(i18n): sync translations with en-US (#42064)
Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Co-authored-by: yyh <92089059+lyzno1@users.noreply.github.com>
2026-09-09 08:57:53 +00:00
dependabot[bot]
ebb875e0a5 chore(deps): bump h2 from 4.3.0 to 4.4.1 in /dify-agent (#40119)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-09 08:57:27 +00:00
Asuka Minato
677f2cf43f chore: example to add Mapped (#40374) 2026-09-09 08:56:41 +00:00
Asuka Minato
f71047f31a test: migrate console workflow sessions and ORM models to SQLite (#40563)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-09-09 08:50:02 +00:00
Asuka Minato
a062155841 test: migrate console app response sessions and ORM models to SQLite (#40562) 2026-09-09 08:47:46 +00:00
Yunlu Wen
a7cc6913af chore(deps): bump unstructured from 0.21.5 to 0.27.5 in /api (#42053)
Co-authored-by: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-09 08:47:09 +00:00
Stephen Zhou
8e8a3c5414 chore(lint): respect gitignore in ESLint flat config (#42065) 2026-09-09 07:58:29 +00:00
Wu Tianwei
f89c3e6ec7 feat: add agent resource permissions (#41940)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-09-09 07:30:39 +00:00
Joel
e8c3419d1f fix(web): hide decorative content and redundant list semantics (#42060) 2026-09-09 07:28:22 +00:00
Asuka Minato
4f29213cdc test: migrate workflow node execution task sessions and ORM models to SQLite (#40571) 2026-09-09 07:27:39 +00:00
Stephen Zhou
0f232ac4e7 chore(lint): tighten inline disable enforcement (#42058) 2026-09-09 07:21:02 +00:00
Yunlu Wen
4223b8eb0f chore(deps): bump transformers from 5.6.2 to 5.16.1 in /dify-agent (#42054)
Co-authored-by: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-09 07:13:17 +00:00
Asuka Minato
62adebcf4e test: reclassify response filter regressions (#40706) 2026-09-09 07:12:01 +00:00
Joel
b577502a9b fix: make sortable lists keyboard accessible (#41974) 2026-09-09 07:01:54 +00:00
yyh
603176c17d refactor(web): migrate workflow numeric configuration inputs (#42052) 2026-09-09 06:51:29 +00:00
Harsh Kashyap
6e91ee2694 fix: join all rich_text/title segments in Notion database extraction (#42050) 2026-09-09 06:36:13 +00:00
yyh
cb1a8963e3 chore(lint): share and tighten JSX accessibility rules (#42045) 2026-09-09 06:26:57 +00:00
Harsh Kashyap
112e33a665 fix: escape double quotes in .xls cell values like the .xlsx path (#42049) 2026-09-09 06:05:08 +00:00
jiao-weiran
3f76dbe67a refactor(controllers/console): inject saved-message query with @model_validate (#41819)
Co-authored-by: 几一奥 <2481680240@qq.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-09-09 05:41:53 +00:00
nehal-a2z
cd031ab423 refactor(api): remove InstalledApp implicit-session accessor (#42000)
Co-authored-by: nehal-a2z <183489955+nehal-a2z@users.noreply.github.com>
2026-09-09 05:31:08 +00:00
Eddy ZHANG
dc9dd9c559 refactor(models): remove the App.bound_agent_id and App.is_agent wrappers (#41998) 2026-09-09 05:17:29 +00:00
Eddy ZHANG
e65f45f17a refactor(models): remove the unread App.author_name db.session wrapper (#41983) 2026-09-09 05:16:14 +00:00
L1nSn0w
8a69aa2884 fix(console): stop advertising the education plan outside Dify Cloud (#41898) 2026-09-09 04:38:50 +00:00
dependabot[bot]
f1c2917038 chore(deps): bump gitpython from 3.1.58 to 3.1.59 in /api (#42017)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-09 04:21:32 +00:00
Joel
0669e4e033 fix: deduplicate repeated GET request error notifications (#42035) 2026-09-09 03:39:41 +00:00
Harsh Kashyap
0b8435da71 fix(api): accept valid epoch-0 timestamps in localtime conversion tool (#42027) 2026-09-09 03:38:58 +00:00
yyh
bb1797722f chore(deps): upgrade jotai to v3 and jotai-scope (#42036) 2026-09-09 03:30:13 +00:00
Harsh Kashyap
455951056a fix: keep Notion table cell rich text segments in one Markdown column (#41993) 2026-09-09 03:23:01 +00:00
林玮 (Jade Lin)
0c443b7666 fix(api): handle invalid app icon references (#41977)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-09-09 02:56:40 +00:00
Harsh Kashyap
cc44574543 fix(api): reject trailing newlines in user_input_form variable names (#42029) 2026-09-09 02:51:46 +00:00
Harsh Kashyap
75f203cdb9 fix: validate declared blob size before allocating buffer in chunk merger (#42021)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-09-09 02:47:25 +00:00
Harsh Kashyap
da6a1b01d1 fix(api): fall back to first server URL when X-Request-Env is set but servers lack env key (#42025) 2026-09-09 02:38:44 +00:00
FFXN
bb2945a1a3 fix: dataset hitcount deadlock (#41979)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-09-09 02:37:26 +00:00
yyh
bec2c6787a chore(deps): upgrade pnpm to 12.3.4 and Vite+ to 0.3.1 (#42005) 2026-09-09 01:55:47 +00:00
CoralGarden52
89df7a670a fix(dataset): clean multimodal attachments during reindex (#41999) 2026-09-09 01:43:57 +00:00
-LAN-
d60873dd76 docs(CODEOWNERS): Assign domain owners for backend test paths (#42007) 2026-09-09 00:43:49 +00:00
Harsh Kashyap
fc062bfc6d fix(api): allow PDF extraction from URLs without an upload file (#41950) 2026-09-08 11:01:52 +00:00
JackSmith
e34b2f9045 fix(api): resolve aliases in remote settings sources (#41463) 2026-09-08 10:45:36 +00:00
Coding On Star
dfe5d8af31 fix(web): keep recommend banner logos intact and show template authors (#41980)
Co-authored-by: CodingOnStar <hanxujiang@dify.com>
2026-09-08 10:33:31 +00:00
Harsh Kashyap
09ddcbe01e fix(api): flatten readabilipy plain_text items in web reader tool (#41954) 2026-09-08 10:28:20 +00:00
Asuka Minato
398addf0c1 test: migrate segment service sessions and ORM models to SQLite (#40535)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-09-08 10:22:20 +00:00
Asuka Minato
1c4bcff490 test: migrate console dataset document sessions and ORM models to SQLite (#40522) 2026-09-08 10:17:25 +00:00
Asuka Minato
bcda6b4570 test: migrate workspace snippet sessions and ORM models to SQLite (#40524) 2026-09-08 10:17:08 +00:00
Asuka Minato
e4eb3d0d92 test: migrate provider core entity sessions and ORM models to SQLite (#40532) 2026-09-08 10:17:01 +00:00
Joel
e75b5f6bc9 fix: restore comment marker focus after closing threads (#41978) 2026-09-08 09:44:45 +00:00
yyh
0955b8b810 fix(web): reset goto anything search after dialog closes (#41976) 2026-09-08 09:38:11 +00:00
leilei3167
c9e0118ae9 fix(api): accept CRLF SKILL.md when importing skill zips (#41657)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Crazywoola <100913391+crazywoola@users.noreply.github.com>
2026-09-08 09:34:43 +00:00
Stephen Zhou
2f00e647ef fix(api): correct service api rate limit descriptions (#41975) 2026-09-08 09:33:46 +00:00
Keith
f3e5f41a3c refactor(models): pass session into WorkflowNodeExecutionModel accessors (#41968) 2026-09-08 09:31:08 +00:00
Harsh Kashyap
80428a693a fix(api): handle string and missing params in weekday time tool (#41952) 2026-09-08 09:09:51 +00:00
Sourav Rajvi
f3154e347e fix(rag): preserve CSV cell text during knowledge import (#41922) 2026-09-08 08:47:42 +00:00
Wu Tianwei
2873abd647 fix(i18n): sync agent access point copy (#41969) 2026-09-08 08:47:32 +00:00
Joel
93d6ff3889 feat: support keyboard movement for workflow nodes and comments (#41967) 2026-09-08 08:47:27 +00:00
Harsh Kashyap
67f7a5517a fix(api): anchor JSON extraction on brackets in parse_json_markdown (#41959) 2026-09-08 08:32:14 +00:00
CoralGarden52
2cdfe24c18 fix(dataset): delete segment attachment blobs from storage (#41400) 2026-09-08 08:13:18 +00:00
yyh
12d23062d4 refactor(web): isolate pricing modal state and lifecycle (#41960) 2026-09-08 07:53:39 +00:00
Joel
a233b2f53a fix: make panel and node resizing keyboard accessible (#41963)
Co-authored-by: yyh <yuanyouhuilyz@gmail.com>
2026-09-08 07:44:41 +00:00
Eddy ZHANG
9e0763e189 refactor(models): remove four unread legacy db.session wrappers (#41964) 2026-09-08 07:27:02 +00:00
Eddy ZHANG
970bbeca8d refactor(models): remove the legacy db.session wrappers on App (#41942) 2026-09-08 07:26:20 +00:00
yyh
8acdb1538b refactor(api): trim workspace features response contract (#41948) 2026-09-08 05:42:22 +00:00
Pranav Agarwal
a67f62e9aa fix(api): enforce RBAC permission on MCP tool provider GET endpoint (#41547) (#41548)
Co-authored-by: yunlu.wen <yunlu.wen@dify.ai>
2026-09-08 04:43:24 +00:00
Joel
efe506a0f5 fix: correct page landmarks and document layout rules (#41938) 2026-09-08 04:22:04 +00:00
yyh
d978fe710f refactor(web): retire provider context (#41944) 2026-09-08 04:16:45 +00:00
Stephen Zhou
7ba2cfb30b fix(api): align service api schemas with runtime behavior (#41943) 2026-09-08 03:59:02 +00:00
非法操作
146b193ef7 refactor(api): extract plugin file upload application service (#41808) 2026-09-08 03:42:32 +00:00
Zhu Lei
c157e59d58 fix(agent): persist Chatflow Agent V2 memory by conversation_id (#41871)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Yunlu Wen <yunlu.wen@dify.ai>
2026-09-08 03:31:01 +00:00
yyh
1006519012 refactor(web): move model lists out of provider context (#41939) 2026-09-08 03:29:56 +00:00
yyh
e26dcf55a9 refactor(web): move provider feature flags to query consumers (#41937) 2026-09-08 02:56:31 +00:00
非法操作
d43a23d8f5 refactor(api): extract tool file download service (#41790) 2026-09-08 02:51:11 +00:00
yyh
22189f69f6 refactor(console): unify environment-aware oRPC clients and query policies (#41932) 2026-09-08 02:04:41 +00:00
非法操作
749d1f8d04 refactor(api): extract upload file delivery service (#41772) 2026-09-08 02:03:24 +00:00
Taranum Wasu
216180c7fd fix(vdb-weaviate): backward-compatible cleanup + preserve positional alignment (#41915)
Co-authored-by: Taranum01 <taranumwasu@users.noreply.github.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-09-08 01:55:08 +00:00
Taranum Wasu
eeff2c01b1 fix(dataset_service): refresh session snapshot before UploadFile lookup (#41840)
Co-authored-by: Taranum01 <taranumwasu@users.noreply.github.com>
2026-09-08 01:30:39 +00:00
yyh
4f463b1c46 fix(billing): align zero and unlimited quota semantics (#41927) 2026-09-08 01:14:06 +00:00
yyh
8980506597 refactor(web): remove obsolete agent v2 scaffolding and editor state (#41931) 2026-09-08 01:13:40 +00:00
citizen204
0df092d3c7 refactor: add missing @override decorators to console controller classes (#37113)
Co-authored-by: Asuka Minato <i@asukaminato.eu.org>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-09-07 15:56:25 +00:00
Java123456com
d138effca8 style(api): remove unnecessary type conversions in services, repositories and tests (#41856) 2026-09-07 15:54:53 +00:00
ShawYann
a57e04aa49 refactor(models): pass session into InstalledApp.tenant accessor (#41831) 2026-09-07 15:45:39 +00:00
Valor
93287f22a8 refactor: preserve exception context when re-raising in except blocks (#40432)
Co-authored-by: Asuka Minato <i@asukaminato.eu.org>
2026-09-07 13:52:29 +00:00
yyh
8fc11b2927 refactor(web): retire provider context plan state (#41925) 2026-09-07 13:28:20 +00:00
WH-2099
a9cb17eb6c fix(api): reject ownerless pending DSL imports (#40107) 2026-09-07 10:59:09 +00:00
yyh
715bc7cd95 fix(dx): repair and restage Python files in pre-commit (#41877) 2026-09-07 10:37:38 +00:00
however-yir
75f867da85 refactor(models): remove legacy db.session wrappers on Message accessors (#41886)
Co-authored-by: however <however-yir@users.noreply.github.com>
2026-09-07 09:28:29 +00:00
Keith
d5be01b253 refactor(models): remove the last standalone legacy db.session properties on Dataset (#41911) 2026-09-07 09:27:04 +00:00
however-yir
b93101459d refactor(models): pass session into ApiToolProvider.user accessor (#41882)
Co-authored-by: however <however-yir@users.noreply.github.com>
2026-09-07 09:25:55 +00:00
非法操作
c17a96f02f refactor(service-api): extract file preview application service (#41732) 2026-09-07 08:59:18 +00:00
FFXN
60656a60cf fix(api): fix tencent summary vector deadlock (#41916)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-09-07 08:31:08 +00:00
yyh
eba589db89 refactor(api): remove legacy billing enabled state (#41917) 2026-09-07 08:29:57 +00:00
yyh
fc0136647f refactor(web): remove legacy enableBilling consumers (#41913) 2026-09-07 07:56:01 +00:00
Zhu Lei
c7423ffb2d fix(ssrf): apply private allowlist to agent_ssrf_proxy (#41870) 2026-09-07 07:22:12 +00:00
yyh
5c0d3c4393 refactor(web): remove provider plan query flags (#41908) 2026-09-07 06:37:26 +00:00
yyh
3be0cabf0a refactor(web): move app quota refresh out of provider context (#41906) 2026-09-07 06:13:20 +00:00
yyh
40f0b8a2a0 fix(web): use default Code Inspector integration (#41903) 2026-09-07 06:02:40 +00:00
yuki.uix
5e51fe2640 refactor(controllers): adopt with_session in web saved_message (#41859) 2026-09-07 05:43:29 +00:00
Charles
2df92204e9 refactor(models): pass session into CustomizedSnippet accessors (#40379) 2026-09-07 05:37:43 +00:00
github-actions[bot]
5f978fec37 chore(i18n): sync translations with en-US (#41904)
Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Co-authored-by: yyh <92089059+lyzno1@users.noreply.github.com>
2026-09-07 05:35:57 +00:00
Keith
11a9627cbb refactor(models): remove remaining legacy db.session property wrappers on Dataset (#41647) 2026-09-07 05:25:51 +00:00
Keith
62a286332a refactor(models): remove legacy db.session property wrappers on DocumentSegment and DatasetQuery (#41794) 2026-09-07 05:24:37 +00:00
Kiveiru3
d91672c6d3 refactor(controllers): inject message request models (#41884) 2026-09-07 05:14:18 +00:00
Eddy ZHANG
56a31bab8d refactor(inner_api): dep-inject workspace payloads with @model_validate (#41540) 2026-09-07 05:13:09 +00:00
however-yir
a1a98e1087 refactor(models): remove legacy db.session wrappers on Message feedback/annotation accessors (#41883)
Co-authored-by: however <however-yir@users.noreply.github.com>
2026-09-07 05:11:29 +00:00
however-yir
80f6f72e8c refactor(models): pass session into AppAnnotationSetting.collection_binding_detail (#41885)
Co-authored-by: however <however-yir@users.noreply.github.com>
2026-09-07 05:00:12 +00:00
Xiyuan Chen
86134ea99e feat(rbac): agent RBAC/ACL scenes and resource-locator check bundles (#41768)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-09-07 04:39:43 +00:00
dependabot[bot]
60e983c493 chore(deps-dev): bump the dev group in /api with 48 updates (#41896)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-09-07 04:31:12 +00:00
kenwoodjw
cf34e3ee1a fix(agent): send uploaded images as native multimodal input (#41685)
Co-authored-by: kenwood chan <kenwoodchan@kenwooddeMacBook-Pro.local>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: yunlu.wen <yunlu.wen@dify.ai>
2026-09-07 04:23:03 +00:00
yyh
3e961dbb77 refactor(web): migrate loop variable constant inputs (#41901) 2026-09-07 04:15:41 +00:00
yyh
789cada297 refactor(web): migrate workflow error default inputs (#41900) 2026-09-07 04:15:40 +00:00
SONG ZHIFEI
1f6dadd22c chore: remove unnecessary str() calls in annotation tasks (#41878) 2026-09-07 03:55:20 +00:00
Kiveiru3
e7d34f05ba refactor(models): remove legacy db.session properties from Conversation (#41847) 2026-09-07 03:43:14 +00:00
dependabot[bot]
4cb70b7421 chore(deps): bump anthropics/claude-code-action from 1.0.211 to 1.0.216 in the github-actions-dependencies group (#41892)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-07 03:35:32 +00:00
非法操作
4c124174c9 refactor(api): extract human input file upload persistence (#41716) 2026-09-07 03:21:33 +00:00
Coding On Star
762dc5e8a6 fix(web): open embedded recommend banner plugins in the detail dialog (#41828)
Co-authored-by: fatelei <fatelei@gmail.com>
Co-authored-by: zxhlyh <jasonapring2015@outlook.com>
Co-authored-by: CodingOnStar <hanxujiang@dify.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: 姜涵煦 <hanxujiang@jianghanxudeMacBook-Pro-2.local>
Co-authored-by: L1nSn0w <l1nsn0w@qq.com>
Co-authored-by: yyh <92089059+lyzno1@users.noreply.github.com>
2026-09-07 03:19:07 +00:00
非法操作
4b0e260ac5 refactor(console): decouple app tracing configuration (#41576) 2026-09-07 02:47:00 +00:00
yyh
dde1d500b5 docs: clarify frontend guidance ownership and dependencies (#41848) 2026-09-05 13:28:40 +00:00
chenshiyang
3c55dcc3d1 refactor(models): pass session into AppAnnotationHitHistory accessors (#41832)
Co-authored-by: Claude <noreply@anthropic.com>
2026-09-05 10:32:30 +00:00
chenshiyang
fde602dadf refactor(models): pass session into tool provider accessors (#41830)
Co-authored-by: Claude <noreply@anthropic.com>
2026-09-05 10:31:41 +00:00
Eddy ZHANG
d69b19b567 refactor(web): dep-inject the passport query with @model_validate (#41845) 2026-09-05 10:31:05 +00:00
yyh
00e5786067 fix(select): isolate trigger states and unavailable package selection (#41843) 2026-09-05 03:49:39 +00:00
Stephen Zhou
ad90cb9111 fix: preserve generated API contracts during local development (#41834) 2026-09-04 14:48:46 +00:00
yyh
a2acf62bf1 fix: align select and autocomplete collection contracts (#41829) 2026-09-04 12:26:26 +00:00
Asuka Minato
08c7a2c5f3 test: migrate application generation sessions and ORM models to SQLite (#40509) 2026-09-04 12:16:31 +00:00
yyh
1b4ae3bcd2 fix(button): align loading accessibility contract (#41823) 2026-09-04 11:39:50 +00:00
yyh
2972468bc1 docs(web): align PreviewCard disclosure guidance (#41827) 2026-09-04 11:26:21 +00:00
Coding On Star
d93e5aa444 fix(web): append /api/v1 when SSR reads MARKETPLACE_API_URL (#41824)
Co-authored-by: fatelei <fatelei@gmail.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: zxhlyh <jasonapring2015@outlook.com>
Co-authored-by: CodingOnStar <hanxujiang@dify.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: 姜涵煦 <hanxujiang@jianghanxudeMacBook-Pro-2.local>
Co-authored-by: L1nSn0w <l1nsn0w@qq.com>
Co-authored-by: yyh <92089059+lyzno1@users.noreply.github.com>
2026-09-04 10:38:53 +00:00
非法操作
e6c9846726 refactor(api): isolate workflow app log queries (#41509) 2026-09-04 10:06:46 +00:00
Joel
6f37f0661d chore: use semantic tags for interactive elements (#41813) 2026-09-04 10:02:23 +00:00
yyh
dcb7b36ad4 refactor(dify-ui): adopt ID-backed combobox items (#41821) 2026-09-04 09:54:44 +00:00
Pranav Agarwal
067a60e0ac fix(api): enforce admin and RBAC permissions on model provider model credential GET endpoint (#41599) (#41600)
Co-authored-by: Yunlu Wen <yunlu.wen@dify.ai>
2026-09-04 09:17:41 +00:00
非法操作
b15fb30ff5 refactor(api): extract app statistic queries from console controllers (#41557) 2026-09-04 09:15:51 +00:00
yyh
bb7114c2e8 chore: bump base-ui to 1.8.0 (#41820) 2026-09-04 09:15:18 +00:00
Asuka Minato
7128456d57 test: migrate core agent runner sessions and ORM models to SQLite (#40508) 2026-09-04 08:50:33 +00:00
yyh
751023c107 perf(agent-v2): flatten build draft request waterfalls (#41816) 2026-09-04 08:49:05 +00:00
github-actions[bot]
16f5e8738b chore(i18n): sync translations with en-US (#41817)
Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Co-authored-by: yyh <92089059+lyzno1@users.noreply.github.com>
2026-09-04 08:47:42 +00:00
yyh
173e92ea24 docs(dify-ui): document combobox chip keyboard hints (#41815) 2026-09-04 08:37:08 +00:00
bucketbase26
b5ee943a63 fix(trigger): sync plugin relationships on publish (#41756) 2026-09-04 08:33:48 +00:00
eux
7919df7ef5 fix(api): skip invalid markdown image URLs (#41343) 2026-09-04 08:17:33 +00:00
非法操作
f8930aba34 refactor(api): extract console workflow run application service (#41336) 2026-09-04 08:16:49 +00:00
Coding On Star
cb6c04637b feat(web): add marketplace creator profiles and homepage redesign (#41538)
Co-authored-by: zxhlyh <jasonapring2015@outlook.com>
Co-authored-by: fatelei <fatelei@gmail.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: CodingOnStar <hanxujiang@dify.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: 姜涵煦 <hanxujiang@jianghanxudeMacBook-Pro-2.local>
Co-authored-by: L1nSn0w <l1nsn0w@qq.com>
Co-authored-by: yyh <92089059+lyzno1@users.noreply.github.com>
2026-09-04 08:09:45 +00:00
Zhu Lei
949f6c4ad4 fix(api): correct Service API segments has_more pagination (#41776) 2026-09-04 08:00:53 +00:00
yyh
7d7390ddaf fix(web): allow CookieYes consent logging (#41812) 2026-09-04 08:00:34 +00:00
yyh
b816754c06 fix(web): use stable error boundary retry (#41811) 2026-09-04 07:57:35 +00:00
Byron.wang
09f301d969 refactor(api): move OpenAPI account access behind application services (#41308) 2026-09-04 07:38:01 +00:00
Jialong(Bruce) Li
95aeb0c362 fix(skills): tolerate __MACOSX metadata folder when importing a Skill package (#41757) 2026-09-04 07:25:01 +00:00
yyh
336b134a40 refactor(web): migrate runtime app inputs (#41806) 2026-09-04 07:23:52 +00:00
Sourav Rajvi
e0673077a7 fix: close unclosed think tags around agent tool calls (#41764)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-09-04 07:23:34 +00:00
Zhu Lei
acf18aad13 fix(api): keep segment attachments when attachment_ids omitted (#41777) 2026-09-04 07:21:32 +00:00
Zhu Lei
1942925eb1 fix(api): persist plugin trigger subscription expires_at from provider (#41773) 2026-09-04 07:21:17 +00:00
Crazywoola
f5c14295b4 chore: use emoji issue labels 2026-09-04 15:49:27 +08:00
Zhu Lei
5355edefe3 fix(api): correct dataset and document list has_more pagination (#41784) 2026-09-04 07:19:33 +00:00
Jean-Rémi Larcelet-Prost
b3b92f11af docs(api): Fix reformat script path in api/README.md (#41658) 2026-09-04 15:28:03 +08:00
dependabot[bot]
621ab7d19b chore(deps-dev): bump mkdocs-material from 9.7.6 to 9.7.7 in /dify-agent (#41767)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-04 15:22:59 +08:00
yyh
0d8ad27b14 test: split skill detail page suite (#41799) 2026-09-04 07:06:33 +00:00
yyh
9e68c45058 fix(ci): avoid npm bootstrap in web setup (#41804) 2026-09-04 06:53:54 +00:00
Joel
6208b33e08 chore: correct ARIA roles and preserve control interactions (#41738)
Co-authored-by: yyh <yuanyouhuilyz@gmail.com>
2026-09-04 06:06:02 +00:00
非法操作
cea89f784f refactor: make explore localization request-driven (#41798) 2026-09-04 06:03:46 +00:00
非法操作
8504aaa0ef fix(api): support Lao as a display language (#41743) 2026-09-04 05:51:34 +00:00
Byron.wang
81abb7322d ci: parallelize change detection and gate style jobs (#41678)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-09-04 05:05:30 +00:00
Sourav Rajvi
5b13b7a44d refactor(models): use sa.false()/sa.true() for boolean server defaults (#41762)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-09-04 02:50:27 +00:00
Yunlu Wen
2619d172dc chore: run dify-agent typecheck in python-style (#41701)
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-09-04 02:40:55 +00:00
yyh
d9ff45022b chore(web): enforce query options lint (#41754) 2026-09-04 02:37:21 +00:00
Wu Tianwei
550196e3b8 feat: app deployment v2 (#41444)
Co-authored-by: zhangx1n <zhangxin@dify.ai>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-09-04 02:01:35 +00:00
非法操作
8e2058a962 refactor: pass notification language explicitly (#41770) 2026-09-04 01:52:30 +00:00
Sourav Rajvi
df0460f876 fix(binding-files): keep UTF-8 text preview when max_bytes splits a character (#41761) 2026-09-04 01:35:32 +00:00
yyh
65b4091402 refactor(query): migrate imperative APIs to query semantics (#41746) 2026-09-03 13:54:48 +00:00
Keith
e6a38fd793 refactor(models): remove legacy db.session property wrappers on Document (#41721) 2026-09-03 13:34:49 +00:00
非法操作
8c98e3fad5 refactor(web): align account preference requests with API contracts (#41748) 2026-09-03 12:55:44 +00:00
非法操作
24f9f07752 fix(web): map pt-BR to pt_BR for tool metadata (#41745) 2026-09-03 12:54:46 +00:00
yyh
4beffa97e0 refactor(web): migrate runtime variable inputs (#41739)
Co-authored-by: Joel <iamjoel007@gmail.com>
2026-09-03 09:38:39 +00:00
Joel
aee0062cb2 chore: remove redundant aria-label attributes (#41724)
Co-authored-by: yyh <yuanyouhuilyz@gmail.com>
2026-09-03 09:10:16 +00:00
yyh
863930836b chore(dify-ui): enable purity lint in tests (#41736) 2026-09-03 09:00:30 +00:00
zyssyz123
a702b3bb2b fix(agent): surface missing tool credentials (#41726) 2026-09-03 08:53:55 +00:00
Byron.wang
692010f0fc refactor(api): decouple console OAuth flow from legacy account services (#41188)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-09-03 08:47:14 +00:00
github-actions[bot]
363753a0c5 chore(i18n): sync translations with en-US (#41733)
Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Co-authored-by: yyh <92089059+lyzno1@users.noreply.github.com>
2026-09-03 08:46:49 +00:00
yyh
e982a3de33 test(web): remove workspace switcher browser test (#41728) 2026-09-03 08:06:17 +00:00
Stephen Zhou
137eb19de9 chore(web): prune unused i18n keys (#41725) 2026-09-03 08:01:55 +00:00
Zhu Lei
612a929907 fix(web): stringify object editor values before Monaco createModel (#41719) 2026-09-03 07:51:41 +00:00
Stephen Zhou
29acaabc6a chore(web): canonicalize Tailwind classes (#41718) 2026-09-03 07:33:05 +00:00
Jingyi
642ad2fffe fix(web): align workspace switcher states and semantics (#41713) 2026-09-03 07:18:49 +00:00
Benjamin
8f7cca3ae2 fix(web): guard LLM node model_selector against persisted null (#41707) 2026-09-03 06:20:48 +00:00
Byron.wang
b015aa416f refactor(api): extract account login service and consolidate adapters (#41184) 2026-09-03 06:20:21 +00:00
非法操作
ba1d5ba172 refactor(api): centralize remote file handling (#41627) 2026-09-03 06:00:13 +00:00
zyssyz123
688107c3e5 fix(api): bound suggested question generation latency (#41705) 2026-09-03 05:02:09 +00:00
非法操作
d8c3f7c5ee refactor(openapi): inject file upload service (#41606) 2026-09-03 04:42:31 +00:00
非法操作
69484a07e1 refactor(console): inject file service (#41603) 2026-09-03 04:42:30 +00:00
非法操作
5f4b1f867d refactor(web): inject file upload service (#41586) 2026-09-03 04:42:30 +00:00
Eddy ZHANG
fc7193cf04 refactor(service_api): dep-inject the dataset create payload with @model_validate (#41651) 2026-09-03 03:52:41 +00:00
yyh
59021616d4 refactor(web): migrate legacy form controls to Dify UI (#41682) 2026-09-03 03:50:23 +00:00
非法操作
ab0e92b893 refactor(service-api): inject file upload service (#41585) 2026-09-03 03:41:45 +00:00
Wu Tianwei
b0b495d243 feat(web): make markdown form field name length configurable (#41697) 2026-09-03 03:21:10 +00:00
yyh
6536ffc422 docs(web): clarify browser mode focus test boundary (#41692) 2026-09-03 02:48:08 +00:00
Stephen Zhou
b7570ce4b7 chore(dify-ui): migrate class merging to cn (#41693) 2026-09-03 02:31:52 +00:00
dependabot[bot]
907bc2558b chore(deps): bump transformers from 5.5.0 to 5.10.1 in /api (#41609)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-03 01:50:39 +00:00
Eddy ZHANG
95a6a14ed5 refactor(console,web): dep-inject query params with @model_validate (#41646) 2026-09-03 01:50:22 +00:00
Byron.wang
be7d11ca1d refactor(api): extract forgot password application service (#41111)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-09-03 01:38:59 +00:00
Asuka Minato
8129555642 chore: Site to typebase (#35632) 2026-09-02 14:44:08 +00:00
dependabot[bot]
f28d993607 chore(deps): bump transformers from 5.6.2 to 5.10.1 in /dify-agent (#41608)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-02 14:36:06 +00:00
github-actions[bot]
0fc01fee3f chore(i18n): sync translations with en-US (#41669)
Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
2026-09-02 11:36:24 +00:00
yyh
bc716020c7 perf(web): load Zendesk on support intent (#41653) 2026-09-02 10:32:47 +00:00
YungLe
3cd1fc098c feat: allow knowledge base API keys to be scoped to a single dataset (#37569)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-09-02 10:30:42 +00:00
yyh
7664ad7149 fix(web): align avatar file extension with output type (#41662) 2026-09-02 10:22:59 +00:00
Yunlu Wen
b1eafb0d82 fix: validate rule for provider scoped credentials (#41659) 2026-09-02 10:07:44 +00:00
Ingram Z
a1a10f17e3 fix(dify-agent): harden E2B binding lifecycle (#41623)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-09-02 09:47:24 +00:00
Joel
6ae40b1f15 fix: preserve Swagger tool authorization after refresh (#41656) 2026-09-02 09:13:51 +00:00
yyh
e577c007a0 fix(web): stabilize Home and Studio route titles (#41654) 2026-09-02 09:03:58 +00:00
yyh
02855848ea perf(web): downsample static account avatars (#41655) 2026-09-02 09:02:46 +00:00
dependabot[bot]
98090d60b3 chore(deps): bump pypdf from 6.14.2 to 6.16.1 in /dify-agent (#41604)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-02 08:03:07 +00:00
非法操作
59ee8878f9 refactor(api): require active workspace in request context (#41280) 2026-09-02 06:54:47 +00:00
Wu Tianwei
82d86dcf98 feat: app access point permission (#41631)
Co-authored-by: fatelei <fatelei@gmail.com>
2026-09-02 06:34:33 +00:00
yyh
183741b5f7 refactor(web): migrate webapp email code inputs (#41634) 2026-09-02 06:22:21 +00:00
yyh
de3f3714ae refactor(web): migrate webapp reset password inputs (#41633) 2026-09-02 06:22:20 +00:00
yyh
415e999cef refactor(web): migrate console reset password inputs (#41632) 2026-09-02 06:22:19 +00:00
Joel
c25b439d8b fix: improve snippets list accessibility (#41579)
Co-authored-by: yyh <yuanyouhuilyz@gmail.com>
2026-09-02 04:39:17 +00:00
QuantumGhost
324ee5f036 fix(api): tolerate workflow pause snapshot cleanup failure (#41581) 2026-09-02 04:33:04 +00:00
yyh
8707d0c82f docs(e2e): refine Playwright and Cucumber skill guidance (#41617) 2026-09-02 03:45:41 +00:00
Eddy ZHANG
4d9bda7422 refactor(inner_api): dep-inject request payloads with @model_validate (#41575) 2026-09-02 03:40:46 +00:00
yyh
88c64a8db9 refactor(web): migrate access point mutations (#41614) 2026-09-02 03:17:03 +00:00
Eddy ZHANG
a5445f2424 refactor(service_api): dep-inject segment payloads with @model_validate (#41571) 2026-09-02 02:59:30 +00:00
dependabot[bot]
334a3043bc chore(deps): bump pypdf from 6.15.0 to 6.16.1 in /api (#41607)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-02 01:56:41 +00:00
Xiyuan Chen
93dae7d8a0 fix(rbac): let agent.manage operate every agent page (#41583)
Co-authored-by: yunlu.wen <yunlu.wen@dify.ai>
2026-09-02 01:45:42 +00:00
yyh
ea98d38c3d refactor(web): migrate webhook table input (#41612) 2026-09-02 01:44:52 +00:00
yyh
18ac946e2b refactor(web): migrate dataset settings name input (#41611) 2026-09-02 01:44:51 +00:00
yyh
baf629dd36 refactor(web): migrate external API selection input (#41610) 2026-09-02 01:44:51 +00:00
dependabot[bot]
a3dbf9293a chore(deps-dev): bump nltk from 3.10.0 to 3.10.3 in /api (#41602)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-09-02 01:20:41 +00:00
yyh
3f982e3dc8 ci(e2e): shard pull request browser tests (#41596) 2026-09-02 01:19:08 +00:00
yyh
6bc7f01261 fix(web): announce agent draft status (#41595) 2026-09-01 11:53:05 +00:00
Byron.wang
c4ea406586 refactor(api): decouple system features and web adapters (#40772)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-09-01 11:50:52 +00:00
Asuka Minato
7978352262 test: migrate dataset download sessions and ORM models to SQLite (#40630) 2026-09-01 09:28:50 +00:00
Asuka Minato
980a9d4ed4 test: migrate dataset retrieval sessions and ORM models to SQLite (#40548) 2026-09-01 09:28:33 +00:00
Asuka Minato
d337c59916 test: migrate workspace member sessions and ORM models to SQLite (#40523) 2026-09-01 09:27:46 +00:00
Asuka Minato
c45e5386fb test: migrate agent-v2 workflow sessions and ORM models to SQLite (#40514) 2026-09-01 09:25:46 +00:00
QuantumGhost
d6e4f48526 fix(web): merge workflow tool outputs from all End nodes (#41517)
Co-authored-by: twwu <twwu@dify.ai>
2026-09-01 08:50:37 +00:00
QuantumGhost
27c2f058fe fix(web): publish workflow before creating tool (#41528) 2026-09-01 07:52:07 +00:00
yyh
8e064ffe98 chore: upgrade Node.js runtime to 24 LTS (#41573) 2026-09-01 06:57:38 +00:00
zyssyz123
fe39211aac fix(agent): bound Redis run event streams (#41566)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-09-01 06:47:16 +00:00
Joel
770b83d9cc fix: handle published workflow request failures in access points (#41572) 2026-09-01 06:37:25 +00:00
Keith
566b8857dd refactor(models): remove legacy db.session property wrappers on Dataset (#41569) 2026-09-01 06:28:24 +00:00
elyar1124
3ed28dce33 refactor(models): pass session into DocumentSegment and AppDatasetJoin accessors (#41568) 2026-09-01 06:24:04 +00:00
Joel
fdca3e2a1a chore: enforce titles on CSS-truncated elements (#41438) 2026-09-01 06:18:53 +00:00
Eddy ZHANG
6411d6235c refactor(service_api): dep-inject query params with @model_validate (#41562) 2026-09-01 05:55:50 +00:00
Eddy ZHANG
1977355dd1 refactor(console): dep-inject model provider payloads with @model_validate (#41539) 2026-09-01 04:24:45 +00:00
yyh
520e5e2beb chore(deps): upgrade workspace dependencies (#41564) 2026-09-01 04:19:06 +00:00
Joel
5cbc42cd38 chore: Revert "feat: use app.acl.access_point_manage to control access point page access" (#41563) 2026-09-01 03:46:03 +00:00
yyh
765e6338d2 fix(plugin): prevent install dialog error overflow (#41561) 2026-09-01 03:34:23 +00:00
yyh
62221bf8b8 refactor(web): align skills card semantics (#41559) 2026-09-01 02:36:21 +00:00
yyh
8f2ff3a8fb refactor(plugins): migrate credential rename input (#41552) 2026-09-01 01:44:44 +00:00
yyh
f92f7e92c3 refactor(workflow): migrate email subject input (#41551) 2026-09-01 01:44:43 +00:00
yyh
72458d5750 refactor(workflow): migrate schedule cron input (#41550) 2026-09-01 01:44:43 +00:00
Xiyuan Chen
ce801f4445 fix(web): hide Open in Explore for SSO-restricted apps (#41518)
Co-authored-by: yyh <yuanyouhuilyz@gmail.com>
2026-09-01 01:10:03 +00:00
yyh
57144b0094 docs(frontend): clarify transient state ownership (#41541) 2026-08-31 13:37:22 +00:00
Xiyuan Chen
b71dcb8253 fix(web): reset test-email sender state when reopening the modal (#41515)
Co-authored-by: yyh <yuanyouhuilyz@gmail.com>
2026-08-31 12:15:40 +00:00
zyssyz123
762019a160 fix(workflow): block manual runs for trigger workflows (#41519)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-31 09:30:52 +00:00
Yunlu Wen
39f06b6f05 chore(dify-agent): make local dev work with defaults out of the box (#41533)
Co-authored-by: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-08-31 08:37:30 +00:00
-LAN-
d0a86cfd4e fix(workflow): allow human input in iteration and loop (#40061) 2026-08-31 08:28:17 +00:00
Joel
336dd0b8c0 fix: hide chat features drawer while opener dialog is active (#41530) 2026-08-31 08:01:55 +00:00
Jingyi
6da1b473e6 fix(web): align tool plugin card layout (#41525) 2026-08-31 07:25:06 +00:00
Joel
f021ee4dc0 fix: prevent the exit versions button from shrinking (#41527) 2026-08-31 07:23:45 +00:00
Joel
280f81757d fix: stabilize node block selectors and restore start tabs (#41523) 2026-08-31 06:58:56 +00:00
Asuka Minato
1952cff091 test: migrate model and agent sessions to SQLite (#40087) 2026-08-31 05:57:40 +00:00
Asuka Minato
f8f71fdc68 test: migrate audit findings sessions and ORM models to SQLite (#40551) 2026-08-31 05:55:38 +00:00
Asuka Minato
9398482b53 test: migrate console dataset sessions and ORM models to SQLite (#40521) 2026-08-31 05:55:12 +00:00
Asuka Minato
5db79a77e4 test: migrate advanced chat generator sessions and ORM models to SQLite (#40585) 2026-08-31 05:51:30 +00:00
Jingyi
02222e8fce fix(web): preserve plugin footer text layout (#41514) 2026-08-31 05:50:29 +00:00
yyh
5a5b9c6fec fix(web): make plugin detail drawer non-modal (#41473) 2026-08-31 05:46:55 +00:00
Byron.wang
d25e2b51fc refactor(api): decouple onboarding and notification services (#40759)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: hjlarry <hjlarry@163.com>
2026-08-31 04:37:07 +00:00
Coding On Star
c6ca395042 fix(web): make registration tracking consent-safe and retryable (#41365)
Co-authored-by: CodingOnStar <hanxujiang@dify.com>
2026-08-31 03:39:37 +00:00
Wu Tianwei
7167d7d662 fix(rbac): grant agent access to all legacy roles (#41511) 2026-08-31 03:33:09 +00:00
Byron.wang
9e07c2dac6 refactor(api): extract email registration application service (#41108)
Co-authored-by: hjlarry <hjlarry@163.com>
2026-08-31 03:22:01 +00:00
wangxiaolei
6a00c23e49 feat: use app.acl.access_point_manage to control access point page access (#41462)
Co-authored-by: twwu <twwu@dify.ai>
2026-08-31 03:05:19 +00:00
Xiyuan Chen
750810ea81 fix(api): keep workspace owner consistent on ownership transfer (#41267) 2026-08-31 02:51:19 +00:00
非法操作
b70ad7d424 fix(web): show DSL import warning details (#41502) 2026-08-31 02:36:32 +00:00
zyssyz123
ad86351cc1 fix(agent): reject incompatible session snapshots (#41447) 2026-08-31 02:26:07 +00:00
dependabot[bot]
8b8031710b chore(deps): bump anthropics/claude-code-action from 1.0.199 to 1.0.210 in the github-actions-dependencies group (#41504)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-08-31 01:25:59 +00:00
yyh
94dff4dddc fix(web): unify tool plugin selection state (#41470) 2026-08-31 01:24:49 +00:00
yyh
17ae89ff22 fix(e2e): target agent roster list items (#41453) 2026-08-31 01:24:04 +00:00
yyh
fce29e6f6a fix(web): refine agent dialog form sessions (#41492) 2026-08-31 01:24:03 +00:00
Eddy ZHANG
6130f081e0 refactor(console): dep-inject account payloads with @model_validate (#41500) 2026-08-31 00:52:10 +00:00
Eddy ZHANG
8894b09c3b refactor(web): dep-inject payloads with @model_validate (#41501) 2026-08-31 00:50:12 +00:00
yyh
bf64390d7c revert(web): revert dataset button a11y changes (#41493) 2026-08-30 16:00:14 +00:00
Eddy ZHANG
884ece570e refactor(service_api): dep-inject dataset payloads with @model_validate (#41490) 2026-08-30 15:06:36 +00:00
LuckTerence
9d396524b9 fix(web): improve a11y of dataset clickable divs with native buttons (#41319) 2026-08-30 13:00:42 +00:00
Eddy ZHANG
8b3c2ee274 refactor(service_api): dep-inject app payloads with @model_validate (#41491) 2026-08-30 12:51:50 +00:00
Weike Zhang
02f9b3ca7c refactor: pass db.session explicitly in instruction_modify_workflow (#37403) (#40827) 2026-08-30 00:48:00 +00:00
jjj-n
09054169c4 refactor(models): pass session into Workflow accessors (#41464) 2026-08-29 14:28:15 +00:00
Asuka Minato
0f3cde8120 test: migrate application DSL sessions and ORM models to SQLite (#40554) 2026-08-29 14:06:07 +00:00
Asuka Minato
2bdcbe96c5 test: enforce centralized config overrides (#40869) 2026-08-29 14:05:35 +00:00
Asuka Minato
3824323fe7 test: centralize core and service config overrides (#40868) 2026-08-29 14:05:34 +00:00
lin
1264d29a4f chore: remove unnecessary type conversions (#41454) 2026-08-29 07:04:18 +00:00
Terminator666666
f8dd276e2c refactor(controllers/console): dep-inject workflow payloads with @model_validate (#41244)
Co-authored-by: Terminator666666 <Terminator666666@users.noreply.github.com>
2026-08-28 14:49:46 +00:00
Eddy ZHANG
37988de678 refactor(service_api): dep-inject payloads with @model_validate (#41374) 2026-08-28 14:47:18 +00:00
Asuka Minato
92110e1982 test: centralize controller and storage config overrides (#40867) 2026-08-28 14:47:17 +00:00
Asuka Minato
d8e7a97b25 test: centralize account and feature config overrides (#40864) 2026-08-28 14:47:16 +00:00
Keith
e6fc0a8ba8 refactor(models): pass session into WorkflowAppLog accessors (#41440) 2026-08-28 14:32:27 +00:00
yyh
28e9a52ea5 feat(web): enhance app and agent card interactions (#41449) 2026-08-28 12:24:56 +00:00
Joel
efd90de70a fix: avoid duplicate error toast when applying agent build drafts (#41442) 2026-08-28 09:18:10 +00:00
Benjamin
aa208d2dd7 fix(web): give the favicon a single owner in root metadata (#41433)
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-28 08:57:04 +00:00
yyh
11bb82c731 fix(web): align agent roster card interactions (#41436) 2026-08-28 08:50:30 +00:00
yyh
78c85ae7c1 fix(agent): add roster publication status contract (#41435)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-28 08:50:30 +00:00
Joel
4c414988ee fix: improve accessibility across the apps list (#41393)
Co-authored-by: yyh <yuanyouhuilyz@gmail.com>
2026-08-28 07:55:59 +00:00
Xiyuan Chen
3bc4ac44e5 fix(ci): correct difyctl release and e2e workflow gates (#41355) 2026-08-28 06:56:25 +00:00
Jingyi
94fdda18e2 fix(web): prevent tool card footer clipping (#41430) 2026-08-28 05:36:13 +00:00
yyh
0b11d34d4b fix(web): align web app sidebar spacing (#41425) 2026-08-28 05:34:32 +00:00
wangxiaolei
ff5d431efd feat: hide skill_entry when use has no skill.view permission (#41429) 2026-08-28 05:13:38 +00:00
alanhuangyoo
97b5d8092c ci: run the dify-agent test suite (#41327) 2026-08-28 05:09:34 +00:00
Wu Tianwei
f7d6cd1afe fix(web): block resource access for Agent apps (#41424) 2026-08-28 03:43:48 +00:00
Wu Tianwei
1971450ad8 fix: protect workspace owners in resource access (#41423) 2026-08-28 03:03:40 +00:00
Keith
c8606db16b refactor(models): pass session into ChildChunk accessors (#41370)
Co-authored-by: ke-yu <ke-yu@pepabo.com>
2026-08-28 02:30:10 +00:00
chenshiyang
654324c0d9 refactor(models): pass session into PipelineCustomizedTemplate.created_user_name (#41394)
Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-28 02:26:41 +00:00
huyua9
650f8880ea docs: correct UUIDv7 helper docstring (#41419)
Co-authored-by: huyua9 <huyua9@users.noreply.github.com>
2026-08-28 02:26:40 +00:00
yyh
f7e71ca9e1 refactor(web): simplify pricing components (#41416) 2026-08-28 01:37:01 +00:00
yyh
290acf1b73 fix(ui): keep scroll area focus indicator visible (#41404) 2026-08-28 01:37:00 +00:00
-LAN-
458c96d5ba fix(api): preserve tracing configuration boundaries (#41403) 2026-08-27 22:11:32 +08:00
Benjamin
2a554ab2d1 perf(web): virtualize the Web Apps sidebar list again (#41397)
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-authored-by: yyh <yuanyouhuilyz@gmail.com>
2026-08-27 13:45:50 +00:00
Asuka Minato
3ce262de05 test: migrate agent service sessions and ORM models to SQLite (#40598) 2026-08-27 12:15:36 +00:00
Asuka Minato
3ea5f38e92 test: migrate human input sessions and ORM models to SQLite (#40597) 2026-08-27 12:15:07 +00:00
lei_lei
8c25190713 fix(api): raise Socket.IO max_http_buffer_size for large workflows (#41347) 2026-08-27 11:48:42 +00:00
yyh
9c16c86597 revert(web): restore Agentation devtool (#41387) 2026-08-27 09:09:44 +00:00
wangxiaolei
d84088ef74 feat: new user add automatic add to app / dataset whitelist (#41363) 2026-08-27 08:51:05 +00:00
yyh
a38ddd9d02 fix: align documentation links with stable anchors (#41384) 2026-08-27 08:38:41 +00:00
Joel
d94204ec33 feat: track inline agent and preview mode events (#41373) 2026-08-27 08:09:09 +00:00
HelloSrauker
1db542c706 fix(workflow): correct loop boolean break condition values (#41186) 2026-08-27 08:02:52 +00:00
yyh
15021ad350 chore(web): remove Agentation devtool (#41372) 2026-08-27 07:54:27 +00:00
yyh
59383e88c2 fix(web): refine agent configure section states (#41371) 2026-08-27 07:51:07 +00:00
wangxiaolei
05b00574aa chore: add permission check back (#41369) 2026-08-27 07:45:50 +00:00
yyh
5aac67f570 test(e2e): wait for apps console readiness (#41357) 2026-08-27 07:40:23 +00:00
Joel
1be72af661 fix: allow publishing workflows with legacy Agent nodes (#41368) 2026-08-27 07:26:48 +00:00
Asuka Minato
1ccac4792c test: migrate knowledge file access sessions and ORM models to SQLite (#40596) 2026-08-27 07:19:20 +00:00
Asuka Minato
d67a8323c5 test: migrate agent observability sessions and ORM models to SQLite (#40588) 2026-08-27 07:18:58 +00:00
Asuka Minato
ef20a16a2f test: migrate explore installed app sessions and ORM models to SQLite (#40525) 2026-08-27 07:18:32 +00:00
Asuka Minato
1efc71c624 test: migrate Service API dataset segment sessions and ORM models to SQLite (#40517) 2026-08-27 07:17:41 +00:00
Joel
54298abf2d fix: improve home page accessibility (#41310)
Co-authored-by: yyh <yuanyouhuilyz@gmail.com>
2026-08-27 07:03:01 +00:00
非法操作
735d814dc0 fix(web): use management provider list for MCP integrations (#41360) 2026-08-27 06:49:47 +00:00
QuantumGhost
3e12f0b9fb fix(api): ignore broken pipe during app stop checks 🤖🤖🤖 (#41356) 2026-08-27 06:39:06 +00:00
yyh
85b4626ac6 fix(web): route Agent V2 documentation links correctly (#41353) 2026-08-27 06:20:03 +00:00
yyh
8266d741e8 refactor(web): migrate tracing inputs (#41341) 2026-08-27 06:13:10 +00:00
yyh
3765a41b8c refactor(web): migrate workflow variable inputs (#41340) 2026-08-27 05:43:10 +00:00
wangxiaolei
6a1b23935f chore: remove permission check (#41349) 2026-08-27 05:29:38 +00:00
非法操作
bf54dd7814 refactor(api): remove unused workflow archived logs endpoint (#41345) 2026-08-27 03:48:57 +00:00
dependabot[bot]
1aa7ee29a1 chore(deps): bump h2 from 4.3.0 to 4.4.1 in /api (#40120)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-08-27 03:12:26 +00:00
非法操作
a9319c86ee refactor(api): extract workflow run archive application service (#41253) 2026-08-27 02:41:43 +00:00
非法操作
5a6191b96b refactor(api): extract workflow statistic query service (#41271) 2026-08-27 02:41:02 +00:00
yyh
ce31cdc585 refactor(web): migrate metadata inputs (#41339) 2026-08-27 02:40:08 +00:00
非法操作
32981687dd refactor: remove unused workflow run export endpoint (#41335) 2026-08-27 02:38:27 +00:00
非法操作
58d71bf9c9 fix(web): align model provider access permissions (#41329) 2026-08-27 02:27:57 +00:00
-LAN-
82520c144f fix(api): migrate legacy model types during upgrade (#41326) 2026-08-27 02:00:33 +00:00
Pranav Agarwal
0d05eae517 fix(api): enforce RBAC permission on agent composer GET endpoint (#41324) (#41325) 2026-08-26 20:09:25 +00:00
yyh
c8e29d9a7d fix(web): preserve link semantics in button-styled navigation (#41312) 2026-08-26 10:50:06 +00:00
Xin Zhang
638dfd77a4 fix: update secret environment variable description (#41309) 2026-08-26 10:08:30 +00:00
wangxiaolei
0047522b0d feat: add command cli to migration rbac scope to automatic_include_workspace_members (#41304) 2026-08-26 09:10:22 +00:00
Joel
ac23430aca fix: improve login and signup accessibility (#41301) 2026-08-26 08:16:15 +00:00
yyh
06482af260 test(e2e): stabilize Agent access toggles (#41282) 2026-08-26 07:56:28 +00:00
Byron.wang
30e6069851 refactor(api): thin OAuth controllers and extract application services (#40692) 2026-08-26 07:33:37 +00:00
github-actions[bot]
021d5ceae7 chore(i18n): sync translations with en-US (#41291)
Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Co-authored-by: yyh <92089059+lyzno1@users.noreply.github.com>
2026-08-26 07:31:34 +00:00
Wu Tianwei
73dd8739ef feat: optimize resource access config logic (#41164)
Co-authored-by: fatelei <fatelei@gmail.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-26 07:18:57 +00:00
林玮 (Jade Lin)
f5aaa50a30 fix(auth): normalize Gmail registration emails (#41249) 2026-08-26 07:14:27 +00:00
林玮 (Jade Lin)
8c9f248520 fix(api): attribute Skill Builder credit usage (#41290) 2026-08-26 07:02:45 +00:00
Taranum Wasu
6e0e32848e fix(human-input): align backend timeout handle with frontend DSL (#40746)
Co-authored-by: Taranum01 <50813317+Taranum01@users.noreply.github.com>
Co-authored-by: QuantumGhost <obelisk.reg+git@gmail.com>
2026-08-26 06:47:14 +00:00
非法操作
6ba29b3f0c chore(web): remove retired forum entry (#41289) 2026-08-26 06:47:13 +00:00
lei_lei
119e6af2a9 fix(api): honor DELETE JSON body in model_validate (#41288) 2026-08-26 06:38:13 +00:00
非法操作
c563528a2d refactor(api): standardize compliance downloads (#41057) 2026-08-26 06:32:13 +00:00
非法操作
c4ace15afd refactor(api): extract console app site command boundary (#41216) 2026-08-26 06:31:06 +00:00
ccl125
d5a8ace1c4 fix(rag-pipeline): mark credential-free datasources as authorized (#39772)
Co-authored-by: ccl125 <ccl125@users.noreply.github.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: FFXN <31929997+FFXN@users.noreply.github.com>
2026-08-26 05:44:10 +00:00
heyszt
86f8b847e9 fix(api): clean multimodal attachments in batch deletion (#41256) 2026-08-26 05:10:28 +00:00
Stephen Zhou
1c6f0a0388 fix(api): restore Service API OpenAPI semantics (#41274) 2026-08-26 05:05:36 +00:00
wangxiaolei
c937fcb21a feat: go to anything check enable skill (#41281) 2026-08-26 04:46:10 +00:00
yyh
0a1ce09dfb refactor(web): migrate external knowledge input (#41278) 2026-08-26 04:44:52 +00:00
yyh
b9ac4d3cb1 refactor(web): migrate dataset settings input (#41277) 2026-08-26 04:44:51 +00:00
yyh
e4cd2c72ad refactor(web): migrate document metadata input (#41276) 2026-08-26 04:44:50 +00:00
Joel
dfe396fb64 fix: separate WebApp analytics from console page tracking (#41251) 2026-08-26 03:02:38 +00:00
Pranav Agarwal
6b5952425d fix(api): enforce RBAC permission on agent app detail GET endpoint (#41264) (#41265) 2026-08-26 02:51:13 +00:00
samzong
1299d99b2d feat(cli): add a compact command map for agent discovery (#41226)
Signed-off-by: samzong <samzong.lu@gmail.com>
2026-08-26 01:13:07 +00:00
yyh
36dfc5abd3 fix(web): upgrade Next.js to 16.3.3 (#41262) 2026-08-26 00:32:30 +00:00
yyh
c7520d7c71 refactor(ci): trim redundant autofix work (#41259) 2026-08-25 13:10:06 +00:00
yyh
798a238e63 fix(web): align goto anything autocomplete behavior (#41258) 2026-08-25 12:39:07 +00:00
yyh
db5121828e fix(agent-v2): refine access card interactions (#41254) 2026-08-25 12:25:49 +00:00
yyh
ed184a6632 fix(web): restore AI credits icon (#41257) 2026-08-25 12:22:49 +00:00
Stephen Zhou
92016aa139 fix(api): align Service API OpenAPI contract (#41248)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-25 10:54:14 +00:00
Yunlu Wen
09a855dcef chore: bump version to 1.17.0 (#41247)
Co-authored-by: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-08-25 10:52:21 +00:00
wangxiaolei
a6fe278662 feat: hide add library skill in agent ui (#41250)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-25 10:26:06 +00:00
林玮 (Jade Lin)
960018253b feat(api): track credit usage contexts (#41181)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-25 10:21:32 +00:00
yyh
8abff1b0b1 refactor(web): migrate dataset rename form (#41233) 2026-08-25 09:41:37 +00:00
yyh
eb7a1829fe refactor(web): migrate pipeline DSL import form (#41232) 2026-08-25 09:41:36 +00:00
yyh
9ce92d8605 fix(ui): add tabs panel focus treatment (#41231) 2026-08-25 09:41:36 +00:00
wangxiaolei
ddcdbb2d14 feat: add skill enable feature switch (#41246) 2026-08-25 08:42:15 +00:00
Joel
18d3990ae6 fix: show a not-allowed cursor for the prompt editor in build mode (#41243) 2026-08-25 07:43:32 +00:00
zxhlyh
03e4bc50a2 fix(skills): align Japanese Skills page title (#41242) 2026-08-25 07:42:23 +00:00
Joel
370efc493c fix: prevent sidebar footer actions from triggering hover preview (#41230) 2026-08-25 06:53:52 +00:00
Rafli Surya Wijaya
cf236aed8a fix(api): enforce APP_EDIT RBAC permission on MCP server refresh endpoint (#41235) 2026-08-25 06:38:13 +00:00
Asuka Minato
48315be2b1 test: migrate RAG variable controller sessions and ORM models to SQLite (#40609)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-25 06:20:48 +00:00
Asuka Minato
a9035a3264 test: migrate step-by-step tour sessions to SQLite (#40636) 2026-08-25 06:20:13 +00:00
Asuka Minato
39ce9f68fc test(vdb): use real ORM models in provider tests (#40687) 2026-08-25 06:19:59 +00:00
Asuka Minato
ed9d3801ba test: move pure integration cases to unit tests (#40705)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-25 06:19:48 +00:00
Asuka Minato
f3bb73b671 test: centralize app and account config overrides (#40860) 2026-08-25 06:19:35 +00:00
wangxiaolei
bc845ea748 fix: fix skill display name rename conflict (#41229) 2026-08-25 06:13:47 +00:00
非法操作
1afac21690 feat(api): support New Agent Beta for inline Workflow agents (#41215) 2026-08-25 05:39:41 +00:00
samzong
dd2e691ea8 fix(cli): declare write effect for import and context-switch commands (#41225)
Signed-off-by: samzong <samzong.lu@gmail.com>
2026-08-25 05:32:55 +00:00
非法操作
f360a7bf94 fix: allow OAuth trigger builder verification without credentials (#39199)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-25 05:32:27 +00:00
Xiyuan Chen
caf7e90ca5 test(cli): tsconfig gap (#41224) 2026-08-25 05:11:44 +00:00
Alexey Shabalin
1e501cd75b fix(web): stop digits rendering in the emoji font (#41201)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-25 05:04:23 +00:00
盐粒 Yanli
45cb385d77 fix(docker): harden agent compose configuration (#41065) 2026-08-25 04:41:51 +00:00
Yunlu Wen
679514d40a perf(agent): exponential backoff in polling to prevent forking storm (#41222) 2026-08-25 04:36:46 +00:00
Yunlu Wen
9643dcacce perf(agent): polling interval tuning (#41221) 2026-08-25 03:50:22 +00:00
Joel
fcb380044c fix: enforce read-only agent resources in build mode (#41220) 2026-08-25 03:37:02 +00:00
向阳
d4ed92cb0a perf(api): batch recommended app catalog lookups (#41218) 2026-08-25 03:23:52 +00:00
Joel
12f259ecae fix: address Agent UX feedback (#41219) 2026-08-25 03:14:24 +00:00
Aarush Karak
d9ca69d34f fix(types): replace any[] with ThoughtItem[] for agent_thoughts (#41141)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-25 02:08:51 +00:00
Taranum Wasu
ebb0f12cd0 fix(model): re-sign bare/backticked tool file URLs in answer (#40799)
Co-authored-by: Taranum01 <50813317+Taranum01@users.noreply.github.com>
Co-authored-by: Taranum01 <taranumwasu@users.noreply.github.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Crazywoola <100913391+crazywoola@users.noreply.github.com>
2026-08-25 02:04:21 +00:00
zxhlyh
667d66c4dc fix(skills): align management UI accessibility and localization (#41180)
Co-authored-by: yyh <yuanyouhuilyz@gmail.com>
2026-08-25 01:53:19 +00:00
非法操作
ef92cb7c65 refactor(api): complete account education boundary (#41153)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-25 01:48:12 +00:00
dependabot[bot]
c9ea15a968 chore(deps): bump boto3 from 1.43.71 to 1.43.76 in /api in the storage group (#41126)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-08-25 10:00:23 +08:00
Jingyi
b56d30b366 fix(web): refresh model provider version after update (#41212) 2026-08-25 01:12:01 +00:00
yyh
8d6128957f fix(web): restore model selector popup spacing (#41190) 2026-08-24 15:05:22 +00:00
Joel
e25ca611d8 fix: failed e2e test in agent caused by changed copywriting (#41187) 2026-08-24 13:16:37 +00:00
Joel
44aec257bf fix: avoid copy-sensitive agent file toast assertion (#41179) 2026-08-24 10:33:25 +00:00
Joel
2be3c3d69e fix: refine agent configuration copy (#41177) 2026-08-24 09:58:06 +00:00
yyh
09b199b280 fix: keep pagination skeletons in app grid (#41175) 2026-08-24 09:35:54 +00:00
github-actions[bot]
b9764c4779 chore(i18n): sync translations with en-US (#41173)
Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
2026-08-24 09:08:26 +00:00
Harsh Kashyap
ff3cf5681f fix(api): attach exc_info=True to 11 logger.debug/info('...: %s', str(e)) sites — sibling of #41066 (DEBUG/INFO level) (#41077)
Co-authored-by: Harsh Kashyap <harsh23kashyap@gmail.com>
Co-authored-by: Asuka Minato <i@asukaminato.eu.org>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-24 09:08:08 +00:00
Asuka Minato
cfae2515fd test: remove obsolete integration coverage (#40704) 2026-08-24 09:06:29 +00:00
yyh
b5982927de fix: align main navigation card grids (#41167) 2026-08-24 09:04:30 +00:00
Xiyuan Chen
28a4859218 fix(api): respect configured model params in prompt generator (#41165) 2026-08-24 09:02:34 +00:00
QuantumGhost
4f8a4c20fd ci: add HITL IM test environment deployment (#41171) 2026-08-24 08:54:27 +00:00
Crazywoola
21d540f760 feat(web): enhance Go to Anything navigation and discovery (#41160) 2026-08-24 08:48:53 +00:00
Joel
fef28097cc fix: preserve agent task editor focus when inserting commands (#41166) 2026-08-24 08:33:29 +00:00
yyh
3de20e0ba8 fix: keep home intro without banner (#41155) 2026-08-24 08:30:55 +00:00
yyh
703f6d1780 fix(web): align agent v2 monitoring translations (#41161) 2026-08-24 08:21:41 +00:00
-LAN-
2e1620c1ac chore(api): enforce backend layer boundaries (#41159) 2026-08-24 08:17:11 +00:00
zyssyz123
4847447635 fix(agent): allow saving model-less inline Agent drafts (#41147) 2026-08-24 07:57:14 +00:00
Joel
7ce751ffe8 chore: show full agent save time on hover (#41148)
Co-authored-by: yyh <92089059+lyzno1@users.noreply.github.com>
2026-08-24 07:53:31 +00:00
Joel
7cb9aa2d3b fix: align duplicate agent name behavior with agent forms (#41156) 2026-08-24 07:48:33 +00:00
yyh
3ab8476d2d fix(web): align agent v2 monitoring copy (#41150) 2026-08-24 07:36:18 +00:00
yyh
643e2d66bf chore(deps): upgrade pnpm workspace dependencies (#41138) 2026-08-24 07:07:47 +00:00
Joel
693e1b0fc5 fix: show checklist errors for inline agents without models (#41146) 2026-08-24 06:57:34 +00:00
林玮 (Jade Lin)
70a513fc62 fix(api): scope hosted credits by tenant plan (#41131)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-24 06:35:42 +00:00
FFXN
bec4ef6ac7 fix: fix upload for plugin (#41133)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-24 05:39:27 +00:00
wangxiaolei
0024a845f7 feat: support agent skill (#39675)
Signed-off-by: kenwoodjw <blackxin55+@gmail.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: zxhlyh <jasonapring2015@outlook.com>
Co-authored-by: 起岚 <155608604+xiaoyaoqilan@users.noreply.github.com>
Co-authored-by: Parman Mohammadalizadeh <prmma23@gmail.com>
Co-authored-by: Escape0707 <tothesong@gmail.com>
Co-authored-by: Xin Zhang <zhangxin@dify.ai>
Co-authored-by: iridescentWen <66297467+iridescentWen@users.noreply.github.com>
Co-authored-by: Bond Zhu <37842169+MRZHUH@users.noreply.github.com>
Co-authored-by: KVOJJJin <jzongcode@gmail.com>
Co-authored-by: Joel <iamjoel007@gmail.com>
Co-authored-by: 非法操作 <hjlarry@163.com>
Co-authored-by: yyh <92089059+lyzno1@users.noreply.github.com>
Co-authored-by: Asuka Minato <i@asukaminato.eu.org>
Co-authored-by: Chester <superdiao6@gmail.com>
Co-authored-by: WH-2099 <wh2099@pm.me>
Co-authored-by: Jony <619963502@qq.com>
Co-authored-by: Jony <13896935+zyz619963502zyz@users.noreply.github.com>
Co-authored-by: Harsh Kashyap <harsh.kashyap2001@gmail.com>
Co-authored-by: Harsh Kashyap <Harsh23Kashyap@users.noreply.github.com>
Co-authored-by: kenwoodjw <blackxin55+@gmail.com>
Co-authored-by: csurong <csurong1@gmail.com>
Co-authored-by: caosurong <surong.cao@thinkingdata.cn>
Co-authored-by: Taranum Wasu <81034301+Taranum01@users.noreply.github.com>
Co-authored-by: Taranum01 <50813317+Taranum01@users.noreply.github.com>
Co-authored-by: Pranav Agarwal <agarwalpranav0711@gmail.com>
Co-authored-by: Stephen Zhou <hi@hyoban.cc>
Co-authored-by: zl86790 <marshal_li_b@163.com>
Co-authored-by: QuantumGhost <obelisk.reg+git@gmail.com>
Co-authored-by: yunlu.wen <yunlu.wen@dify.ai>
Co-authored-by: yyh <yuanyouhuilyz@gmail.com>
2026-08-24 05:29:14 +00:00
Crazywoola
0ab88ef36a chore: Replace star image with new asset link (#41136) 2026-08-24 04:33:24 +00:00
yyh
7b3d97cb42 refactor(web): migrate pipeline publishing input form (#41129) 2026-08-24 04:05:39 +00:00
yyh
429edf4d82 refactor(web): migrate pipeline template input form (#41128) 2026-08-24 04:05:38 +00:00
yyh
5a9b6cb239 refactor(web): migrate duplicate app input form (#41127) 2026-08-24 04:05:37 +00:00
Asuka Minato
bda6bf3fee test: migrate trigger and webhook sessions and ORM models to SQLite (#40594) 2026-08-24 04:01:02 +00:00
Joel
24287bcb0c fix: stabilize the agent tool picker placement (#41132) 2026-08-24 03:38:57 +00:00
AsperforMias
3f7e6cdcb4 fix(tts): propagate and validate actual audio MIME (#41043)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: WH-2099 <wh2099@pm.me>
2026-08-24 03:38:09 +00:00
Benjamin
ea6c15b68e fix: fall back to the batch API when the global plugin manifest is empty (#41107)
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-24 03:33:23 +00:00
dependabot[bot]
77998e41e4 chore(deps): bump gunicorn from 26.0.0 to 26.1.0 in /api in the flask group (#41118)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-08-24 03:28:14 +00:00
酒诗
aed1672366 refactor: pass session to workflow comment account accessors (#41117)
Co-authored-by: geneachina <geneachina@gmail.com>
2026-08-24 03:20:32 +00:00
dependabot[bot]
11c922b5d4 chore(deps): bump the github-actions-dependencies group with 4 updates (#41120)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-08-24 03:17:12 +00:00
XIIRUAN
ccd0f4b15d refactor(web): use shared session factory for JWT decoding (#41007) 2026-08-24 03:16:44 +00:00
lei_lei
ab34f9ae09 fix(workflow): honor stop between non-streaming nodes (#41090)
Co-authored-by: Crazywoola <100913391+crazywoola@users.noreply.github.com>
Co-authored-by: crazywoola <427733928@qq.com>
2026-08-24 02:51:20 +00:00
ump45nose
9385e583ff fix(agent): avoid empty Bedrock schema fields (#40443)
Co-authored-by: Crazywoola <100913391+crazywoola@users.noreply.github.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-24 02:08:11 +00:00
非法操作
5018f8aa8a refactor(api): standardize session factory wiring (#41085) 2026-08-24 01:57:17 +00:00
非法操作
ed45016475 refactor(api): standardize console billing portal errors (#41055)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-24 01:55:48 +00:00
陈志谦
9d6c846a49 docs: fix dead anchors in localized READMEs and stale dify-agent link (#41101) 2026-08-24 01:53:59 +00:00
yyh
8bdf702f73 fix(agent-v2): prevent workflow refresh render loop (#41105) 2026-08-23 08:56:02 +00:00
yyh
c62947f1f1 refactor(dify-ui): rename radio family entrypoint (#41104) 2026-08-23 08:08:29 +00:00
Pranav Agarwal
24f5e2ac69 fix(api): enforce admin and RBAC permissions on default model and provider models GET endpoints (#41099) (#41100) 2026-08-23 07:33:57 +00:00
yyh
e18310e52e refactor(dify-ui): simplify overlay content APIs (#41098) 2026-08-22 23:54:08 +00:00
Pranav Agarwal
07119e3f00 fix(api): enforce admin and RBAC permissions on data source integrates GET endpoint (#41079) (#41080) 2026-08-21 17:57:23 +00:00
yyh
a9b8c84e9b refactor(dify-ui): simplify popover content API (#41069) 2026-08-21 13:11:40 +00:00
盐粒 Yanli
35a4533889 refactor(agent): simplify Agent v2 output contract (#41062)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-21 11:55:25 +00:00
Blackoutta
3a8fbcbd02 feat(trace): add provider-neutral unified tracing (#39451)
Co-authored-by: EvoX <evox@evomap.ai>
2026-08-21 11:28:18 +00:00
mesrop2008
23150c2319 fix(api): attach exc_info=True to logger.warning sites that drop the traceback (#41068) 2026-08-21 11:20:42 +00:00
Xiyuan Chen
d6147456e3 feat: Enterprise Home Snapshot — runtime endpoints and dify-agent adapter (#40996) 2026-08-21 10:39:36 +00:00
gegemeimingzi
7d5c68c2e1 fix(web): prevent signin page content from overflowing on mobile (#40921)
Co-authored-by: gegemeimingzi <gegemeimingzi@users.noreply.github.com>
2026-08-21 10:36:31 +00:00
Rafli Surya Wijaya
385e8662bb fix(vdb): add document_id keyword mapping and fix VectorType in elasticsearch-ja adapter (#40400)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-21 10:35:54 +00:00
yyh
6cb96adfbe refactor(dify-ui): compose dialog close controls (#41064) 2026-08-21 10:21:43 +00:00
Yunlu Wen
373f33fd3b fix: add missing metrics back and enhance typing (#40935)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-21 09:46:45 +00:00
yyh
faca558bf5 fix(web): prevent Safari clipping tour recovery prompt (#41060) 2026-08-21 09:19:38 +00:00
Byron.wang
b38d907ede refactor(api): finish account controller application boundary (#40440) 2026-08-21 08:46:06 +00:00
Carson Yang
0c3d08f355 docs: add Sealos deployment option (#41026) 2026-08-21 08:15:35 +00:00
Byron.wang
a52adef203 refactor(api): extract change email state machine (#40439) 2026-08-21 08:13:23 +00:00
Byron.wang
3b05b5e553 refactor(api): move account lifecycle into application services (#40438) 2026-08-21 08:05:43 +00:00
Asuka Minato
92978f6d9f test: migrate console dataset segment sessions and ORM models to SQLite (#40515)
Co-authored-by: Byron.wang <byron@dify.ai>
2026-08-21 06:50:14 +00:00
Asuka Minato
6fe87aaca5 test: migrate residual app generator ORM models to SQLite (#40580)
Co-authored-by: Byron.wang <byron@dify.ai>
2026-08-21 06:49:58 +00:00
Asuka Minato
37a927bf63 test: migrate console agent skill ORM models to SQLite (#40570)
Co-authored-by: Byron.wang <byron@dify.ai>
2026-08-21 06:49:44 +00:00
yyh
44e89d8844 refactor(web): migrate external API input fields (#41052) 2026-08-21 06:38:21 +00:00
yyh
7b1339a156 refactor(web): migrate subscription confirmation input (#41051) 2026-08-21 06:38:21 +00:00
yyh
2ff3f7b533 refactor(web): migrate human input timeout field (#41050) 2026-08-21 06:38:20 +00:00
potoior
34fdac2113 fix: merge system messages and place them first to comply with Qwen/v… (#39136) 2026-08-21 06:24:20 +00:00
Asuka Minato
7d635d9f7e test: migrate auth and access controller ORM models to SQLite (#40572)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-21 06:12:29 +00:00
Asuka Minato
0ce41bfea1 test: migrate console app sessions and ORM models to SQLite (#40559) 2026-08-21 06:12:08 +00:00
Asuka Minato
92b93c9d37 test: migrate remaining controller sessions and ORM models to SQLite (#40538)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-21 06:11:44 +00:00
Asuka Minato
4692741aa0 test: migrate Agent App session store to SQLite ORM (#40638) 2026-08-21 06:10:31 +00:00
Asuka Minato
4ca0a10088 test: migrate vector space admission sessions and ORM models to SQLite (#40640) 2026-08-21 06:10:13 +00:00
Asuka Minato
6ce0976265 test: add tmp_path type (#40724)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-21 06:09:39 +00:00
Asuka Minato
5827ce2adf test: migrate annotation sessions and ORM models to SQLite (#40504) 2026-08-21 06:09:26 +00:00
Byron.wang
1d79b87307 refactor(api): move account access behind application services (#40437) 2026-08-21 05:56:30 +00:00
zl86790
9d8dacd0c8 fix(api): prevent dropped workflow_started events in Redis Streams (#40964)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: QuantumGhost <obelisk.reg+git@gmail.com>
2026-08-21 03:46:50 +00:00
yyh
720e1fab9b refactor(dify-ui): expose slider anatomy (#41045) 2026-08-21 03:15:45 +00:00
yyh
ca6f4e11f9 docs(dify-ui): establish documentation hierarchy (#41044) 2026-08-21 02:29:41 +00:00
WH-2099
a5e284e6b1 fix(plugin): protect endpoint listings (#40897) 2026-08-21 02:17:58 +00:00
Stephen Zhou
3d08b2f89a fix(web): route enterprise documentation links (#40957) 2026-08-21 02:13:26 +00:00
Pranav Agarwal
43e59d3bc5 fix(api): enforce edit and RBAC permissions on datasource credential …fix(api): enforce edit and RBAC permissions on datasource credential GET endpoint (#41040) (#41041) 2026-08-21 02:11:46 +00:00
WH-2099
edc805c453 fix(api): enforce app-scoped access on indirect resources (#40893) 2026-08-21 00:52:39 +00:00
Ingram Z
0ca99312c1 fix(agent): align Binding file upload timeouts (#41027) 2026-08-20 18:59:44 +00:00
wangxiaolei
785ca4b915 fix: when rbac enabled is true, not check_dataset_permission (#41022) 2026-08-20 14:45:40 +00:00
dependabot[bot]
c7b5a455f5 chore(deps): bump google-cloud-aiplatform from 1.160.0 to 1.164.0 in /api in the google group across 1 directory (#39249)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-08-20 13:48:44 +00:00
dependabot[bot]
0c698744ab chore(deps): bump the storage group across 1 directory with 2 updates (#40393)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-08-20 13:47:50 +00:00
hyhyf
e425e18fca fix: add MESSAGE_TRACE task on chat pipline error events (#39129)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-20 13:44:22 +00:00
yyh
f4e50f3c8a refactor(web): migrate empty dataset input (#41030) 2026-08-20 13:38:53 +00:00
yyh
aba3f9c1d6 refactor(web): migrate document rename input (#41029) 2026-08-20 13:38:52 +00:00
yyh
979c8cc34b refactor(web): migrate conversation rename input (#41028) 2026-08-20 13:38:51 +00:00
Asuka Minato
502418f707 test: centralize typed runtime config overrides (#40857)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-20 13:30:04 +00:00
蓝破碎半圆/破碎蓝调
ccfb47d2c5 feat: support ODT document extraction (#39973)
Co-authored-by: Crazywoola <100913391+crazywoola@users.noreply.github.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Asuka Minato <i@asukaminato.eu.org>
2026-08-20 13:23:03 +00:00
非法操作
1bb9183af9 refactor(api): replace legacy recommended app retrieval stack (#40395) 2026-08-20 13:13:43 +00:00
非法操作
de7e43a7ef refactor(api): decouple recommended app runtime admission (#40257) 2026-08-20 13:13:43 +00:00
非法操作
b09691e5d2 refactor(api): isolate trial app usage writes (#40208) 2026-08-20 13:13:42 +00:00
GGbond
6f70ca8d26 refactor(api): decouple console tag management (#40843)
Co-authored-by: Byron Wang <byron@dify.ai>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-20 12:31:01 +00:00
Fasih Ur Rahman
a7a30b20af fix(api): add missing admin and RBAC permission decorators to model credentials GET endpoints (#40962) 2026-08-20 12:15:13 +00:00
盐粒 Yanli
cbd78c0073 fix(agent): clean legacy Agent Soul files (#41024) 2026-08-20 10:34:11 +00:00
盐粒 Yanli
97a3039a2d refactor(dify-agent): use Workspace as shell temp space (#41023) 2026-08-20 10:16:05 +00:00
盐粒 Yanli
005edb7d47 fix(dify-agent): add reliable shellctl stdio mode (#39997) 2026-08-20 10:10:00 +00:00
盐粒 Yanli
b034368b3b fix(dify-agent): adjust local sandbox home paths (#41021) 2026-08-20 10:00:01 +00:00
Pranav Agarwal
43b6d8e32e fix(api): enforce admin and RBAC permissions on tool OAuth custom client GET endpoint (#40944) (#40945) 2026-08-20 09:10:02 +00:00
FFXN
248df5dd25 fix(snippet): support snippet history version export (#41012)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-20 08:52:45 +00:00
非法操作
f97fc01c2f refactor(api): extract recommended app query service (#40207) 2026-08-20 08:45:47 +00:00
林玮 (Jade Lin)
a6ace29e1a fix(api): handle suspended email domains (#41004)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-20 08:04:05 +00:00
盐粒 Yanli
013b328555 fix(agent): complete ownership-aware deletion lifecycle (#40888)
Co-authored-by: yyh <92089059+lyzno1@users.noreply.github.com>
2026-08-20 07:48:02 +00:00
chelsealong
d7b1531431 fix(snippets): implement delete for published snippet workflow versions (#41003)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-20 07:36:17 +00:00
yyh
63acefa6d0 fix(billing): remove misleading tax assurance (#41009) 2026-08-20 07:33:20 +00:00
Stephen Zhou
e2f6418fe4 chore: inline custom ESLint rules (#41008) 2026-08-20 07:32:13 +00:00
yyh
2daa69c92e fix(web): clarify agent deletion consequences (#41002) 2026-08-20 06:45:55 +00:00
yyh
72b6a4e6ed refactor: consolidate frontend browser test infrastructure (#40997) 2026-08-20 06:13:30 +00:00
yyh
b16a24f084 refactor(web): migrate install account fields (#40992) 2026-08-20 05:54:30 +00:00
Asuka Minato
6e890524db test: migrate snippet service ORM models to SQLite (#40567) 2026-08-20 05:12:30 +00:00
Asuka Minato
e27eb51f8a test: migrate media and execution service sessions and ORM models to SQLite (#40552) 2026-08-20 05:11:46 +00:00
Asuka Minato
2155adff5a test: migrate Explore controller sessions and ORM models to SQLite (#40537) 2026-08-20 05:10:49 +00:00
Asuka Minato
c2c1876484 test: migrate document service sessions and ORM models to SQLite (#40536) 2026-08-20 05:10:13 +00:00
非法操作
48f338e649 refactor(api): extract web app runtime bootstrap (#40949) 2026-08-20 05:05:31 +00:00
Byron.wang
b4e13ec83e refactor(api): add account profile application service (#40436)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-20 05:03:08 +00:00
yyh
11f830a17b ci(web): run browser tests on GitHub Ubuntu (#40995) 2026-08-20 04:24:32 +00:00
yyh
5550ec8ebf fix(web): redirect after deleting an agent (#40994) 2026-08-20 04:09:50 +00:00
yyh
ea59256349 refactor(web): migrate signup password fields (#40991) 2026-08-20 03:29:14 +00:00
yyh
0f1536585e refactor(web): migrate signup email field (#40990) 2026-08-20 03:29:13 +00:00
林玮 (Jade Lin)
602a646dbd fix(api): enforce dataset document ownership (#40989) 2026-08-20 03:24:45 +00:00
Amogh Bhat Nagri
54ffbc7f0f fix(logstore): normalize workflow timestamps to naive UTC (#40947)
Co-authored-by: wangxiaolei <fatelei@gmail.com>
2026-08-20 02:58:07 +00:00
WH-2099
ae20d64304 fix(ci): run Playwright E2E on GitHub Ubuntu (#40986) 2026-08-20 02:48:27 +00:00
非法操作
ee997d00fa refactor(api): reuse web app access queries for permissions (#40984) 2026-08-20 02:27:49 +00:00
yyh
98c2ffeec7 fix(ui): align toast swipe direction with viewport (#40980) 2026-08-19 13:16:12 +00:00
yyh
8e1c259a66 fix(web): prevent workflow errors after app deletion (#40977) 2026-08-19 12:24:40 +00:00
盐粒 Yanli
ea3fd4c093 perf(dify-agent): parallelize Agent Stub config pulls (#40973) 2026-08-19 10:35:24 +00:00
盐粒 Yanli
930f4e6c26 fix(dify-agent): persist interrupted run history (#40972) 2026-08-19 10:35:13 +00:00
非法操作
356e3a8ab6 refactor(api): snapshot explore banner feature flag (#40555) 2026-08-19 10:34:37 +00:00
非法操作
532489babd refactor(api): extract web app access queries (#40482) 2026-08-19 10:34:36 +00:00
yyh
6fa9c14490 fix(ui): stabilize toast stack interactions (#40970) 2026-08-19 10:13:43 +00:00
zyssyz123
d0149c3f94 fix(agent): resolve suggested questions from runtime config (#40963) 2026-08-19 07:54:38 +00:00
非法操作
2f6e782215 refactor(api): reuse app definition queries for service API site (#40795) 2026-08-19 07:23:47 +00:00
zyssyz123
414f211cde fix(auth): harden email code login verification (#40960) 2026-08-19 06:57:47 +00:00
Pranav Agarwal
f1b48a93a9 fix(api): enforce edit and RBAC permissions on model provider credential GET endpoints (#40899) (#40900) 2026-08-19 06:48:15 +00:00
盐粒 Yanli
8874f3c80b refactor(agent): remove Agent Drive (#40887)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-19 06:34:36 +00:00
yyh
297fdc7cb8 refactor(web): migrate HTTP timeout inputs (#40953) 2026-08-19 06:30:37 +00:00
yyh
73b15fc562 refactor(web): compose reset password fields (#40952) 2026-08-19 06:30:37 +00:00
yyh
90a6b8c998 refactor(web): simplify debounced filter state (#40951) 2026-08-19 06:30:36 +00:00
Riskey
8d18931125 fix: refine access point copy and remove undeploy state warning (#40886) 2026-08-19 04:11:44 +00:00
Nguyễn Phương
7444f96a1d refactor: clean away unnecessary-type-conversion (bool/str no-op wrappers) (#40822) 2026-08-19 03:48:45 +00:00
Wu Tianwei
8a33a9adb5 fix(web): remove only-me resource access option (#40956) 2026-08-19 02:50:07 +00:00
yyh
b78a3462c9 chore(web): align browser support targets (#40938) 2026-08-18 14:21:18 +00:00
zyssyz123
c38fb16efa fix(agent): retain usage for incomplete runs (#40937) 2026-08-18 13:11:22 +00:00
Asuka Minato
2400c6c59d test: migrate dataset service sessions and ORM models to SQLite (#40534) 2026-08-18 12:35:57 +00:00
yyh
324ddb361d fix(web): gate system features requests by connection (#40939) 2026-08-18 12:34:34 +00:00
Asuka Minato
4f81005662 test: migrate app runtime sessions and ORM models to SQLite (#40590) 2026-08-18 12:27:32 +00:00
Asuka Minato
f2dfa462e1 test: migrate agent runtime sessions and ORM models to SQLite (#40587) 2026-08-18 12:26:58 +00:00
Asuka Minato
14bc28ffbe test: migrate residual controller sessions and ORM models to SQLite (#40579) 2026-08-18 12:26:33 +00:00
Asuka Minato
5afce305e7 test: migrate residual service and task ORM models to SQLite (#40576) 2026-08-18 12:26:01 +00:00
Asuka Minato
beecf5730a test: migrate telemetry and core entity ORM models to SQLite (#40574) 2026-08-18 12:25:42 +00:00
Asuka Minato
eeda983b17 test: migrate service boundary sessions and ORM models to SQLite (#40533)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-18 12:23:33 +00:00
Asuka Minato
e2e3521874 test: migrate residual model sessions and ORM models to SQLite (#40531) 2026-08-18 12:23:02 +00:00
Asuka Minato
303ce70ac4 test: migrate app model sessions and ORM models to SQLite (#40530) 2026-08-18 12:22:33 +00:00
Asuka Minato
5fde1d096e test: eliminate remaining whole config mocks (#40855) 2026-08-18 12:01:49 +00:00
Asuka Minato
3bcd97b643 test: scope plugin and datasource config overrides (#40854) 2026-08-18 12:01:29 +00:00
Asuka Minato
20fdbcf36f test: centralize enterprise config overrides (#40853) 2026-08-18 12:01:01 +00:00
Asuka Minato
c7f4422333 test: keep integration config overrides typed (#40850) 2026-08-18 12:00:32 +00:00
Asuka Minato
da6ca23b50 test: use typed config overrides in service coverage (#40848) 2026-08-18 11:59:58 +00:00
yyh
b064a13aa4 refactor(web): remove legacy embedded API docs (#40929) 2026-08-18 09:53:55 +00:00
yyh
45e2d81be4 fix(ci): align Oxlint suppression formatting (#40934) 2026-08-18 09:41:48 +00:00
yyh
fe41e80f33 refactor(web): remove legacy tag component (#40928) 2026-08-18 07:58:47 +00:00
yyh
a2ac8ad106 refactor(web): migrate clearable search inputs (#40924) 2026-08-18 07:55:08 +00:00
yyh
bd4cfd5a7a refactor(web): migrate retry units to number field (#40923) 2026-08-18 07:55:07 +00:00
chenshiyang
0e975f6305 refactor(models): dep-inject Session on remaining @property accessors (#40797)
Co-authored-by: Claude <noreply@anthropic.com>
2026-08-18 07:23:09 +00:00
dependabot[bot]
c94846ee2a chore(deps): bump sqlparse from 0.5.4 to 0.6.0 in /api (#40904)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-08-18 06:50:31 +00:00
yyh
9ce463fc24 refactor(web): compose search prefixes with input group (#40922) 2026-08-18 06:04:37 +00:00
zyssyz123
5a0a12cb44 fix: preserve Agent tool-generated file outputs (#40917) 2026-08-18 05:59:43 +00:00
Byron.wang
ba61ab4f9f refactor(api): extract account activation application service (#40421)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-18 05:27:40 +00:00
Byron.wang
891627b210 refactor(api): decouple data source API key auth flow (#40452)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-18 04:30:17 +00:00
蓝破碎半圆/破碎蓝调
ba5e7d76fd fix: accept legacy plugin daemon list responses (#38265) 2026-08-18 04:11:49 +00:00
yyh
809a6cff1e refactor(web): standardize label search inputs (#40914) 2026-08-18 04:05:26 +00:00
yyh
32c11fd06e refactor(web): standardize dataset search inputs (#40913) 2026-08-18 04:05:25 +00:00
yyh
04d2d9ff19 refactor(web): standardize app log search inputs (#40912) 2026-08-18 04:05:25 +00:00
yyh
05499b9011 test(dify-ui): stabilize dropdown menu story (#40916) 2026-08-18 04:05:24 +00:00
Harsh Kashyap
ca32e87683 fix(api): bound connect phase to 5.0s in two api/core/ outbound timeouts (#40807)
Co-authored-by: Harsh Kashyap <Harsh23Kashyap@users.noreply.github.com>
2026-08-18 03:38:59 +00:00
盐粒 Yanli
122368f5e0 chore(dify-agent): disable Landlock for E2B templates (#40892) 2026-08-18 03:30:00 +00:00
盐粒 Yanli
c267e73ca6 fix(dify-agent): use E2B traffic access header (#40891) 2026-08-18 03:29:50 +00:00
盐粒 Yanli
c649b84bf6 fix(dify-agent): isolate cancellation intent observer (#40896) 2026-08-18 03:29:42 +00:00
yyh
09f8f43d20 fix(ci): use default Ubuntu mirror for Playwright (#40909) 2026-08-18 02:55:17 +00:00
mesrop2008
50d6c19ef4 fix(api): clear stale cancellation signals when resuming a paused workflow (#40905) 2026-08-18 02:27:43 +00:00
yyh
6d89557355 feat(dify-ui): add input group composition (#40890) 2026-08-18 02:14:39 +00:00
Amogh Bhat Nagri
30c304c6a7 fix(api): repair two malformed logger format strings (#40901) 2026-08-18 02:10:59 +00:00
yyh
76a91eb433 refactor(dify-ui): expose autocomplete popup anatomy (#40895) 2026-08-18 02:06:03 +00:00
Chengxiao
394b43376a fix: suggest deepseek-v4-flash for Agent mode (#40852) 2026-08-18 01:57:21 +00:00
Asuka Minato
02f0e8cffa test: isolate config inputs from process environment (#40847) 2026-08-17 13:09:17 +00:00
Asuka Minato
3f0a9c5060 test: migrate RAG indexing sessions and ORM models to SQLite (#40513) 2026-08-17 12:13:02 +00:00
Asuka Minato
ce1aed8df5 test: migrate RAG pipeline sessions and ORM models to SQLite (#40511) 2026-08-17 12:12:46 +00:00
Asuka Minato
c3d090fe4e test: migrate Service API dataset metadata sessions and ORM models to SQLite (#40518) 2026-08-17 12:12:06 +00:00
Asuka Minato
d92cf5d198 test: migrate Service API dataset document sessions and ORM models to SQLite (#40519) 2026-08-17 12:11:53 +00:00
Asuka Minato
ccf4d25321 test: migrate console workflow controller sessions and ORM models to SQLite (#40527) 2026-08-17 12:11:34 +00:00
Asuka Minato
4e02075f8d test: migrate console app MCP sessions and ORM models to SQLite (#40526) 2026-08-17 12:11:12 +00:00
Asuka Minato
0f358f5bb3 test: migrate console conversation sessions and ORM models to SQLite (#40528) 2026-08-17 12:10:57 +00:00
Asuka Minato
a575ae5ef2 test: migrate controller auth wrapper sessions and ORM models to SQLite (#40529) 2026-08-17 12:10:44 +00:00
盐粒 Yanli
2aaac4dadb feat(dify-agent): enforce signed upload size limits (#40883) 2026-08-17 11:59:42 +00:00
盐粒 Yanli
bec3890689 fix(dify-agent): enforce short-lived Agent Stub authorization (#40884) 2026-08-17 11:48:12 +00:00
非法操作
e3ab88f6de feat: dispatch New Agent Beta eligibility checks (#40725)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-17 10:33:50 +00:00
盐粒 Yanli
a679ee5644 fix(dify-agent): preserve snapshots for failed and cancelled runs (#40876) 2026-08-17 10:11:22 +00:00
盐粒 Yanli
96809473fc feat(dify-agent): add context-aware history compaction (#40872) 2026-08-17 09:36:21 +00:00
林玮 (Jade Lin)
5ef8becd25 feat: create accounts with client IP (#40875) 2026-08-17 09:29:57 +00:00
盐粒 Yanli
4249a0d052 fix(dify-agent): require E2B traffic authentication (#40871) 2026-08-17 08:35:53 +00:00
zyssyz123
64587eae43 fix(workflow): preserve historical Agent node compatibility (#40859) 2026-08-17 07:31:38 +00:00
yyh
4ce681d42f test(e2e): align agent model selector locators (#40862) 2026-08-17 06:48:00 +00:00
yyh
59c6a470bb fix(web): update agent model request limit copy (#40863) 2026-08-17 06:37:23 +00:00
无能的迪拜巧克力
b02072baee fix(web): let multimodal guidance height fit content (#40846) 2026-08-17 06:10:06 +00:00
Bond Zhu
f6a472d948 feat(ci): sync E2B template on release tag push (#40858) 2026-08-17 06:06:46 +00:00
Weike Zhang
45be4620fe refactor(controllers/web): dep-inject login and forgot-password payloads (#36659) (#40856) 2026-08-17 05:58:40 +00:00
dependabot[bot]
08993dd622 chore(deps): bump the github-actions-dependencies group with 2 updates (#40834)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-08-17 02:50:41 +00:00
YungLe
219596c4df feat(plugin-auth): visibility picker for OAuth credentials (#39840)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Wu Tianwei <30284043+WTW0313@users.noreply.github.com>
Co-authored-by: twwu <twwu@dify.ai>
2026-08-17 02:41:26 +00:00
yyh
facb60abfe fix(web): align combobox interaction semantics (#40826) 2026-08-17 02:13:08 +00:00
zy
141cbf9832 fix(api): support audio/x-m4a for ASR (#40776)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-16 02:47:31 +00:00
Asuka Minato
8fb5dd8587 test: migrate agent controller sessions and ORM models to SQLite (#40600)
Co-authored-by: Byron Wang <byron@dify.ai>
2026-08-15 15:15:28 +00:00
Asuka Minato
1651bcc774 test: migrate residual controller sessions and ORM models to SQLite (#40606)
Co-authored-by: Byron Wang <byron@dify.ai>
2026-08-15 15:15:11 +00:00
mesrop2008
c2e68335d4 docs: fix pipeline_generator docstrings to reference pipeline instead of app_model (#40813) 2026-08-15 12:09:16 +00:00
Asuka Minato
177edaa1c6 test: migrate annotation security sessions and ORM models to SQLite (#40604) 2026-08-15 09:54:29 +00:00
Asuka Minato
edb32fba92 test: migrate RAG processor residuals to SQLite ORM models (#40608) 2026-08-15 09:54:09 +00:00
Asuka Minato
959cacdc00 test: migrate agent surface sessions and ORM models to SQLite (#40602) 2026-08-15 09:53:48 +00:00
Asuka Minato
582c73bc3b test: migrate residual user ORM stand-ins to real models (#40625) 2026-08-15 09:52:59 +00:00
Asuka Minato
6eca353804 test: migrate file controller ORM models to real entities (#40632) 2026-08-15 09:52:38 +00:00
Harsh Kashyap
d43685bc79 fix(extension): chain original exception in APIBasedExtensionRequestor per PEP 3134 (#40810)
Co-authored-by: Harsh Kashyap <Harsh23Kashyap@users.noreply.github.com>
2026-08-15 08:48:28 +00:00
Valor
56ebccf14d fix: narrow bare except in storage exists() to ClientError (#40420)
Co-authored-by: Asuka Minato <i@asukaminato.eu.org>
2026-08-15 07:12:04 +00:00
chenshiyang
d31a7d47bf refactor(controllers/web): dep-inject payloads with @model_validate (#40796)
Co-authored-by: chenshiyang.10 <chenshiyang.10@jd.com>
2026-08-15 06:55:06 +00:00
Dream
8031ea6d73 fix: replace bare except with except Exception in core agent, storage and vector backends (#40801) 2026-08-15 00:56:09 +00:00
zyssyz123
dfac3e524e fix: reclaim conversation resources on deletion (#40792)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-14 14:30:04 +00:00
WH-2099
fc7b51634d fix(api): protect agent sandbox reads (#40794) 2026-08-14 13:51:41 +00:00
WH-2099
96bfcf20cd fix(api): protect workspace credential mutations (#40790) 2026-08-14 12:03:54 +00:00
Mahbub Souad
557fbec45f refactor: add Mapped type annotations to model fields (#40373) (#40380) 2026-08-14 12:03:17 +00:00
AlexMultiAgent
eaa9d877f1 test(api): make session decorator path assertion platform-agnostic (#39895)
Co-authored-by: -LAN- <laipz8200@outlook.com>
2026-08-14 11:52:40 +00:00
chelsealong
b537fed907 fix(api): point SSRF-blocked error message at the correct dify issue (#40605) 2026-08-14 11:46:50 +00:00
酒诗
b6319c819c chore: dep inject for model in dataset document actions (#40787)
Co-authored-by: geneachina <geneachina@gmail.com>
2026-08-14 11:08:21 +00:00
WH-2099
b6694d462f fix(api): protect custom OAuth client deletion (#40786) 2026-08-14 10:59:49 +00:00
L1nSn0w
ea6770c7a1 feat(oauth): drive silent authorization from oauth_provider_apps.auto_authorize (#40783)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-14 10:29:39 +00:00
Joel
b0c5172e10 fix: show accurate copy for agent run limit errors (#40784) 2026-08-14 10:07:36 +00:00
WH-2099
62a544a146 fix(api): enforce RAG draft variable access boundaries (#40745) 2026-08-14 10:07:22 +00:00
非法操作
eec092f93d refactor(api): reuse app definition queries for service API info (#40476) 2026-08-14 09:38:35 +00:00
非法操作
e0fd3b264a refactor(api): reuse app definition queries for app parameters (#40465) 2026-08-14 09:38:34 +00:00
非法操作
17c8ff6a33 refactor(api): reuse app definition queries in web and service APIs (#40463) 2026-08-14 09:38:33 +00:00
非法操作
c425e4cdd5 refactor(api): extract installed app definition queries (#40462) 2026-08-14 09:38:32 +00:00
yyh
de9b456e82 fix(ci): align staged checks with Vite+ (#40774) 2026-08-14 09:09:33 +00:00
Joel
62d06a3c73 fix: preserve successful last run status after page restore (#40775) 2026-08-14 08:59:18 +00:00
zyssyz123
09f20b7a14 fix(agent): return conflict for duplicate creation (#40771)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-14 08:57:13 +00:00
Asuka Minato
0a1e52598f test: migrate controller identity ORM models to SQLite (#40626) 2026-08-14 08:54:48 +00:00
Asuka Minato
640bf56859 test: migrate workflow tool users to SQLite ORM models (#40628) 2026-08-14 08:54:31 +00:00
Asuka Minato
a958c2cadb test: migrate RAG residual entities to real ORM models (#40629) 2026-08-14 08:53:56 +00:00
Asuka Minato
f058e36084 test: migrate account tenant ORM stand-ins to SQLite (#40627) 2026-08-14 08:53:32 +00:00
Asuka Minato
9f364339cc test: migrate residual namespace ORM entities to real models (#40633) 2026-08-14 08:52:53 +00:00
盐粒 Yanli
3acc9470d4 feat(dify-agent): expand and enforce agent run limits (#40641) 2026-08-14 08:27:19 +00:00
yyh
9ddbc23b16 fix(dify-ui): refine segmented control focus feedback (#40769) 2026-08-14 08:17:14 +00:00
Myshkin451
c903e93e8b fix: preserve file preview content type (#37211)
Co-authored-by: FFXN <31929997+FFXN@users.noreply.github.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-14 07:45:21 +00:00
盐粒 Yanli
0b36a0bbc0 fix(dify-agent): clarify shell working spaces (#40623)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-14 07:39:32 +00:00
林玮 (Jade Lin)
4e44ade07f fix: handle long text URLs in webscraper (#40757) 2026-08-14 07:34:53 +00:00
Joel
35132d6892 chore: reopen the education application flow (#40760)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-14 07:16:21 +00:00
dependabot[bot]
6edc8ba147 chore(deps): bump pydantic-ai-slim from 1.102.0 to 1.106.0 in /dify-agent (#40736)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-08-14 06:26:00 +00:00
yyh
12b3b62a7f chore: update workspace dependencies (#40764) 2026-08-14 06:17:11 +00:00
Crazywoola
58653f2cdb feat(workflow-generator): prefer installed tools (#40611) 2026-08-14 05:38:37 +00:00
Asuka Minato
ef176f130b test: migrate workflow event ORM models to real entities (#40634) 2026-08-14 05:35:10 +00:00
Asuka Minato
c36161a73f test: migrate OpenAPI and tool-file ORM entities (#40637) 2026-08-14 05:34:56 +00:00
Asuka Minato
4b189777c4 test: migrate web controller identity ORM models to real entities (#40639) 2026-08-14 05:34:43 +00:00
Asuka Minato
d08dc6162c test: migrate trace workflow run ORM model to real entity (#40642) 2026-08-14 05:34:29 +00:00
Asuka Minato
b5e05516f4 test: migrate annotation controller ORM models to real entities (#40643) 2026-08-14 05:34:16 +00:00
Asuka Minato
9f048cd89b test: migrate load balancing account ORM model to real entity (#40644) 2026-08-14 05:34:00 +00:00
Asuka Minato
78dfce3b63 test: migrate expired log workflow ORM models to real entities (#40645) 2026-08-14 05:33:46 +00:00
Asuka Minato
97d34ae6be test: migrate agent drive end-user ORM models to real entities (#40654) 2026-08-14 05:33:29 +00:00
Asuka Minato
ea0ee680dc test: migrate app service accounts and commit failures to real ORM (#40655) 2026-08-14 05:33:16 +00:00
yyh
9acdcbe2f8 fix(web): skip lifecycle scripts in Docker install (#40763) 2026-08-14 05:12:14 +00:00
yyh
0f63a05d04 chore: upgrade Vite+ to 0.2.9 (#40762) 2026-08-14 04:42:28 +00:00
WH-2099
3cd23d4ef8 fix(agent): authenticate agent control plane (#40737) 2026-08-14 04:32:09 +00:00
Pranav Agarwal
e2852524be fix(api): enforce edit and RBAC permissions on dataset API key GET endpoint (#40740) (#40743) 2026-08-14 04:27:37 +00:00
yyh
f8e05ebfc0 docs(web): consolidate maintainer guidance (#40758) 2026-08-14 03:40:05 +00:00
Joel
0ac005eb98 fix: add semantic document titles across pages (#40396) 2026-08-14 03:29:16 +00:00
林玮 (Jade Lin)
755c154b1f refactor: resolve completion model via manager (#40756) 2026-08-14 02:52:42 +00:00
Jingyi
e3b3165e9a feat(web): embed marketplace in integration categories (#40744) 2026-08-14 01:55:51 +00:00
Xiyuan Chen
bf044cf19c chore(deps): bump wandb to 0.28.2 (go-git, grpc, x/text, Go stdlib CVEs) (#40753) 2026-08-14 01:36:14 +00:00
yyh
1cf8db8395 refactor(web): clarify model selector trigger ownership (#40732)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-14 01:03:50 +00:00
WH-2099
c1bde25bcc fix(api): remove unsafe Bedrock test endpoint (#40742) 2026-08-13 19:47:13 +00:00
Harsh Kashyap
8238684334 fix(api): chain original exception in 13 except blocks per PEP 3134 (#40738)
Co-authored-by: Harsh Kashyap <Harsh23Kashyap@users.noreply.github.com>
2026-08-13 17:50:05 +00:00
zyssyz123
c9c7fb9962 fix(agent): meter internal LLM calls through API (#40613)
Co-authored-by: yyh <92089059+lyzno1@users.noreply.github.com>
2026-08-13 12:15:44 +00:00
林玮 (Jade Lin)
b9248690b0 refactor: generalize hosted model quota lifecycle (#40722)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-13 08:10:02 +00:00
yyh
36dfc6c216 refactor(ui): enforce single-choice segmented controls (#40726) 2026-08-13 08:09:10 +00:00
yyh
7a6f380f2c fix(dify-ui): refine pagination navigation semantics (#40723) 2026-08-13 07:54:31 +00:00
Joel
84e348c52b fix: prevent cross-tab chat conversation switching (#40709) 2026-08-13 07:26:38 +00:00
盐粒 Yanli
79b8d7a797 fix(agent): normalize plugin provider identities (#40619)
Co-authored-by: Joel <iamjoel007@gmail.com>
2026-08-13 07:22:41 +00:00
yyh
fb30dd2d58 refactor(web): migrate app card icon controls (#40652) 2026-08-13 07:04:17 +00:00
yyh
a0ca3d2e81 refactor(web): remove legacy action button references (#40651) 2026-08-13 07:04:16 +00:00
yyh
204a906de8 refactor(web): migrate help menu icon trigger (#40650) 2026-08-13 07:04:15 +00:00
yyh
146f402a8c refactor(web): migrate workflow icon commands (#40649) 2026-08-13 06:44:03 +00:00
yyh
d6f32a0267 refactor(web): migrate plugin icon commands (#40648) 2026-08-13 06:44:02 +00:00
yyh
288766171d refactor(web): migrate dataset icon commands (#40647) 2026-08-13 06:44:01 +00:00
yyh
7ab368f4a4 refactor(web): migrate app icon commands (#40646) 2026-08-13 06:44:00 +00:00
yyh
d0e2723e45 refactor(web): migrate semantic icon controls (#40624) 2026-08-13 06:43:59 +00:00
Joel
c085142e66 chore: remove scope selection from the agent environment editor (#40701) 2026-08-13 06:24:51 +00:00
林玮 (Jade Lin)
c647cfd6a3 refactor: resolve summary models through manager (#40696) 2026-08-13 06:22:22 +00:00
yyh
29a4897e73 fix(ci): prevent false failures from superseded runs (#40699) 2026-08-13 06:18:22 +00:00
盐粒 Yanli
8df220c2b3 fix(agent): propagate resource collection failures (#40697) 2026-08-13 06:16:12 +00:00
zyssyz123
6e80f42f38 fix(api): decouple response listeners from execution lifecycle (#39813) 2026-08-13 05:50:43 +00:00
Asuka Minato
211344d0b0 test: migrate conversation lifecycle sessions and ORM models to SQLite (#40656) 2026-08-13 05:20:10 +00:00
Asuka Minato
6b5c04e7d3 test: migrate workflow node trace ORM models to real entities (#40657) 2026-08-13 05:19:52 +00:00
Asuka Minato
6ea89dc7cb test: migrate workflow tool-file ORM model to real entity (#40658) 2026-08-13 05:19:34 +00:00
Asuka Minato
ff46c3d7d7 test: migrate reranker upload-file sessions and ORM models to SQLite (#40659) 2026-08-13 05:19:19 +00:00
Asuka Minato
2f969afaf2 test: migrate app runner transaction sessions and ORM models to SQLite (#40660) 2026-08-13 05:19:00 +00:00
Asuka Minato
fbd38753fa test: migrate residual controller ORM identities to real models (#40661) 2026-08-13 05:18:44 +00:00
Asuka Minato
2d1fb61885 test: migrate RAG dataset ORM contracts to real models (#40662) 2026-08-13 05:18:25 +00:00
Asuka Minato
7e3381e8ad test: migrate OpenTelemetry ORM identities to real models (#40663) 2026-08-13 05:17:53 +00:00
Joel
190780e125 fix(e2e): skip hidden Agent knowledge E2E scenarios (#40691) 2026-08-13 05:03:15 +00:00
yyh
1f96da5e6d fix(ci): always report required style checks (#40684) 2026-08-13 04:05:45 +00:00
Joel
a8d5679a1c fix: update Agent advanced settings copy (#40682) 2026-08-13 03:25:43 +00:00
Xiyuan Chen
5bacb68115 fix(ops): keep the path of self-hosted LangSmith and Weave endpoints (#40584) 2026-08-13 03:18:22 +00:00
Asuka Minato
af2fac75db test: migrate workflow variable ORM model to real entity (#40664) 2026-08-13 03:05:31 +00:00
Asuka Minato
616736e0f1 test: migrate residual session factories to shared SQLite (#40665) 2026-08-13 03:04:59 +00:00
Asuka Minato
94323c0838 test: migrate residual dataset and archive ORM models (#40668) 2026-08-13 03:04:17 +00:00
Asuka Minato
223998bd48 test: migrate residual ORM model stand-ins to real mappings (#40666) 2026-08-13 03:03:46 +00:00
Joel
b3d770a69b fix: hide knowledge retrieval from Agent V2 configuration (#40679) 2026-08-13 03:03:12 +00:00
Asuka Minato
9fb51b7e67 test: migrate API workflow pause ORM models to real entities (#40669) 2026-08-13 03:03:10 +00:00
yyh
67366dd35c feat(ui): expose base toggle composition (#40622) 2026-08-13 02:29:37 +00:00
yyh
71b31e17b0 refactor(web): migrate domain icon commands (#40621) 2026-08-13 02:29:36 +00:00
yyh
312bc4912d refactor(web): migrate shared icon commands (#40620) 2026-08-13 02:29:36 +00:00
yyh
3925b5fa1b refactor(ui): adopt icon button in close controls (#40617) 2026-08-13 02:29:35 +00:00
yyh
d4d30148bd feat(ui): add icon button primitive (#40616) 2026-08-13 02:29:34 +00:00
林玮 (Jade Lin)
12e6838403 fix: meter hosted LLM invocations (#40589) 2026-08-12 12:33:21 +00:00
WH-2099
489772908b fix: enforce API key list permissions (#40516) 2026-08-12 11:44:27 +00:00
Benjamin
6a37e1538a fix(rbac): grant member policies when a dataset is opened to the work… (#39735)
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-12 09:02:03 +00:00
wangxiaolei
eeaaf11a51 fix: fix create dataset with document miss rbac operation (#40599)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-12 08:57:43 +00:00
Wu Tianwei
6899c7720f refactor(web): remove deprecated deployments pages (#40593) 2026-08-12 08:49:51 +00:00
Byron.wang
51a007e84e refactor(api): extract init validation into layered application service (#40046) 2026-08-12 08:42:09 +00:00
yyh
6d185b6f40 test(web): remove brittle publisher lock test (#40592) 2026-08-12 07:55:46 +00:00
github-actions[bot]
7358c0f735 chore(i18n): sync translations with en-US (#40573)
Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Co-authored-by: yyh <92089059+lyzno1@users.noreply.github.com>
2026-08-12 07:49:39 +00:00
yyh
01460f681e fix(web): render workspace plan badge during SSR (#40581)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-12 07:45:39 +00:00
Crazywoola
750fce7e52 fix(web): restore app deletion autofill and knowledge scope label (#40583) 2026-08-12 07:31:59 +00:00
Asuka Minato
216d528f1b test: migrate agent app sandbox sessions and ORM models to SQLite (#40568) 2026-08-12 06:30:17 +00:00
Xin Zhang
0ee89c1302 fix: restrict app deploy to explicit enterprise permission (#40564) 2026-08-12 06:25:05 +00:00
WH-2099
af382be837 fix(api): bind remaining RAG resources to owners (#40503) 2026-08-12 06:05:16 +00:00
chelsealong
d813edb945 fix(agent-v2): stop dropping non-vision attachments from agent chat (#40179)
Co-authored-by: Crazywoola <100913391+crazywoola@users.noreply.github.com>
2026-08-12 05:57:21 +00:00
无能的迪拜巧克力
9041251da5 feat(web): add multimodal retrieval guidance for Knowledge embedding models (#40566) 2026-08-12 05:54:33 +00:00
Joel
9e04e4f5c2 chore: add Docker configuration for the Turnstile site key (#40569) 2026-08-12 05:54:21 +00:00
yyh
28ba7033fa refactor(web): remove profile bootstrap atom layer (#40474) 2026-08-12 04:05:57 +00:00
Wu Tianwei
fbaf23dc8d fix(web): improve app deployment v2 accessibility (#40550) 2026-08-12 03:43:35 +00:00
github-actions[bot]
9cc1f68364 chore(i18n): sync translations with en-US (#40546)
Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Co-authored-by: yyh <92089059+lyzno1@users.noreply.github.com>
2026-08-12 03:25:34 +00:00
zyssyz123
059c9ce0b6 feat: add trunstile (#40494)
Co-authored-by: Joel <iamjoel007@gmail.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-12 03:08:19 +00:00
yyh
668fb4c14a refactor(web): sync zendesk from profile query (#40473) 2026-08-12 02:57:27 +00:00
yyh
4c06bcf000 refactor(web): sync amplitude from profile query (#40472) 2026-08-12 02:15:24 +00:00
Wu Tianwei
7aba539e82 feat: app deployment v2 (#39829)
Co-authored-by: zhangx1n <zhangxin@dify.ai>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-12 01:55:36 +00:00
WH-2099
ef8544b173 fix(api): bind dataset operations to owners (#40149) 2026-08-11 16:37:14 +00:00
yyh
bee269afe8 refactor(web): align education autocomplete async behavior (#40500) 2026-08-11 14:12:50 +00:00
yyh
324b0f97ff refactor(web): read plugin profile from query cache (#40471) 2026-08-11 11:39:26 +00:00
yyh
7352944dec refactor(web): read account profile from query cache (#40470) 2026-08-11 11:17:29 +00:00
yyh
78c7fb9c5c refactor(web): move education verification to dedicated routes (#40493)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-11 09:56:11 +00:00
Joel
8598af2a17 fix: improve agent working directory tab labels and tooltips (#40496) 2026-08-11 09:36:33 +00:00
yyh
df07a0a1de refactor(web): read workflow profile from query cache (#40469) 2026-08-11 09:03:56 +00:00
Asuka Minato
a64a24b39c test: migrate snippet and vector sessions to SQLite (#40089)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Byron Wang <byron@dify.ai>
2026-08-11 08:51:07 +00:00
yyh
cd0e88c680 refactor(web): read dataset profile from query cache (#40468) 2026-08-11 08:30:49 +00:00
Asuka Minato
08008f6305 test: migrate controller sessions to SQLite (#40083)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-11 08:29:40 +00:00
Valor
e3812cf72b fix: add zh_Hans labels for builtin Audio provider and its tools (#40408) 2026-08-11 08:27:59 +00:00
yyh
4175d062f4 fix(web): make legacy Home redirect permanent (#40492) 2026-08-11 08:27:57 +00:00
Yunlu Wen
84f9b6530e chore: bump cryptography, pypdf, h2 for CVE fixes (#40409)
Co-authored-by: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-08-11 08:14:55 +00:00
yyh
3d02a12eb6 refactor(web): read app profile from query cache (#40467) 2026-08-11 08:09:58 +00:00
Byron.wang
c1e94f8ee7 refactor(api): consolidate deployment edition handling (#40142)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-11 07:39:01 +00:00
yyh
7fffd51535 fix(web): preserve workflow canvas after history updates (#40489) 2026-08-11 07:36:21 +00:00
Joel
a68e0bbc6f fix: show a persistent toast for agent run timeouts (#40486) 2026-08-11 07:27:52 +00:00
Asuka Minato
dd3cf53044 test: migrate retention and task sessions to SQLite (#40090)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-11 07:05:36 +00:00
Asuka Minato
500e37e2fd test: migrate core RAG sessions to SQLite (#40085)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-11 07:05:26 +00:00
Joel
44c5f1c011 fix: split sandbox files into saved and temporary tabs (#40478) 2026-08-11 06:46:01 +00:00
Asuka Minato
7162450e83 test: migrate app service sessions to SQLite (#40088)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-11 06:43:15 +00:00
Asuka Minato
3f62f3cd05 test: migrate dataset indexing task sessions to SQLite (#40091) 2026-08-11 06:31:33 +00:00
Asuka Minato
15483f1592 test: use sqlite sessions in rag pipeline coverage (#40093) 2026-08-11 06:19:08 +00:00
wangxiaolei
4c7b870062 fix: _multiple_retrieve_thread not fail fast (#40466) 2026-08-11 05:40:23 +00:00
yyh
48451f5adf fix(web): keep agent ref updates out of render (#40429) 2026-08-11 03:57:58 +00:00
Kecheng Wang
f785af3cec fix(docker): use dynamic DNS resolution for all nginx upstreams (#39155)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-11 00:48:59 +00:00
Tushar Motwani
aa5e8a5eff chore: suppress pyrefly necessary conversions (#40444) 2026-08-10 16:41:34 +00:00
yyh
6a9efa8ffd fix(web): keep workflow ref updates out of render (#40428) 2026-08-10 14:38:04 +00:00
林玮 (Jade Lin)
4eb9a24997 refactor(workflow): align standalone node execution layers (#40447) 2026-08-10 12:37:34 +00:00
yyh
b206e691ca fix(web): keep shared ref updates out of render (#40427) 2026-08-10 11:33:11 +00:00
yyh
3f354c2b06 docs(web): clarify ref mutation ownership (#40426) 2026-08-10 11:04:18 +00:00
github-actions[bot]
8ae9d0ad8e chore(i18n): sync translations with en-US (#40435)
Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Co-authored-by: yyh <92089059+lyzno1@users.noreply.github.com>
2026-08-10 11:00:10 +00:00
Joel
0f583cfe75 fix: widen agent orchestration chat on large displays (#40433) 2026-08-10 09:57:47 +00:00
zyqzyq
df250423d4 feat: add tool plugin param type date and date-picker (#36163)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: hjlarry <hjlarry@163.com>
2026-08-10 09:31:38 +00:00
Asuka Minato
b8934b743c test: migrate core app sessions to SQLite (#40084)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-10 09:01:02 +00:00
Byron.wang
976d061f9b refactor(api): merge ping and version endpoints into system (#40058)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-10 08:50:40 +00:00
Asuka Minato
96655436f4 test: migrate RAG index sessions to SQLite (#40080)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-10 08:43:18 +00:00
非法操作
648806bc9c refactor(api): extract explore banner query service (#40053) 2026-08-10 08:07:54 +00:00
yyh
64ebfe2235 fix(web): name the webapp password visibility action (#40225) 2026-08-10 07:12:24 +00:00
yyh
ca4d7ff1f2 fix(web): make suggested questions native buttons (#40200)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-10 06:47:19 +00:00
yyh
2917d1d51c refactor(web): migrate webapp password fields to dify ui (#40223) 2026-08-10 06:44:28 +00:00
yyh
c79b9821fa fix(web): name endpoint card actions (#40260) 2026-08-10 06:44:10 +00:00
yyh
6422ef2b57 fix(web): use button for workflow debug close (#40274)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-10 06:43:23 +00:00
yyh
509ea9afc4 fix(web): name secret key delete action (#40297) 2026-08-10 06:43:02 +00:00
yyh
1828cc6a10 fix(web): name MCP header delete actions (#40300) 2026-08-10 06:42:45 +00:00
yyh
8d5ff67d05 fix(web): name external API card actions (#40304) 2026-08-10 06:42:36 +00:00
yyh
ec63a26511 fix(web): expose chat variable tips state (#40334) 2026-08-10 06:42:03 +00:00
yyh
c2b3b89445 docs(web): add Next.js agent rules (#40398) 2026-08-10 06:39:37 +00:00
Joel
5967bd8e08 chore: tighten education verification and pause discount access (#40402)
Co-authored-by: Yansong Zhang <916125788@qq.com>
2026-08-10 06:33:03 +00:00
非法操作
7e7548cd18 fix(web): allow unlimited text input in trial apps (#40403) 2026-08-10 06:18:38 +00:00
dependabot[bot]
1ba3aa718e chore(deps): bump pymdown-extensions from 11.0 to 11.0.1 in /dify-agent (#40183)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-08-10 06:16:06 +00:00
dependabot[bot]
c7b1660650 chore(deps): bump gitpython from 3.1.57 to 3.1.58 in /api (#40184)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-08-10 06:14:40 +00:00
yyh
f5e1f1590f fix(web): use buttons for version filters (#40357)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-10 04:41:57 +00:00
yyh
09d0cca5b9 fix(web): make tool category filters keyboard accessible (#40243) 2026-08-10 04:18:04 +00:00
yyh
d8736be194 fix(web): name MCP header fields (#40299) 2026-08-10 03:57:24 +00:00
Pranav Agarwal
7f15f506f8 fix(api): end_date filter in feedback export excludes the entire end date (#40114) 2026-08-10 03:27:56 +00:00
chelsealong
6aa3fa5193 fix: catch ValueError instead of bare except in account CLI commands (#40356) 2026-08-10 03:18:33 +00:00
dependabot[bot]
c849be5e52 chore(deps): bump the github-actions-dependencies group with 2 updates (#40391)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-08-10 03:17:53 +00:00
yyh
b3b3088a17 fix(web): name external API panel close (#40309) 2026-08-10 03:13:36 +00:00
yyh
72fad39913 fix(web): name external API modal close (#40313) 2026-08-10 03:13:35 +00:00
yyh
e12563a4b4 fix(web): name plugin item actions (#40261) 2026-08-10 03:13:33 +00:00
yyh
e8afed13cc fix(web): name plugin detail close action (#40264) 2026-08-10 03:13:33 +00:00
yyh
7a72bb3571 fix(web): name OAuth redirect copy action (#40303) 2026-08-10 03:13:33 +00:00
yyh
08f30717ad fix(web): make verification back actions keyboard accessible (#40196) 2026-08-10 03:13:31 +00:00
yyh
2bdfbb9e61 fix(web): name generated result copy action (#40259) 2026-08-10 03:13:31 +00:00
yyh
06e757a9e9 fix(web): name the snippet info menu trigger (#40251) 2026-08-10 03:13:31 +00:00
yyh
7b84d4daca fix(web): use primary headings on password reset pages (#40193) 2026-08-10 03:13:31 +00:00
yyh
5e0d705a7f fix(web): name the plugin debug trigger (#40252) 2026-08-10 03:13:31 +00:00
yyh
30ca836e03 fix(web): make the citation toggle a button (#40204) 2026-08-10 03:12:25 +00:00
Asuka Minato
b391dc56a0 chore: example to rm db.session (#40370) 2026-08-10 02:58:52 +00:00
yyh
606fac6e1c fix(web): use button for publisher access (#40361)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-10 02:56:21 +00:00
yyh
ed36ee5133 refactor(web): rely on preview dialog containment (#40363)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-10 02:56:20 +00:00
yyh
c35242731f fix(web): use button for provider tool item (#40362) 2026-08-10 02:56:20 +00:00
yyh
d2d07d0345 fix(web): use buttons for plugin type switch (#40353)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-10 02:56:19 +00:00
yyh
8b908d6150 fix(web): use buttons for pricing categories (#40360)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-10 02:56:18 +00:00
yyh
1017a76b4c fix(web): name assigner add operation (#40337) 2026-08-10 02:56:18 +00:00
yyh
9c5d76c299 refactor(web): rely on QR panel containment (#40352)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-10 02:56:18 +00:00
yyh
83987b8eec fix(web): name prompt generator action (#40328) 2026-08-10 02:56:16 +00:00
yyh
cbd71699de fix(web): expose SVG preview toggle state (#40332) 2026-08-10 02:56:16 +00:00
yyh
5d58a25e52 fix(web): name human input preview close (#40321) 2026-08-10 02:56:16 +00:00
yyh
764d9b5fbe fix(web): name external retrieval close action (#40317) 2026-08-10 02:56:16 +00:00
yyh
5ffea6d30e fix(web): name code generator action (#40324) 2026-08-10 02:56:16 +00:00
yyh
2796210e18 fix(web): name agent log navigation menu (#40286) 2026-08-10 02:56:14 +00:00
yyh
1b2c71ac75 fix(web): name variable inspect close actions (#40289) 2026-08-10 02:56:14 +00:00
yyh
cc4bf22d07 fix(web): expose workflow parallel toggle state (#40282) 2026-08-10 02:56:14 +00:00
yyh
7295d9306f fix(web): name image previewer actions (#40283) 2026-08-10 02:56:14 +00:00
yyh
2a66b49bc7 fix(web): name human input delete action (#40293) 2026-08-10 02:56:14 +00:00
yyh
c944a25585 fix(web): expose debug toolbar semantics (#40258) 2026-08-10 02:56:12 +00:00
yyh
2067836851 fix(web): name saved item actions (#40256) 2026-08-10 02:56:12 +00:00
yyh
6f95a071b5 fix(web): name snippet stop action (#40278) 2026-08-10 02:56:11 +00:00
yyh
a543fd3656 fix(web): name workflow version history action (#40276) 2026-08-10 02:56:11 +00:00
yyh
d94c4415af fix(web): name annotation reply actions (#40270) 2026-08-10 02:56:11 +00:00
yyh
abbed23c64 fix(web): make dataset sidebar menu items buttons (#40248) 2026-08-10 02:56:09 +00:00
yyh
5de4e5b3c0 fix(web): name dataset configuration actions (#40254) 2026-08-10 02:56:09 +00:00
yyh
1e17a55e79 fix(web): name annotation configuration action (#40255) 2026-08-10 02:56:09 +00:00
yyh
465dab2eed refactor(web): keep copy id events on the button (#40247) 2026-08-10 02:56:09 +00:00
yyh
532e0a77cc fix(web): name conversation menu triggers (#40253) 2026-08-10 02:56:09 +00:00
yyh
47835e6b25 fix(web): expose the voice recording timer (#40205) 2026-08-10 02:56:07 +00:00
yyh
11c537dc1e fix(web): restore webapp email code form submission (#40227) 2026-08-10 02:56:07 +00:00
yyh
e4420227b5 fix(web): make the scroll-to-node action a button (#40214) 2026-08-10 02:56:07 +00:00
yyh
f9e44fe86e fix(web): restore the signup email focus order (#40230) 2026-08-10 02:56:07 +00:00
yyh
b256e211dc fix(web): make the member selector keyboard accessible (#40209) 2026-08-10 02:56:07 +00:00
yyh
2a34c7a714 fix(web): make the human input expander a button (#40202)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-10 02:55:30 +00:00
yyh
04132b51f0 fix(web): use button for chat variable panel close (#40333)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-10 02:53:49 +00:00
yyh
908f6ada4e fix(web): restore webapp password form submission (#40222) 2026-08-10 02:53:43 +00:00
yyh
e7da213f93 fix(web): name workflow debug actions (#40273) 2026-08-10 02:53:37 +00:00
yyh
e7f789f185 fix(web): hide citation measurement items from assistive tech (#40203) 2026-08-10 02:34:14 +00:00
yyh
f8d381e6c5 fix(web): name chat settings triggers (#40341) 2026-08-10 02:33:11 +00:00
yyh
c29425c0fc fix(web): name chat history controls (#40344) 2026-08-10 02:33:02 +00:00
yyh
612f9ee669 fix(web): use button for tool detail toggle (#40349)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-10 02:32:52 +00:00
Souravrajvi0
81a38df814 feat(api): cache remote recommended app template fetches (#40176) 2026-08-10 02:30:15 +00:00
yyh
e9eb130731 fix(web): use a button for unauthorized logout (#40198) 2026-08-10 02:29:46 +00:00
yyh
4edaecc04d fix(web): use a button for the webapp fallback action (#40197) 2026-08-10 02:29:10 +00:00
yyh
fc8d0a0187 fix(web): use a primary heading on the install page (#40194) 2026-08-10 02:26:36 +00:00
yyh
96960499ef fix(web): use primary headings on auth pages (#40192) 2026-08-10 02:26:10 +00:00
yyh
c2687c16b3 refactor(web): unify infinite scroll sentinels (#40188) 2026-08-10 02:22:07 +00:00
Asuka Minato
883944d289 test: Type test (#40371)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-10 02:13:17 +00:00
yyh
a7156a0702 fix(web): remove workflow output title tab stop (#40377) 2026-08-10 01:52:33 +00:00
yyh
dee9d27af8 fix(web): associate app deletion confirmation label (#40375) 2026-08-10 01:52:09 +00:00
yyh
e06f0ee315 fix(web): hide credential icons from assistive tech (#40376) 2026-08-10 01:51:42 +00:00
chelsealong
7522ae14b2 fix(agent): preserve plugin-declared model parameters through Agent Soul (#40163)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-09 08:48:01 +00:00
Likalikali
e09eee8fd1 refactor: replace manual model_validate with @model_validate in datasets controllers (#40236)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-09 08:25:27 +00:00
Likalikali
b692ddd80c refactor: replace manual model_validate with @model_validate in workspace remaining controllers (#40239)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-09 08:23:51 +00:00
Likalikali
5ebb389d26 refactor: replace manual model_validate with @model_validate in rag_pipeline controllers (#40237) 2026-08-09 08:22:50 +00:00
Likalikali
fff6f7cf2f refactor: replace manual model_validate with @model_validate in app workflow controllers (#40235) 2026-08-09 08:20:10 +00:00
Likalikali
516fd12b8d refactor: replace manual model_validate with @model_validate in app core controllers (#40234)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-09 08:18:02 +00:00
Likalikali
925ca49f21 refactor: replace manual model_validate with @model_validate in explore/snippets controllers (#40241) 2026-08-09 07:07:08 +00:00
Likalikali
a1577fc48c refactor: replace manual model_validate with @model_validate in auth/billing/tag controllers (#40240) 2026-08-09 06:14:07 +00:00
Likalikali
acda0341ed refactor: replace manual model_validate with @model_validate in workspace plugin/tool controllers (#40238) 2026-08-09 06:13:24 +00:00
Likalikali
98378cfe03 refactor: replace manual model_validate with @model_validate in agent controllers (#40233) 2026-08-09 06:11:33 +00:00
非法操作
3f89a3c742 fix(workflow): fall back when default socket is unavailable (#40191) 2026-08-09 04:13:41 +00:00
medimedi
e036075e22 chore: Remove redundant dataset context string conversions (#40189) 2026-08-08 18:26:52 +00:00
Asuka Minato
5a84cde198 test: move RAG pipeline workflow coverage to unit tests (#38937) 2026-08-08 12:00:32 +00:00
Byron.wang
4e18ab0ad4 refactor(api): decouple setup and spec endpoints (#40104) 2026-08-08 11:52:15 +00:00
chelsealong
2a742486c5 fix(agent-v2): accept composer UI ids on manual metadata filter conditions (#40171)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-08 06:55:27 +00:00
Likalikali
d362bdbb4e refactor: replace manual model_validate with @model_validate decorator in app controllers (#40170) 2026-08-08 05:47:11 +00:00
Likalikali
60d6be5b13 chore: dep inject for model in explore workflow run (#40158) 2026-08-08 02:50:27 +00:00
Likalikali
cc1b55aaf7 chore: dep inject for model in explore apis (#40160)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-08 02:23:17 +00:00
yyh
d1fa17032e revert(web): use suspense boundary in home page (#40167) 2026-08-07 18:50:33 +00:00
盐粒 Yanli
916d7e1c96 refactor(dify-agent): download Binding files through Agent Stub (#40143)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-07 14:56:52 +00:00
Likalikali
c094117ca2 chore: dep inject for model in agent app sandbox upload (#40153) 2026-08-07 13:28:31 +00:00
Likalikali
c6b1311aa3 chore: dep inject for model in workspace snippets, load balancing, and endpoint (#40161) 2026-08-07 13:22:02 +00:00
Likalikali
515c3d0c62 chore: dep inject for model in onboarding step by step tour (#40155) 2026-08-07 12:41:22 +00:00
Likalikali
fe94ddaaeb chore: dep inject for model in workflow run archive download (#40157) 2026-08-07 12:40:44 +00:00
Likalikali
3e8c0fdcef chore: dep inject for model in website crawl api (#40156) 2026-08-07 12:40:12 +00:00
Likalikali
055462fe6e chore: dep inject for model in tags, mcp server, and data source auth (#40159) 2026-08-07 12:38:29 +00:00
Likalikali
06e229e8b2 chore: dep inject for model in api based extension (#40154) 2026-08-07 12:37:50 +00:00
Likalikali
fa498ad7a2 chore: dep inject for model in oauth server (#40147) 2026-08-07 11:16:11 +00:00
Likalikali
a279be91a8 chore: dep inject for model in datasets document and web human input … (#40151) 2026-08-07 11:15:43 +00:00
盐粒 Yanli
12300f3833 feat(dify-agent): propagate run limit error types (#40116)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-07 10:37:22 +00:00
Joel
b439b6a800 feat: support accessibility checks in CI (#40137) 2026-08-07 10:28:44 +00:00
github-actions[bot]
7a7d8fe19e chore(i18n): sync translations with en-US (#40150)
Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
2026-08-07 10:10:33 +00:00
Joel
2635d1b3df fix: improve readability of DSL import warnings (#40148) 2026-08-07 10:01:09 +00:00
yyh
a952487789 chore(web): remove unreachable explore sidebar (#40136) 2026-08-07 09:29:44 +00:00
WH-2099
c9e6db5ef2 fix(api): scope temporary capabilities to owners (#39863) 2026-08-07 09:21:13 +00:00
Likalikali
b31e66107c chore: dep inject for model in notification dismiss (#40146) 2026-08-07 09:02:49 +00:00
Joel
42d6589ce2 fix: show inline agent build draft change details (#40140) 2026-08-07 07:28:41 +00:00
yyh
f00d0329d4 perf(web): prefetch app links on intent (#40133)
Co-authored-by: 非法操作 <hjlarry@163.com>
2026-08-07 07:16:38 +00:00
yyh
af9d2d00a3 chore(web): add dedicated home loading boundary (#40135) 2026-08-07 07:16:25 +00:00
非法操作
ae8cb996c7 chore: use multi-arch plugin daemon image tag (#40139) 2026-08-07 07:01:06 +00:00
盐粒 Yanli
adb89a8926 refactor(dify-agent): make config pulls direct and remove gRPC (#40044) 2026-08-07 06:54:07 +00:00
非法操作
3a4920c595 chore: bump plugin daemon image (#40134) 2026-08-07 06:22:33 +00:00
yyh
276c3b6e02 refactor(web): localize education status query (#40132)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-07 05:29:31 +00:00
Mubelotix
7ff5c85796 docs: Fixes Star History chart (#40115) 2026-08-07 05:23:22 +00:00
yyh
b8330df96e refactor(web): simplify billing portal link (#40131) 2026-08-07 04:26:18 +00:00
yyh
7422052759 fix(web): scope hidden outlines to focus-visible (#40130) 2026-08-07 04:00:19 +00:00
Xiyuan Chen
ab0e131e87 refactor(api): move license expiry notice flag onto license detail (#40128)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-07 03:53:35 +00:00
Asuka Minato
1375dc3864 test: migrate console app sessions to SQLite (#40081)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-07 03:46:27 +00:00
Asuka Minato
6530f2bcdb test: migrate document indexing task sessions to SQLite (#40092)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-07 03:45:56 +00:00
Asuka Minato
7039217c99 test: use sqlite sessions at generation boundaries (#40095) 2026-08-07 03:45:27 +00:00
yyh
924d787e41 fix(web): enforce frame ancestors on protected routes (#40124)
Signed-off-by: yyh <yuanyouhuilyz@gmail.com>
2026-08-07 03:11:30 +00:00
非法操作
baba36d47d chore: improve current workspace summary (#40121)
Co-authored-by: Jingyi-Dify <jingyi.qi@dify.ai>
2026-08-07 03:08:55 +00:00
Xiyuan Chen
4b2c5ac4ae feat: make the console license expiry badge optional (#39972)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-07 02:28:58 +00:00
yyh
73197e4354 refactor(web): modernize Studio app list data flow (#40109) 2026-08-07 02:23:38 +00:00
Jingyi
5dfd83e9ab feat: optimize integrations initial loading (#40118)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-07 02:06:25 +00:00
yyh
6f2e4d72d3 test(e2e): align duplicate Agent publish state (#40108) 2026-08-07 01:56:05 +00:00
Byron.wang
b76a14d71d refactor(api): decouple console queries through application services (#40031) 2026-08-07 00:42:55 +00:00
Yunlu Wen
1983e842ca feat: support azure keyvault (#39933)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: -LAN- <laipz8200@outlook.com>
2026-08-07 00:42:13 +00:00
zyssyz123
90d6046345 fix: gate Agent access until first publish (#40105)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: yyh <yuanyouhuilyz@gmail.com>
2026-08-06 12:36:24 +00:00
盐粒 Yanli
05c7386013 fix(dify-agent): end SSE streams on terminal events (#40042) 2026-08-06 10:53:10 +00:00
盐粒 Yanli
4d0bc32dd3 fix(dify-agent): align agent and shell execution limits (#40043)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-06 10:53:03 +00:00
yyh
d6336c5d49 revert(web): remove redundant slash picker intent tracking (#40103) 2026-08-06 09:20:46 +00:00
yyh
7073baa737 fix(ci): switch Playwright jobs to Azure Ubuntu mirror (#40100) 2026-08-06 09:01:37 +00:00
Asuka Minato
78129cf6c3 test: use SQLite sessions in datasource files (#39048) 2026-08-06 08:28:27 +00:00
Asuka Minato
1a69435fff test: use sqlite3 session in test_external_dataset_service (#38696)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-06 08:27:37 +00:00
yyh
33b238343b chore: remove obsolete development docs (#40098) 2026-08-06 08:21:17 +00:00
github-actions[bot]
4b8a2c7e6c chore(i18n): sync translations with en-US (#40096)
Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
2026-08-06 08:14:10 +00:00
Joel
06d8301a90 fix: report unavailable agent tools in publish and workflow checks (#40077) 2026-08-06 07:44:22 +00:00
yyh
dc309ced59 chore(web): remove obsolete PWA assets (#40082) 2026-08-06 07:41:01 +00:00
Elliot Bai
cf88aef710 feat: support TiDB Vector full-text and hybrid search (#38112)
Co-authored-by: Crazywoola <100913391+crazywoola@users.noreply.github.com>
Co-authored-by: bkidy <bkidyy.macmini@gmail.com>
2026-08-06 07:08:42 +00:00
BoneNI
0277b9eb30 feat: Add Lao (lo-LA) language support #39489 (#39474)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: crazywoola <427733928@qq.com>
2026-08-06 07:00:37 +00:00
Eldar Dadashov
8fbbfbc243 fix(web): register audio listeners on real media events (#37841)
Co-authored-by: crazywoola <427733928@qq.com>
2026-08-06 06:57:58 +00:00
wangxiaolei
5bceac05eb fix: get role and list role need filter billing permission key (#38218)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-06 06:37:52 +00:00
yyh
febcc4e054 chore: format GitHub metadata with Oxfmt (#40073) 2026-08-06 06:37:06 +00:00
Souravrajvi0
36c990a0cf fix(web): only open slash variable picker when / is typed (#39755) (#39761) 2026-08-06 06:36:30 +00:00
yyh
658d5e0dcf fix(e2e): align marketplace plugin download URL (#40075) 2026-08-06 06:32:16 +00:00
yyh
cfef48c408 chore: upgrade workspace dependencies (#40069) 2026-08-06 05:56:30 +00:00
Liu Ziming
1973a2e96f feat(trace-aliyun): GenAI spans for LLM TTFT, agent ReAct, tools, and failed LLM nodes (#39339)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-06 05:51:28 +00:00
Asuka Minato
b105f21763 test: use SQLite sessions in core repositories (#39061)
Co-authored-by: Byron Wang <byron@dify.ai>
2026-08-06 05:50:40 +00:00
Wu Tianwei
e5a07e97a4 fix(web): improve markdown form rendering (#40070) 2026-08-06 05:49:24 +00:00
Asuka Minato
046df1260a test: use SQLite sessions in controllers console app (#39096)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-06 05:25:01 +00:00
Asuka Minato
9e95e1302e test: use SQLite sessions in commands (#39082) 2026-08-06 05:14:38 +00:00
Asuka Minato
59cbba3b37 test: use SQLite sessions in controllers console auth (#39060) 2026-08-06 05:12:35 +00:00
Asuka Minato
20b31de791 test: use SQLite sessions in core entities (#39056)
Co-authored-by: Byron Wang <byron@dify.ai>
2026-08-06 05:10:04 +00:00
yyh
5e036e5489 refactor(system-features): derive nullable SSO protocol (#40063) 2026-08-06 04:51:32 +00:00
Asuka Minato
e6ede05fe9 test: use SQLite sessions in clean dataset (#39051) 2026-08-06 04:49:10 +00:00
Asuka Minato
7edd05100a test: move webhook service coverage to unit tests (#38945)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-06 04:48:27 +00:00
Asuka Minato
46024b6ad8 test: use SQLite sessions in core app apps (#39083)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-06 04:38:15 +00:00
Asuka Minato
123f128ccc test: use real ORM models in app and API tests (#40020) 2026-08-06 04:36:58 +00:00
Joel
6474059eb1 fix: hide log detail actions for legacy app logs (#40057) 2026-08-06 04:18:23 +00:00
Asuka Minato
479a5613a8 test: use real ORM models in dataset service tests (#40018) 2026-08-06 04:14:12 +00:00
Joel
d51900974f fix: offset legacy app error toasts below model controls (#40040)
Co-authored-by: yyh <yuanyouhuilyz@gmail.com>
Co-authored-by: yyh <92089059+lyzno1@users.noreply.github.com>
2026-08-06 04:14:12 +00:00
Asuka Minato
f08cc41546 test: use SQLite sessions in services core (#39058) 2026-08-06 04:07:01 +00:00
Asuka Minato
2443df2e42 test: use real ORM models in workflow repository tests (#40019) 2026-08-06 04:06:04 +00:00
Asuka Minato
2e65ab9d1e test: use SQLite sessions in core tools (#39108) 2026-08-06 03:57:33 +00:00
Aiden
6add64a44d fix(api): allow account avatars across workspaces (#40055)
Co-authored-by: aiden <zhouyuchi@kurogames.com>
2026-08-06 03:33:23 +00:00
非法操作
8170a2a5f3 chore: more upload file size for paid user (#39967)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-06 03:23:16 +00:00
pineapple880066
70051950ab fix: preserve UTF-8 byte size for text uploads (#40034) 2026-08-06 02:25:29 +00:00
csurong
f7881bb635 fix: make document retry batches consistent (#39978)
Co-authored-by: caosurong <surong.cao@thinkingdata.cn>
2026-08-06 02:01:14 +00:00
Escape0707
b6b3e747f3 refactor(api): extract workspace member listing into layered service (#39974)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-06 01:08:39 +00:00
Jingyi
18f740402f fix(web): redirect legacy plugin fallbacks (#40051)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-05 23:27:08 +00:00
Jingyi
15a5317bd3 fix(web): refresh model provider plugins after updates (#40002) 2026-08-05 23:26:18 +00:00
盐粒 Yanli
1369a2cdfc fix(dify-agent): wait for E2B shellctl readiness (#39996) 2026-08-05 11:03:06 +00:00
Asuka Minato
ac0c909d11 test: use real ORM models in RAG indexing tests (#40017) 2026-08-05 10:03:23 +00:00
林玮 (Jade Lin)
945503523b fix(web): improve debug plugin copy accessibility (#40035) 2026-08-05 10:00:37 +00:00
Asuka Minato
fe7e2dc62f test: use sqlite3 session in test_agent_config_service (#38764) 2026-08-05 08:43:40 +00:00
Asuka Minato
3bb21a9a88 test: use sqlite3 session in test_credit_pool_service (#38694) 2026-08-05 08:43:27 +00:00
yyh
dc09384b1d refactor(web): derive system feature enums from schemas (#40030) 2026-08-05 08:32:54 +00:00
yyh
890e5aa294 refactor(web): align query client ownership (#40024) 2026-08-05 07:02:09 +00:00
yyh
0bf3416431 fix(web): remove misleading ARIA states (#40015) 2026-08-05 06:52:41 +00:00
yyh
685e291e65 refactor(web): remove duplicate dataset title update (#40023) 2026-08-05 06:18:09 +00:00
yyh
c15dd6d994 refactor(web): simplify tag selector trigger (#40014) 2026-08-05 05:23:53 +00:00
Joel
72b30ff313 chore: add copy action to workflow log errors (#40011) 2026-08-05 05:15:59 +00:00
yyh
7dd7b3dfa8 fix(ci): make web workflows reproducible (#40010) 2026-08-05 04:08:12 +00:00
yyh
d033124552 fix(ci): harden Playwright browser installs (#40009) 2026-08-05 03:57:08 +00:00
yyh
2fd8f98f2d chore(deps): upgrade Base UI to 1.7.0 (#40006) 2026-08-05 03:55:46 +00:00
Asuka Minato
7d6d173b01 test: use SQLite in Arize Phoenix traces (#38984) 2026-08-05 03:45:06 +00:00
yyh
2dc6b08044 fix(web): preserve feedback state on submission failure (#40004) 2026-08-05 02:55:50 +00:00
Byron.wang
896e5e20c0 refactor(api): extract workspace list into layered application service (#39822)
Co-authored-by: WH-2099 <wh2099@pm.me>
2026-08-05 02:36:16 +00:00
yyh
143bc121da fix(e2e): configure sandbox-reachable API URL (#40005) 2026-08-05 02:28:16 +00:00
zyssyz123
4213e6b150 fix(agent): expose feedback in agent logs (#39994)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-04 14:11:13 +00:00
盐粒 Yanli
b462cb041d feat(agent): separate CLI file URL audiences (#39952)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-04 13:14:02 +00:00
nightcityblade
9d81f0da10 chore(api): remove unreachable match suppressions (#39949)
Co-authored-by: nightcityblade <nightcityblade@gmail.com>
2026-08-04 11:56:37 +00:00
Asuka Minato
482ec5e712 test: use sqlite3 session in test_qa_index_processor (#38765) 2026-08-04 10:53:55 +00:00
Asuka Minato
36a4c98732 test: use sqlite3 session in test_if_else (#38753) 2026-08-04 10:53:42 +00:00
yyh
dec1cb3798 fix(ui): align button spacing with design (#39990) 2026-08-04 10:37:16 +00:00
林玮 (Jade Lin)
3ada29bbe0 fix(api): surface system quota exhaustion without fallback (#39986) 2026-08-04 08:49:25 +00:00
非法操作
8f817644e9 fix(workflow): avoid app context dependency in parallel iteration (#39983) 2026-08-04 07:47:49 +00:00
Joel
0271ca6e5f fix: align build and preview chat layouts (#39980) 2026-08-04 07:07:48 +00:00
-LAN-
aab31292d8 feat(workflow): support LLM environment variables (#39125)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-04 06:17:13 +00:00
-LAN-
545bdecff2 chore(docker): move optional settings to service envs (#39970) 2026-08-04 05:28:05 +00:00
yyh
7d92097526 fix(dify-ui): improve select and status dot accessibility (#39971) 2026-08-04 05:14:02 +00:00
Xiyuan Chen
edcd3fc2e3 fix(api): allow external knowledge base creation under enterprise RBAC (#39930) 2026-08-04 04:50:43 +00:00
yyh
be413650ba chore(web): upgrade Next.js to 16.3 (#39962) 2026-08-04 04:46:44 +00:00
-LAN-
2d2cc7cab1 refactor(workflow): move AgentNode events out of graphon (#39845) 2026-08-04 03:54:40 +00:00
dependabot[bot]
2838957004 chore(deps): bump the vdb group with 9 updates (#39911)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: -LAN- <laipz8200@outlook.com>
2026-08-04 03:40:41 +00:00
Yufeng He
f6852205d2 fix(vdb): bound the TiDB Cloud API timeouts (#39953)
Signed-off-by: Yufeng He <40085740+he-yufeng@users.noreply.github.com>
Co-authored-by: -LAN- <laipz8200@outlook.com>
2026-08-04 03:17:05 +00:00
dependabot[bot]
9802329b91 chore(deps): bump aiohttp from 3.14.1 to 3.14.3 in /api (#39959)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: -LAN- <laipz8200@outlook.com>
2026-08-04 03:14:55 +00:00
盐粒 Yanli
dc5192ba11 fix(dify-agent): make run cancellation route-independent (#39942)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-04 03:11:22 +00:00
盐粒 Yanli
21dbc6c60c fix(dify-agent): keep tmux server alive without sessions (#39943) 2026-08-04 03:09:11 +00:00
dependabot[bot]
a1769d0b3d chore(deps): bump cryptography from 49.0.0 to 50.0.0 in /dify-agent (#39958)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: -LAN- <laipz8200@outlook.com>
2026-08-04 03:02:14 +00:00
林玮 (Jade Lin)
be0e2c03e4 feat(api): isolate credentials from local packages (#39957) 2026-08-04 02:50:04 +00:00
Xiyuan Chen
1b7a132afa fix(api): validate installation scope for cached marketplace packages (#39935) 2026-08-04 02:22:45 +00:00
Xiyuan Chen
f2d0001424 fix(api): bump OpenTelemetry to stop duplicate Flask context detach (#39921) 2026-08-04 02:17:53 +00:00
yyh
9ea21e4fd1 perf(web): streaming ssr for home page (#39922) 2026-08-04 02:16:08 +00:00
yyh
5456d4d56e fix(web): improve main navigation responsiveness and tour focus (#39940)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-03 19:05:49 +00:00
Asuka Minato
b4f360127d test: use SQLite sessions in core app apps (#39079) 2026-08-03 15:45:14 +00:00
Asuka Minato
f15a514878 test: use SQLite sessions in core test_provider_manager.py (#39071)
Co-authored-by: Byron Wang <byron@dify.ai>
2026-08-03 15:44:54 +00:00
Asuka Minato
ca1cec6011 test: use SQLite sessions in controllers console explore (#39064) 2026-08-03 15:44:43 +00:00
Asuka Minato
0a05328eb2 test: use SQLite sessions in controllers service api (#39059) 2026-08-03 15:44:25 +00:00
Asuka Minato
6e9a3f8654 test: use SQLite sessions in rag pipeline dsl (#39053) 2026-08-03 15:43:43 +00:00
Asuka Minato
730794426a test: use SQLite sessions in web controller fixtures (#39052) 2026-08-03 15:41:56 +00:00
yyh
a77236e564 fix(web): remove Web Apps loading skeleton (#39939) 2026-08-03 13:41:29 +00:00
yyh
984045190c fix(web): improve home accessibility (#39938) 2026-08-03 13:41:15 +00:00
Ingram Z
612ad161bc fix(dify-agent): atomically finalize run terminals (#39929)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-03 12:02:09 +00:00
mengnanjiugaipeifense
e2bc8f2c17 fix: keep colons in HTTP node form body values on migration (#38861)
Co-authored-by: xiaweiwei67-stack <293320877+xiaweiwei67-stack@users.noreply.github.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-03 08:39:04 +00:00
wangxiaolei
dc8dd09450 feat: pass image file to llm (#39848)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-03 06:04:32 +00:00
Asuka Minato
982c0667e1 chore: bump pyrefly version (#39876)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-03 05:59:01 +00:00
Ingram Z
66a69c30f5 fix(dify-agent): stabilize E2B config materialization (#39873) 2026-08-03 05:38:05 +00:00
Harsh Kashyap
a5f5acbe0c fix(api): stop echoing the raw api_key in the 403 error message (#39888) (#39902)
Co-authored-by: Harsh Kashyap <Harsh23Kashyap@users.noreply.github.com>
2026-08-03 03:18:06 +00:00
wangxiaolei
2f52ac94fe chore: keep dify-agent env same with dify (#39918) 2026-08-03 03:17:14 +00:00
Wu Tianwei
5d151ec214 fix(web): clarify member permission exception copy (#39917) 2026-08-03 02:51:51 +00:00
Hand Sonic
bb68a05f9e chore: pass session explicitly in ApiModeration (#39885) 2026-08-03 02:33:18 +00:00
dependabot[bot]
61583e3f0f chore(deps): bump the github-actions-dependencies group with 2 updates (#39909)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-08-03 02:32:24 +00:00
-LAN-
351577bdb0 feat(workflow): support human input in loop and iteration (#39243)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-03 02:24:18 +00:00
Harsh Kashyap
8dbac96621 fix(vdb-oceanbase): reject trailing newlines in metadata-key and document-id validators (#39884) (#39901)
Co-authored-by: Harsh Kashyap <Harsh23Kashyap@users.noreply.github.com>
2026-08-03 02:17:13 +00:00
Hassan Rady
26b4798e88 perf(dataset): fix N+1 database insert bottleneck in Notion sync (#39899) 2026-08-03 00:57:22 +00:00
yyh
802fe70423 test(web): remove Base UI component mocks (#39877) 2026-08-02 09:51:45 +00:00
Harsh Kashyap
02a9c51a3e fix(api): bound JinaReader and adaptive-crawl HTTP timeouts (#39859) (#39860)
Co-authored-by: Harsh Kashyap <Harsh23Kashyap@users.noreply.github.com>
2026-08-02 02:49:17 +00:00
Taranum Wasu
83b3a8fd88 fix(api): make SSRF-blocked error message actionable (#39867)
Co-authored-by: Taranum01 <50813317+Taranum01@users.noreply.github.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-02 02:48:44 +00:00
csurong
8a2cf65ec5 fix(matrixone): apply score threshold to vector search (#39784)
Co-authored-by: caosurong <surong.cao@thinkingdata.cn>
2026-08-02 02:43:56 +00:00
kenwoodjw
a42d486bc0 fix(api): prevent cookies from shadowing admin API keys (#39872)
Signed-off-by: kenwoodjw <blackxin55+@gmail.com>
2026-08-02 02:43:29 +00:00
yyh
b6824334cf refactor(web): align Base UI state consumers (#39864)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-01 13:09:30 +00:00
Harsh Kashyap
eec0e2e44e fix(api): bound billing service HTTP timeouts (#39874) (#39875)
Co-authored-by: Harsh Kashyap <Harsh23Kashyap@users.noreply.github.com>
2026-08-01 10:46:13 +00:00
Jony
f6832fddee chore(api): fix typos in config description and comment (#39870)
Co-authored-by: Jony <13896935+zyz619963502zyz@users.noreply.github.com>
2026-08-01 07:41:28 +00:00
WH-2099
e7380865d8 fix(api): scope segment batch deletes (#38217) 2026-08-01 01:39:40 +00:00
yyh
c4d9919d30 fix(web): align secondary sidebar help trigger (#39862) 2026-07-31 20:33:27 +00:00
Chester
4557f127ff fix(auth): add bounded timeout to WaterCrawl credential validation (#39824) 2026-07-31 13:52:02 +00:00
Chester
97e9d8be5a fix(rag): add bounded timeout to Notion extractor requests (#39833) 2026-07-31 13:41:44 +00:00
Chester
074811106d fix(rag): add bounded timeout to Firecrawl extractor requests (#39831) 2026-07-31 13:41:19 +00:00
Asuka Minato
33518407c9 test: use SQLite sessions in services workflow (#39087) 2026-07-31 12:54:41 +00:00
Asuka Minato
f6bbb94112 test: use SQLite sessions in core workflow (#39086) 2026-07-31 12:54:30 +00:00
Asuka Minato
917207414b test: use SQLite sessions in core callback_handler (#39081) 2026-07-31 12:54:20 +00:00
Asuka Minato
753583c06c test: use SQLite sessions in core repositories (#39078) 2026-07-31 12:54:10 +00:00
Asuka Minato
8c4c1dc656 test: use SQLite sessions in core llm_generator (#39070) 2026-07-31 12:54:00 +00:00
Asuka Minato
bab3db7f77 test: use SQLite sessions in core tools (#39068) 2026-07-31 12:53:50 +00:00
Asuka Minato
9ee7750411 test: use SQLite sessions in core ops (#39062)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-31 12:53:32 +00:00
Asuka Minato
5800338911 test: use SQLite sessions in core rag (#39055) 2026-07-31 12:52:42 +00:00
Asuka Minato
5e71fdde0f test: use SQLite sessions in services agent (#39054) 2026-07-31 12:52:11 +00:00
yyh
7e30aba12a refactor(ui): simplify scroll area API (#39857) 2026-07-31 12:43:11 +00:00
yyh
c62ab071eb fix(web): hide prompt log action in agent v2 logs (#39858) 2026-07-31 12:40:44 +00:00
非法操作
b4d93b02fd fix(web): skip auth validation for local file datasource (#39856) 2026-07-31 09:55:48 +00:00
Joel
37bf80dcf6 feat: prioritize configured tools in the agent prompt picker (#39850) 2026-07-31 08:50:54 +00:00
KVOJJJin
f9966c2ee4 fix(workflow): remap snippet references (#39843) 2026-07-31 06:57:10 +00:00
Bond Zhu
c562f78d4f fix(api): silence opentelemetry.context error reports to Sentry on cloud (#39841) 2026-07-31 05:32:02 +00:00
iridescentWen
0d8c02ca62 docs: fix typos in api comments and prompt example (#39838) 2026-07-31 05:30:53 +00:00
Xin Zhang
4b415e7d6b fix: refresh mcp server code by app id (#39828)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-31 04:57:02 +00:00
Escape0707
676dff04c8 test: exercise credential visibility with SQLite (#39827) 2026-07-31 03:20:21 +00:00
Parman Mohammadalizadeh
908dc703ec chore(api): consolidate chained .where() calls into single calls (#39819) 2026-07-30 16:59:50 +00:00
起岚
bea2f78e09 docs: remove trailing whitespace in docker/README.md (#39808) 2026-07-30 16:45:37 +00:00
yyh
5e6154fdd1 refactor(web): align Base UI composition contracts (#39820) 2026-07-30 13:37:04 +00:00
wangxiaolei
69a16d8319 feat: change api/v1/plugins/download to api/v1/plugins/download-url (#39811) 2026-07-30 10:23:29 +00:00
yyh
563cf2602f refactor(dify-ui): govern public component APIs (#39806)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-30 10:12:34 +00:00
Evan
3aa937def4 test: use caplog for telemetry error logging (#39722) 2026-07-30 09:32:56 +00:00
Escape0707
f057a7d32f test: use SQLite sessions in app DSL service tests (#39803) 2026-07-30 09:31:12 +00:00
林玮 (Jade Lin)
8cca3959ae feat: make skill package upload size limit configurable (#39799) 2026-07-30 08:42:24 +00:00
yyh
48bb46a72b fix(ui): align select trigger focus ring (#39804) 2026-07-30 08:40:20 +00:00
yyh
6a52069872 refactor(web): narrow app list context (#39802) 2026-07-30 08:24:22 +00:00
yyh
72afcc1326 refactor(web): remove stale header maximize state (#39801) 2026-07-30 08:20:41 +00:00
yyh
e834fa212d refactor(web): remove dead dataset operator context state (#39800) 2026-07-30 08:20:31 +00:00
Joel
b32c900761 feat: add upload size guidance and validation for agent files and skills (#39798) 2026-07-30 07:57:53 +00:00
Jingyi
e8b17345c3 fix(web): isolate MCP card action overlays (#39797) 2026-07-30 07:51:20 +00:00
yyh
95166806ae refactor(web): remove configuration mitt context (#39796) 2026-07-30 07:07:43 +00:00
yyh
e4947811a5 refactor(web): localize retrieval method query (#39795) 2026-07-30 07:07:32 +00:00
yyh
0bb1b4d6d2 refactor(web): internalize trigger limit modal state (#39794) 2026-07-30 07:07:23 +00:00
yyh
01ff1b5128 refactor(web): remove app log drawer context (#39792) 2026-07-30 06:11:33 +00:00
yyh
71ae1d5511 refactor(web): localize dataset external API state (#39791) 2026-07-30 06:11:23 +00:00
yyh
3d01e8389a fix(chat): derive themes per chat root (#39790) 2026-07-30 06:11:13 +00:00
yyh
44a3ea7c0c refactor(web): localize model load balancing modal state (#39789) 2026-07-30 06:10:57 +00:00
Rafli Surya Wijaya
1fd9ab14f9 fix(workflow): provide default values for AgentNodeData fields (#39743) (#39754)
Co-authored-by: -LAN- <laipz8200@outlook.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-30 05:23:48 +00:00
Asuka Minato
0aefcfa373 test: use SQLite sessions in tasks (#39076) 2026-07-30 05:18:19 +00:00
Asuka Minato
09d5aa47bb test: use sqlite3 session in test_workflow_node_execution_truncation (#38734) 2026-07-30 04:47:38 +00:00
Asuka Minato
b852252076 test: use sqlite3 session in test_trial (#38732) 2026-07-30 04:47:18 +00:00
Asuka Minato
814fee5550 test: use sqlite3 session in test_factory (#38731) 2026-07-30 04:39:16 +00:00
Asuka Minato
754c380e2d test: use sqlite3 session in test_billing (#38722) 2026-07-30 04:39:04 +00:00
Asuka Minato
9f17e1ca95 test: move RAG pipeline import coverage to unit tests (#38938) 2026-07-30 04:32:23 +00:00
Asuka Minato
61a5b4d205 test: use SQLite sessions in core tools (#39094) 2026-07-30 04:23:36 +00:00
Asuka Minato
7b33622cdd test: use SQLite in Langfuse traces (#38985) 2026-07-30 04:14:18 +00:00
Asuka Minato
942a16b2a5 test: use SQLite in Opik traces (#38987) 2026-07-30 04:13:58 +00:00
Joel
97a13b6c36 fix: open inline agent editor from checklist warnings (#39781) 2026-07-30 03:22:07 +00:00
李政达
7fd2f4f4e8 fix(api): prevent HITL pause from aborting workflow resume (#39485)
Co-authored-by: 李政达 <1242427577@qq.com>
Co-authored-by: QuantumGhost <obelisk.reg+git@gmail.com>
2026-07-30 03:21:28 +00:00
Asuka Minato
1593b7cc60 test: use SQLite sessions in core app apps (#39102)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-30 03:18:31 +00:00
Asuka Minato
3f1036e55a test: use SQLite sessions in core app apps (#39101) 2026-07-30 03:18:09 +00:00
Asuka Minato
7c9a0ce93b test: use SQLite sessions in controllers console app (#39097)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-30 03:17:48 +00:00
Asuka Minato
9e8733413a test: use SQLite sessions in controllers console app (#39095)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-30 03:07:43 +00:00
Asuka Minato
3453fdce44 test: use SQLite sessions in core rag (#39092)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-30 03:04:18 +00:00
Asuka Minato
6804dd474d test: use SQLite sessions in services workflow (#39091)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-30 03:03:47 +00:00
Asuka Minato
edd6a6e77f test: use SQLite sessions in core repositories (#39073) 2026-07-30 02:53:50 +00:00
Asuka Minato
19b0a8ce08 test: use SQLite sessions in core repositories (#39067) 2026-07-30 02:53:38 +00:00
Asuka Minato
e12e86a308 test: use sqlite3 session in test_completion_completion_app_generator (#38723) 2026-07-30 02:45:54 +00:00
Asuka Minato
b855d71adb test: use SQLite sessions in rag pipeline transform (#39050) 2026-07-30 02:43:48 +00:00
Asuka Minato
87aa982185 test: use SQLite sessions in services data_migration (#39065) 2026-07-30 02:41:42 +00:00
Asuka Minato
bea82fb57f test: use SQLite sessions in services tools (#39063) 2026-07-30 02:39:55 +00:00
yyh
a21d2b1201 fix(web): constrain slash picker triggers (#39768) 2026-07-30 02:23:52 +00:00
Souravrajvi0
fdaa073d53 fix(api): delete custom models stored with legacy model_type values (#39708)
Co-authored-by: Crazywoola <100913391+crazywoola@users.noreply.github.com>
2026-07-30 01:12:26 +00:00
Jony
89ceba027e fix: allow an empty Agent tools selection (#39695) 2026-07-30 01:06:32 +00:00
Checo
832f42a996 fix(socketio): omit socket_timeout from RedisManager pub/sub options (#39587)
Signed-off-by: sergioperezcheco <checo520@outlook.com>
2026-07-30 00:50:21 +00:00
zyssyz123
72c20daa61 fix(plugin): preserve credentials during local replacement (#39764)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-29 12:39:06 +00:00
yyh
81fd1da3ff fix: refactor account about dialog ownership (#39765) 2026-07-29 12:33:26 +00:00
csurong
fc2f1f4f75 fix(matrixone): generate ids for every document (#39734)
Co-authored-by: caosurong <surong.cao@thinkingdata.cn>
2026-07-29 12:31:11 +00:00
wangxiaolei
080a1d42f2 fix: fix hardcode /home/dify (#39767) 2026-07-29 12:27:38 +00:00
Stephen Zhou
0441d27cac chore: canonicalize Tailwind classes (#39762) 2026-07-29 11:58:14 +00:00
Escape0707
10621b5a9e test: migrate account service tests to shared SQLite (#39758) 2026-07-29 11:43:32 +00:00
非法操作
c1fdd6fb78 chore: paginate installed apps (#39739)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: yyh <yuanyouhuilyz@gmail.com>
Co-authored-by: yyh <92089059+lyzno1@users.noreply.github.com>
2026-07-29 09:51:34 +00:00
Joel
fd804dfcc0 fix(web): show API errors when agent publishing fails (#39756) 2026-07-29 09:37:18 +00:00
Asuka Minato
155e4fbdc5 test: use SQLite in Tencent traces (#38988) 2026-07-29 09:25:26 +00:00
David Park
20b9278ca3 fix(docker): mount shared storage volume in api_websocket (#39424) 2026-07-29 09:00:37 +00:00
Asuka Minato
2844948aa0 test: use SQLite sessions in core app (#39100)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-29 08:14:06 +00:00
Asuka Minato
62791579ab test: move service dataset controller coverage to unit tests (#38941)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Byron Wang <byron@dify.ai>
2026-07-29 07:57:35 +00:00
yyh
dbabddf1ab fix(web): force render dialog backdrop and use dialog description in education verify modal (#39749) 2026-07-29 07:43:21 +00:00
yyh
3ad925a66a refactor(web): clarify education state ownership (#39748) 2026-07-29 07:25:54 +00:00
Joel
54aced9e20 fix: display workflow run errors in the result panel (#39746) 2026-07-29 07:24:48 +00:00
非法操作
0d6b2fc40c fix: avoid returning unused vectors in TiDB on Qdrant search (#39744) 2026-07-29 06:51:18 +00:00
林玮 (Jade Lin)
14a938c5c5 fix: handle unconfigured LLM workflow streams (#39741) 2026-07-29 06:07:24 +00:00
yyh
d4eab4ae88 refactor(web): consolidate settings state in URL (#39740) 2026-07-29 06:00:55 +00:00
Asuka Minato
8629b91517 test: use SQLite sessions in libs (#39089) 2026-07-29 05:53:33 +00:00
Asuka Minato
0290c8d525 test: use SQLite sessions in core rag (#39106) 2026-07-29 05:52:45 +00:00
Asuka Minato
c5b0772ab0 test: use SQLite sessions in core tools (#39107)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-29 05:52:33 +00:00
Asuka Minato
8e74d7d715 test: use sqlite3 session in test_session (#38772) 2026-07-29 05:51:02 +00:00
Asuka Minato
103c864b35 test: use sqlite3 session in test_sqlalchemy_workflow_execution_repository (#38761) 2026-07-29 05:50:43 +00:00
Asuka Minato
133e974dff test: use sqlite3 session in test_metadata_bug_complete (#38721) 2026-07-29 05:50:26 +00:00
Asuka Minato
958d8a7997 test: use sqlite3 session in test_human_input_timeout_tasks (#38703) 2026-07-29 05:49:56 +00:00
Asuka Minato
b6bfae7e3c test: use sqlite3 session in test_workflow_pause_events (#38688) 2026-07-29 05:49:15 +00:00
yyh
8946d7fbf4 refactor(web): remove workflow node useBoolean usage (#39729) 2026-07-29 03:07:30 +00:00
非法操作
e604fad630 fix(web): gate plugin auth permission hint (#39721) 2026-07-29 02:07:57 +00:00
Xiyuan Chen
f07cc3dfb4 chore(deps): bump wandb 0.28.0 -> 0.28.1 for CVE fix attempt (#39718) 2026-07-29 02:01:54 +00:00
盐粒 Yanli
6506aaae83 chore: add E2B sync and tini supervision (#39705) 2026-07-29 02:01:25 +00:00
盐粒 Yanli
f6683c2c6b feat(agent): make home snapshots optional and use backend defaults (#39702)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-29 02:01:12 +00:00
Xiyuan Chen
7eba562f7d chore(deps): bump starlette, soupsieve, cryptography for CVE fixes (#39716) 2026-07-29 01:47:29 +00:00
yyh
fd412a82e9 refactor(e2e): unify seeded runtime orchestration (#39700) 2026-07-28 15:05:20 +00:00
Escape0707
1419c7c6db test: share unbound unit test sessions (#39690) 2026-07-28 14:12:08 +00:00
Escape0707
7083a953e1 test: enforce strict typing in migrated unit tests (#39689) 2026-07-28 14:04:56 +00:00
yyh
93e7d50845 test(e2e): align Agent tool credential states (#39698) 2026-07-28 13:41:23 +00:00
盐粒 Yanli
a048f35099 refactor: introduce agent working environment architecture (#39480)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-28 13:16:05 +00:00
Yunlu Wen
22cef67804 chore(deps): bump gitpython from 3.1.54 to 3.1.57 in /api (#39684) 2026-07-28 10:27:16 +00:00
Joel
3bc8c69def feat: label agent conversation reset action on hover (#39691) 2026-07-28 10:06:46 +00:00
yyh
798e5ed7a7 refactor(web): derive workspace billing from current workspace (#39674)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-28 09:32:03 +00:00
Escape0707
eef709e475 ci: enforce strict checks for unit tests (#39682) 2026-07-28 09:10:02 +00:00
Escape0707
04158ac8ea ci: replace custom noqa markers with guard ignores (#39679) 2026-07-28 08:52:12 +00:00
Joel
ae0b66311d feat: add missing plugin installation to agent DSL imports (#39680) 2026-07-28 08:23:42 +00:00
dependabot[bot]
b97abe5328 chore: bump nltk from 3.9.4 to 3.10.0 in /api (#39503)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: yunlu.wen <yunlu.wen@dify.ai>
2026-07-28 08:19:15 +00:00
Jyong
d94314627f ci: wait for KnowledgeFS before deployment (#39677) 2026-07-28 07:12:29 +00:00
Shakti
7ec6a57ddf fix: populate completion_params from model schema defaults in Agent node (#39590) 2026-07-28 07:06:49 +00:00
Joel
35b539e35b fix: improve unconfigured agent guidance (#39676) 2026-07-28 07:02:49 +00:00
Asuka Minato
3b040e6bed test: use sqlite3 session in test_web_login (#38725)
Co-authored-by: Byron.wang <byron@dify.ai>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-28 06:37:45 +00:00
Asuka Minato
9300be03f0 test: use sqlite3 session in test_agent_app_feature_service (#38724) 2026-07-28 06:32:07 +00:00
github-actions[bot]
137d4f3f60 chore(i18n): sync translations with en-US (#39671)
Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Co-authored-by: yyh <92089059+lyzno1@users.noreply.github.com>
2026-07-28 06:11:36 +00:00
Asuka Minato
e723b348cf test: use SQLite sessions in core app apps (#39103)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-28 05:54:17 +00:00
Harsh Kashyap
59fb603ec6 fix: reject trailing newlines in alphanumeric() validator (#39666) (#39667)
Co-authored-by: Harsh Kashyap <Harsh23Kashyap@users.noreply.github.com>
2026-07-28 05:49:19 +00:00
Asuka Minato
63f072ebfb test: use SQLite sessions in core rag (#39105)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-28 05:47:22 +00:00
Asuka Minato
0913d04d33 test: use SQLite sessions in services retention (#39074)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-28 05:47:01 +00:00
Asuka Minato
80ff108fc0 test: use SQLite in Aliyun trace utilities (#38983) 2026-07-28 05:40:27 +00:00
Asuka Minato
ea58129ebe test: move workflow app service coverage to unit tests (#38946) 2026-07-28 05:34:59 +00:00
-LAN-
698869460c chore(docker): remove redundant feature preview env (#39035) 2026-07-28 05:34:35 +00:00
Asuka Minato
f3f2f63110 test: use SQLite in LangSmith traces (#38986) 2026-07-28 05:26:52 +00:00
Asuka Minato
b100cdc382 test: use SQLite sessions in core app (#39099)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-28 05:22:47 +00:00
Asuka Minato
9e90b32991 test: use SQLite sessions in core datasource (#39104)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-28 05:22:18 +00:00
非法操作
b2d54cb2e9 chore: improve archived logs hint in logs list page (#39659) 2026-07-28 05:15:35 +00:00
yyh
1e5e47b889 fix: validate plugin installation scope (#39669) 2026-07-28 04:13:20 +00:00
Asuka Minato
dd28b0d165 test: move OAuth server service coverage to unit tests (#38931)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Byron.wang <byron@dify.ai>
2026-07-28 04:09:32 +00:00
Joel
49e74e2f58 fix: prevent the model selector footer from covering options (#39668) 2026-07-28 04:02:28 +00:00
Joel
e6e5d761c2 fix: prevent Safari from clipping the settings close button (#39664)
Co-authored-by: yyh <92089059+lyzno1@users.noreply.github.com>
2026-07-28 04:01:12 +00:00
Asuka Minato
e1ce808567 test: move data source controller coverage to unit tests (#38924) 2026-07-28 03:51:22 +00:00
Asuka Minato
3c7ad816d9 test: use SQLite sessions in commands (#39080) 2026-07-28 03:29:02 +00:00
Asuka Minato
f44dd343da test: use sqlite3 session in test_plugin_service (#38727) 2026-07-28 03:27:58 +00:00
Asuka Minato
2d9b2d50f3 test: use sqlite3 session in test_wraps (#38770) 2026-07-28 03:27:22 +00:00
Asuka Minato
003e0f9614 test: move message cleanup coverage to unit tests (#38932) 2026-07-28 03:26:43 +00:00
Asuka Minato
da0979b373 test: use SQLite sessions in services core (#39090)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Byron.wang <byron@dify.ai>
2026-07-28 03:20:27 +00:00
Asuka Minato
81fb57639e test: use SQLite sessions in controllers service api (#39098)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Byron.wang <byron@dify.ai>
2026-07-28 03:19:17 +00:00
Asuka Minato
1e61078e93 test: use SQLite sessions in services core (#39088) 2026-07-28 03:18:32 +00:00
Escape0707
b597bb1b17 test: separate human input unit and database paths (#39655) 2026-07-28 03:18:01 +00:00
Asuka Minato
65ead05dfc test: use SQLite sessions in services plugin (#39084)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Byron.wang <byron@dify.ai>
2026-07-28 03:16:19 +00:00
wangxiaolei
6f8ed69ee1 fix: fix mcp output_schema is optional (#39453)
Co-authored-by: yunlu.wen <yunlu.wen@dify.ai>
2026-07-28 02:31:18 +00:00
Yunlu Wen
59b879d2df chore: bump version to 1.16.1 (#39653)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-28 01:09:25 +00:00
Xiyuan Chen
a57b0b9b58 feat(plugin): allow disabling the tenant plugin model providers cache (#39632) 2026-07-27 23:53:59 +00:00
Xiyuan Chen
d8506efed6 fix(cli): decouple release script tests from the live compat window (#39658) 2026-07-27 23:50:05 +00:00
Jingyi
b25b28cc76 fix(workflow): align block icon vector sizes (#39657) 2026-07-27 23:43:03 +00:00
yyh
f68cabe226 fix(web): align tour trigger DOM order (#39654)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-27 13:00:16 +00:00
Asuka Minato
f73f83c5d6 test: use SQLite sessions in core app (#39075)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Byron.wang <byron@dify.ai>
2026-07-27 10:45:16 +00:00
Asuka Minato
29801d6a65 test: use SQLite sessions in core tools (#39077)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Byron.wang <byron@dify.ai>
2026-07-27 10:45:11 +00:00
Asuka Minato
75016e8bfe test: use SQLite sessions in core ops (#39072)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Byron.wang <byron@dify.ai>
2026-07-27 10:41:17 +00:00
yyh
b6dea7b2ba fix(workflow): preserve latest collaboration session (#39646) 2026-07-27 10:37:45 +00:00
yyh
b2b1cd7e97 chore: update workspace dependencies (#39641) 2026-07-27 10:27:31 +00:00
Asuka Minato
ca63e01d45 test: use SQLite sessions in controllers service api (#39069)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Byron.wang <byron@dify.ai>
2026-07-27 10:26:23 +00:00
yyh
271b6e1f5c fix(ui): unify combobox trigger focus rings (#39643) 2026-07-27 10:21:32 +00:00
Asuka Minato
609ddf9e01 test: use SQLite sessions in core memory (#39066)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Byron.wang <byron@dify.ai>
2026-07-27 10:15:08 +00:00
Asuka Minato
9fd1fea58c test: use SQLite sessions in services core (#39057)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Byron.wang <byron@dify.ai>
2026-07-27 09:36:44 +00:00
Joel
8de3b4d033 fix: prevent the agent build draft UI from flashing during apply (#39642) 2026-07-27 09:32:52 +00:00
dependabot[bot]
d9c038daf2 chore(deps): bump the storage group across 1 directory with 3 updates (#39604)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-27 09:24:58 +00:00
Asuka Minato
c9c057fd04 test: use SQLite sessions in rag retrieval (#39049)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Byron.wang <byron@dify.ai>
2026-07-27 09:12:30 +00:00
dependabot[bot]
85189be53d chore: bump pymdown-extensions from 10.21.2 to 11.0 in /dify-agent (#39618)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-27 09:10:22 +00:00
Asuka Minato
01e736aaf7 test: use sqlite3 session in test_extract_thread_messages (#38739)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-27 09:00:47 +00:00
dependabot[bot]
a28969f564 chore(deps): bump golang.org/x/net from 0.53.0 to 0.55.0 in /dify-agent-runtime (#39025)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-27 08:58:40 +00:00
Asuka Minato
42f9610ba5 test: use sqlite3 session in test_api (#38733) 2026-07-27 08:57:51 +00:00
dependabot[bot]
1a7ffbe5ee chore: bump gitpython from 3.1.52 to 3.1.54 in /api (#39619)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-27 08:57:44 +00:00
Joel
481354ca70 refactor: make agent composer save and publish state consistent (#39637) 2026-07-27 08:43:45 +00:00
Yunlu Wen
3c80857ea3 feat: add bearer auth to agent backend (#39622)
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-07-27 08:37:30 +00:00
Xiyuan Chen
94702efbc2 fix: gate service API, MCP and trigger surfaces on enterprise license (#39635) 2026-07-27 08:23:15 +00:00
Asuka Minato
755f7b0e8b test: use sqlite3 session in test_workflow_comment_service (#38700) 2026-07-27 08:22:45 +00:00
Asuka Minato
a1c9564b30 test: use sqlite3 session in test_llm_generator_missing (#38742) 2026-07-27 08:22:16 +00:00
Asuka Minato
97acd9c70b test: use sqlite3 session in test_utils (#38729) 2026-07-27 08:21:39 +00:00
Asuka Minato
71601bf76c test: use sqlite3 session in test_draft_var_loader_simple (#38702) 2026-07-27 08:20:18 +00:00
Asuka Minato
460efbf285 test: use sqlite3 session in test_workflow_run_service (#38701) 2026-07-27 08:19:32 +00:00
Escape0707
a752f43b8e test: use pristine file-backed SQLite fixtures (#39624)
Co-authored-by: Asuka Minato <i@asukaminato.eu.org>
2026-07-27 08:07:05 +00:00
非法操作
b3774bfe1c perf: add lightweight recent apps endpoint (#39625)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-27 08:00:39 +00:00
yyh
4313d23889 perf(web): lazy-load Home creation modals (#39634) 2026-07-27 07:48:35 +00:00
林玮 (Jade Lin)
26a43db6a4 fix(api): wait for workflow worker cleanup before task completion (#39614) 2026-07-27 07:34:25 +00:00
yyh
e5d40336b3 fix(workflow): lazy-load Loro collaboration runtime (#39631) 2026-07-27 07:15:13 +00:00
yyh
58e2bcbba1 fix(web): stop reporting workspace status (#39626) 2026-07-27 06:22:37 +00:00
Yunlu Wen
e1b55f54e6 feat(agent): add a squid proxy for agent sandbox (#39544)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-27 06:21:20 +00:00
Yunlu Wen
989039db6e fix: use jinja sandbox (#39609)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-27 06:03:01 +00:00
Joel
52428df1bd feat: add amptitude to new agent (#39608)
Co-authored-by: 林玮 (Jade Lin) <linw1995@icloud.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-27 05:54:45 +00:00
yyh
28d174603f fix: align workspace card plan ownership (#39616)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-27 05:01:02 +00:00
Xiyuan Chen
b6099d09ff feat(inner_api): add endpoint to invalidate plugin model providers cache (#39468) 2026-07-27 04:33:36 +00:00
dependabot[bot]
2962a7ea93 chore(deps): bump the github-actions-dependencies group with 6 updates (#39603)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-27 04:32:09 +00:00
zyssyz123
cc01189966 fix(agent): expose publish state from composer (#39615) 2026-07-27 04:05:38 +00:00
dependabot[bot]
d563d6e7df chore: bump pypdf from 6.10.2 to 6.14.2 in /dify-agent (#39502)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-27 03:56:57 +00:00
CYJ1226
e4e99d198b fix: preserve spaces during recursive text splitting (#39498) 2026-07-27 03:21:26 +00:00
yyh
34e6e5a049 refactor(web): simplify Dify logo theming (#39580) 2026-07-27 03:01:24 +00:00
林玮 (Jade Lin)
7e6ba05464 feat(api): expose app mode in webapp site response (#39607)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-27 02:57:18 +00:00
Madan kumar
aeda37db68 fix(rag): stop the document cleaner from stripping valid characters ï, ¿, ¾ (#39215) 2026-07-27 02:53:33 +00:00
FFXN
441f9f9ec0 fix: The expiration time for web app login to JWT is incorrectly set. (#39537) 2026-07-27 02:43:32 +00:00
Taranum Wasu
f16c249b1e fix(api): honor array-element limit and byte budget for list[File] in VariableTruncator (#39218) (#39220)
Co-authored-by: Taranum Wasu <taranumwasu@Taranums-MacBook-Pro.local>
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-27 02:12:57 +00:00
FFXN
858b3b74dc feat: add CE telemetry report (#39452)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-27 02:04:28 +00:00
David Park
d5c0e927c6 fix(web): stop chunk length/overlap inputs collapsing to an unusable width in narrow containers (#39600)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-27 02:03:17 +00:00
Asuka Minato
b81737cfb3 test: use sqlite3 session in test_message_service (#38698) 2026-07-27 02:01:47 +00:00
Asuka Minato
e5496e04c5 test: use sqlite3 session in test_snippet (#38691) 2026-07-27 01:53:52 +00:00
Benjamin
75c54bd40b fix(workflow): stop dropping unsaved edits when collaboration never c… (#39579)
Co-authored-by: hjlarry <hjlarry@163.com>
2026-07-27 01:23:28 +00:00
yyh
119b6532fd refactor(workflow): remove hook barrel exports (#39588)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-26 14:16:18 +00:00
yyh
c61d33f91e refactor: move trial app capability out of system features (#39562) 2026-07-26 12:02:30 +00:00
yyh
99c1cb7781 fix(web): prevent search hotkey hydration mismatch (#39574) 2026-07-26 07:08:48 +00:00
yyh
448e378fc0 fix(dify-ui): honor instant popup transitions (#39572) 2026-07-26 07:08:27 +00:00
SpiliosDmk
8511a3143e docs: Broken Grafana link in Turkish README (placeholder text instead of URL) (#39575) 2026-07-26 06:43:25 +00:00
yyh
fd2e26f8e6 refactor(agents): simplify repository context (#39583) 2026-07-26 06:13:37 +00:00
Yunlu Wen
1d34184999 chore(agent): update && simplify readme (#39584) 2026-07-26 05:08:58 +00:00
SpiliosDmk
ac0320a70d docs: fix typos in ValueSourceType docstring (#39573)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-26 03:50:52 +00:00
SpiliosDmk
4a44befb00 chore: Broken docker-compose.yaml link in Hindi README (missing slash) (#39576) 2026-07-26 03:36:05 +00:00
SpiliosDmk
5aa2092d0f chore: Grammar fix in VDB provider README ("a importable") (#39577) 2026-07-25 19:36:17 +00:00
Asuka Minato
99ed826a55 test: use sqlite3 session in test_pipeline_template_base (#38730) 2026-07-25 14:30:01 +00:00
Asuka Minato
a45f862fb2 test: use sqlite3 session in test_workflow_node_execution_offload (#38728) 2026-07-25 14:23:32 +00:00
Asuka Minato
00496ec867 test: use sqlite3 session in test_encrypter (#38726) 2026-07-25 14:19:49 +00:00
Asuka Minato
58592e1cb1 test: use sqlite3 session in test_llm_quota (#38720) 2026-07-25 14:12:17 +00:00
Asuka Minato
e6efbb08df test: use sqlite3 session in test_metadata_nullable_bug (#38717) 2026-07-25 14:05:52 +00:00
Asuka Minato
662a77213d test: use sqlite3 session in test_wraps (#38716) 2026-07-25 14:05:25 +00:00
Asuka Minato
c2d560ea26 test: use sqlite3 session in test_easy_ui_message_end_files (#38706) 2026-07-25 14:04:52 +00:00
Asuka Minato
ca1782b105 test: use sqlite3 session in test_workflow_execute_task (#38704) 2026-07-25 14:04:11 +00:00
Asuka Minato
8caa1d1379 test: use sqlite3 session in test_webhook_service (#38699) 2026-07-25 13:52:42 +00:00
Evan
c56ac3983e refactor(web): migrate vector space billing query to contract client (#39558) 2026-07-25 04:26:14 +00:00
Asuka Minato
fa000ae8a7 test: use sqlite3 session in test_human_input_service (#38697) 2026-07-25 03:17:57 +00:00
Asuka Minato
8906a49e56 test: use sqlite3 session in test_datasource_provider_service (#38695) 2026-07-25 03:16:43 +00:00
Jingyi
a2d9aeff37 fix(web): prevent customization horizontal overflow (#39557) 2026-07-25 02:24:07 +00:00
yyh
aff5c47541 refactor: remove backend-only system feature fields (#39543) 2026-07-25 02:01:12 +00:00
yyh
58f83fa7e7 refactor(web): remove obsolete route prefix handler (#39545) 2026-07-24 15:30:52 +00:00
Stephen Zhou
2d5161a647 feat(dataset): add document detail (#39361)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-24 15:27:35 +00:00
yyh
1227f19c6a fix(web): patch React Server Components DoS (#39539) 2026-07-24 14:00:26 +00:00
Evan
a0b917425a test: use caplog in ext login tests (#39542) 2026-07-24 13:27:05 +00:00
Stephen Zhou
799c7eea3a feat(dataset): add document processing tasks (#39326)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-24 12:58:15 +00:00
wangxiaolei
5277e4b375 fix: fix when tool execute in progress tool_meta miss tool_provider_type (#39513) 2026-07-24 11:35:12 +00:00
zyssyz123
a877e1bd7e fix(agent): block unpublished agents in workflows (#39532)
Co-authored-by: yyh <92089059+lyzno1@users.noreply.github.com>
2026-07-24 11:02:43 +00:00
yyh
a5703762c0 test(e2e): wait for app list before menu interaction (#39538) 2026-07-24 10:37:22 +00:00
yyh
dcd40d603c fix(agent-v2): link API reference to agent guide (#39534) 2026-07-24 10:14:27 +00:00
Joel
8ef002f624 fix: include CSRF token when fetching skill file content (#39527) 2026-07-24 09:35:41 +00:00
yyh
b1dec5bd42 chore: add web shell code owners (#39526) 2026-07-24 09:17:15 +00:00
yyh
4e85acc605 fix(web): hydrate workspace permissions before navigation render (#39524) 2026-07-24 09:06:57 +00:00
Wu Tianwei
a2c67372ed fix(web): allow clipboard writes in embedded apps (#39511) 2026-07-24 08:27:57 +00:00
林玮 (Jade Lin)
7bb09ce039 chore(web): improve web accessibility semantics (#39505) 2026-07-24 08:16:04 +00:00
Joel
e1495c0bae fix: prevent agent preview actions from being clipped (#39510) 2026-07-24 08:02:55 +00:00
Jyong
ededa1f4cd chore: add deploy-knowledge.yml (#39509) 2026-07-24 08:00:11 +00:00
Joel
b2861b60d8 fix: audio config ui problem (#39504) 2026-07-24 07:42:26 +00:00
David Park
3cbe49bf45 fix: don't open the node settings panel when clicking a node in comment mode (#39500)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-24 07:38:01 +00:00
Joel
dd19b4ff79 fix: download skill files through authenticated API requests (#39499) 2026-07-24 07:37:27 +00:00
yyh
66a545fc6d refactor: centralize deployment edition in system features (#39454)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: GareArc <garethcxy@dify.ai>
2026-07-24 07:15:02 +00:00
Stephen Zhou
eac9f69ad1 feat(dataset): add crawl source selection (#39325)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-24 07:11:48 +00:00
Yufeng He
e4dc29f98e fix(api): make the 10-minute email IP first-strike window take effect (#39479)
Signed-off-by: Yufeng He <40085740+he-yufeng@users.noreply.github.com>
2026-07-24 06:52:30 +00:00
Joel
6889974c05 fix: smooth the preview-to-build transition (#39495) 2026-07-24 06:30:07 +00:00
非法操作
aef1c67721 fix: return disabled auto-upgrade settings when strategy is missing (#39494) 2026-07-24 06:15:02 +00:00
David Park
3ab9e083e0 fix: don't close the active comment panel when a different comment is resolved (#39491)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-24 06:11:25 +00:00
yyh
6e2c21f568 fix(web): simplify agent configure mode state (#39492) 2026-07-24 05:30:45 +00:00
Joel
abbad7b313 fix: prevent build reset from clearing preview chat (#39490) 2026-07-24 04:59:57 +00:00
yyh
c4bfea6096 fix(web): adapt workflow agent logs (#39488) 2026-07-24 04:55:30 +00:00
Asuka Minato
bbb133cd58 test: use sqlite3 session in test_base_trace_instance (#38744) 2026-07-24 03:55:32 +00:00
Joel
34e2205efa chore: support preview mode if not in community version (#39399)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-24 03:23:01 +00:00
wangxiaolei
db29caff2b feat: knowledge add more trace (#38959) 2026-07-24 02:27:16 +00:00
Ponder
14c50a9f09 feat(web): locate workflow nodes by node_id in the workflow editor (#38187)
Co-authored-by: Crazywoola <100913391+crazywoola@users.noreply.github.com>
2026-07-24 02:16:41 +00:00
Stephen Zhou
ba5b26be03 feat(dataset): add website crawl preview (#39324)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-24 02:10:39 +00:00
samzong
922ed4d67d feat(oauth): expose stable account id on provider account endpoint (#39470)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-24 02:09:48 +00:00
zyssyz123
a8a83a357c fix(agent): show workflow node runs in logs (#39471) 2026-07-24 01:59:57 +00:00
Stephen Zhou
302b50c4fb feat(dataset): add source connections (#39319)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-23 13:54:12 +00:00
Byron.wang
43254c1ded chore: avoid duplicate token counting during dataset indexing (#39466) 2026-07-23 10:56:03 +00:00
Joel
2beafdc457 fix: chat not pass doc if not support vision (#39461) 2026-07-23 10:01:43 +00:00
zyssyz123
0198e32447 fix(agent): start new Preview conversations without an ID (#39463) 2026-07-23 09:53:08 +00:00
samzong
b8f91d0e61 fix(web): echo OAuth state on authorize redirect (#39459)
Signed-off-by: samzong <samzong.lu@gmail.com>
2026-07-23 09:30:52 +00:00
非法操作
452dff5c37 fix(api): prevent identity logging deadlock (#39449) 2026-07-23 09:08:04 +00:00
Xiyuan Chen
b56ac4af4d feat: gate agent management behind the agent.manage permission (#39330)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: yyh <yuanyouhuilyz@gmail.com>
Co-authored-by: yyh <92089059+lyzno1@users.noreply.github.com>
2026-07-23 07:34:07 +00:00
Stephen Zhou
2a0661a769 feat(dataset): add New Knowledge creation flow (#39315)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-23 07:25:14 +00:00
eux
00fe96325d fix(web): support TTS playback in Safari and Firefox (#39444)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-23 06:36:52 +00:00
非法操作
a3c18c561e chore: improve lambda plugin runtime error display (#39437) 2026-07-23 06:05:14 +00:00
shakti
1835e8ef31 fix: use re.fullmatch in email validator to reject trailing newlines (#39234) (#39320)
Co-authored-by: Asuka Minato <i@asukaminato.eu.org>
2026-07-23 04:19:44 +00:00
zyssyz123
2b8e40af32 fix(auth): validate account before accepting invitations (#39438)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-23 03:56:32 +00:00
yyh
625ed2a0e7 fix(workflow): hide Agent V2 in chatflow (#39439) 2026-07-23 03:37:13 +00:00
林玮 (Jade Lin)
45711eb6dd chore(api): cloud use presigned download url on api site (#39436)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-23 03:34:49 +00:00
Asuka Minato
fd703739b5 test: use sqlite3 session in test_async_workflow_service (#38692) 2026-07-23 03:34:10 +00:00
Asuka Minato
82c8741c73 test: use sqlite3 session in test_hitl_service_api (#38685) 2026-07-23 03:33:01 +00:00
Asuka Minato
78023bf50d test: use sqlite3 session in test_conversation (#38684) 2026-07-23 03:32:17 +00:00
Asuka Minato
0ad985515b test: move password reset coverage to unit tests (#38936)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-23 03:16:06 +00:00
David Park
da2177c7b2 fix(api): send valid body in external knowledge validation probe (#39410) 2026-07-23 02:52:52 +00:00
Coding On Star
8d293023cc feat: gate cloud analytics behind cookie consent (#39408)
Co-authored-by: CodingOnStar <hanxujiang@dify.com>
2026-07-23 02:40:54 +00:00
yyh
6736f4005b fix(web): improve import DSL dialog states (#39432)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-23 02:26:59 +00:00
Stephen Zhou
bd8f0104d6 feat(dataset): expose New RAG KnowledgeFS contracts (#39314)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-23 01:48:36 +00:00
yyh
018fe7a9d3 fix(dify-ui): preserve link semantics in button story (#39430) 2026-07-23 01:07:08 +00:00
非法操作
d5788cc019 feat: support tool multi-select input (#39346)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: WH-2099 <wh2099@pm.me>
2026-07-23 00:38:54 +00:00
zyssyz123
4da4fa72cd fix(agent): refresh stale inline preview drafts (#39415) 2026-07-22 12:54:09 +00:00
平衡世界的BOY
8853ed99a5 fix: prevent RBAC role names overflowing settings panel (#39412)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-22 12:44:29 +00:00
Stephen Zhou
34a5ca191b feat(dataset): add New Knowledge list and empty state (#39300)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-22 12:00:50 +00:00
Asuka Minato
1271cfcf3f test: use sqlite3 session in test_workflow_events_openapi (#38683) 2026-07-22 11:25:14 +00:00
Asuka Minato
2a0b1a8a63 test: use sqlite3 session in test_runtime_credentials (#38682) 2026-07-22 09:50:31 +00:00
Asuka Minato
4a2e92f43f test: use sqlite3 session in test_plugin_wraps (#38681) 2026-07-22 09:49:54 +00:00
Asuka Minato
84889b88ec test: use sqlite3 session in test_init_validate (#38680) 2026-07-22 09:44:29 +00:00
Asuka Minato
6f034d2c93 test: use sqlite3 session in test_tags (#38679) 2026-07-22 09:43:41 +00:00
Asuka Minato
f91ea49414 test: use sqlite3 session in test_app_import_api (#38674)
Co-authored-by: Byron Wang <byron@dify.ai>
2026-07-22 09:43:30 +00:00
yyh
62db37c403 fix(web): improve DSL export feedback (#39409)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-22 09:40:47 +00:00
Asuka Minato
de07730548 test: use sqlite3 session in test_snippet_workflow_draft_variable (#38678) 2026-07-22 09:20:51 +00:00
Asuka Minato
9b2aa8b216 test: use sqlite3 session in test_snippet_workflow (#38677) 2026-07-22 09:20:21 +00:00
Asuka Minato
8ee3a7eabc test: use sqlite3 session in test_rag_pipeline_workflow (#38676) 2026-07-22 09:19:25 +00:00
zyssyz123
0f9fffb7a2 fix(agent): isolate build and preview chat conversations (#39405)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-22 09:17:55 +00:00
Asuka Minato
187501f53e test: use sqlite3 session in test_reset_encrypt_key_pair (#38673) 2026-07-22 09:17:34 +00:00
Wu Tianwei
03fad2e041 chore: Update permission tip across i18n locales (#39406) 2026-07-22 08:54:37 +00:00
yyh
acb5ee29e1 test(e2e): validate generated console contracts (#39400)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-22 07:48:37 +00:00
林玮 (Jade Lin)
c5aadfe557 fix(api,billing): invalidate vector space cache after cleanup (#39404) 2026-07-22 07:30:16 +00:00
Asuka Minato
c76ff4c38c test: use sqlite3 session in test_base_app_runner (#38740)
Co-authored-by: Byron.wang <byron@dify.ai>
2026-07-22 07:21:22 +00:00
yyh
4b355b7039 fix(ci): avoid duplicate post-merge e2e runs (#39401) 2026-07-22 06:45:18 +00:00
林玮 (Jade Lin)
a3654d6a7d fix(oauth): reauth after accepting invitation (#39366) 2026-07-22 05:59:04 +00:00
yyh
855464e7b4 chore: clean up CODEOWNERS (#39398) 2026-07-22 05:34:54 +00:00
yyh
05a25943e7 fix(e2e): align fixtures with generated contracts (#39394)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-22 05:09:23 +00:00
Asuka Minato
c5d471dbdd test: use sqlite3 session in test_model_config_api (#38675) 2026-07-22 04:53:13 +00:00
Asuka Minato
ba449890a9 test: use sqlite3 session in test_app_runner_conversation_variables (#38687) 2026-07-22 04:53:00 +00:00
Asuka Minato
072953a83a test: use sqlite3 session in test_export_service (#38718) 2026-07-22 04:52:19 +00:00
Asuka Minato
7b95e2a75f test: use sqlite3 session in test_generator_api_missing (#38719) 2026-07-22 04:52:06 +00:00
Asuka Minato
01efc6eecb test: use SQLite sessions in service API fixtures (#38784)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-22 04:51:49 +00:00
Asuka Minato
a4c7261bf9 test: use sqlite3 session in test_workflow (#38686) 2026-07-22 04:51:33 +00:00
dependabot[bot]
0aa04f610e chore: bump pillow from 12.2.0 to 12.3.0 in /dify-agent (#39328)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-22 04:23:00 +00:00
Asuka Minato
66afa3bf4a test: use sqlite3 session in test_clear_free_plan_tenant_expired_logs (#38693) 2026-07-22 04:16:21 +00:00
dependabot[bot]
c0b991c5f9 chore: bump google.golang.org/grpc from 1.82.0 to 1.82.1 in /dify-agent-runtime (#39386)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-22 04:06:51 +00:00
dependabot[bot]
d2aea76dec chore: bump setuptools from 82.0.1 to 83.0.0 in /dify-agent (#39387)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-22 04:06:30 +00:00
dependabot[bot]
bc21972878 chore: bump pyasn1 from 0.6.3 to 0.6.4 in /dify-agent (#39388)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-22 04:06:08 +00:00
dependabot[bot]
389a7608bf chore: bump gitpython from 3.1.50 to 3.1.52 in /api (#39389)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-22 04:05:53 +00:00
dependabot[bot]
3abbab4798 chore: bump pyasn1 from 0.6.3 to 0.6.4 in /api (#39390)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-22 04:05:40 +00:00
Wu Tianwei
84f3c410c4 fix(datasets): update empty state handling and permissions messaging (#39360) 2026-07-22 03:57:35 +00:00
yyh
04f9026724 fix(web): show unavailable state for disabled Web Apps (#39392)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-22 03:32:40 +00:00
Xiyuan Chen
3f0f57c594 fix: apply configured timeout to enterprise inner API requests (#39335) 2026-07-22 02:56:08 +00:00
Asuka Minato
79a5b31bc6 test: move console OAuth coverage to unit tests (#38923) 2026-07-22 02:27:55 +00:00
Asuka Minato
f35655a5bb test: use sqlite3 session in test_human_input_forms (#38777) 2026-07-22 02:27:30 +00:00
zcxGGmu
97489d5a44 docs: note minimum Docker Compose version (#39374)
Co-authored-by: zq <zhouquan1511@163.com>
2026-07-22 02:27:30 +00:00
Asuka Minato
e9bd8741f4 test: use sqlite3 session in test_auth_wraps (#38760) 2026-07-22 02:23:37 +00:00
Asuka Minato
33acaa558e test: use SQLite sessions in core workflow (#39109) 2026-07-22 02:18:56 +00:00
Asuka Minato
b38caf3cdb test: use SQLite sessions in services core (#39111) 2026-07-22 02:15:01 +00:00
Asuka Minato
cb2b36f1aa test: use SQLite sessions in services enterprise (#39113) 2026-07-22 02:13:52 +00:00
Asuka Minato
2d15743b96 test: use SQLite sessions in services misc (#39114) 2026-07-22 02:11:52 +00:00
yyh
d5e5227c6e chore(deps): upgrade Next.js to 16.2.11 (#39384) 2026-07-22 02:04:05 +00:00
yyh
9b432d0d29 fix: enforce tool provider type contracts (#39380)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-22 01:30:55 +00:00
Wu Tianwei
5216ee1d20 feat: add WebSocket support to dev proxy with cookie rewriting (#39370) 2026-07-22 01:14:27 +00:00
Loi Nguyen
ba8ce362d7 fix(api): PaginatedResult.pages should be 0 for an empty result set (#39229)
Co-authored-by: Loi Nguyen <1948922+lntutor@users.noreply.github.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-22 01:11:14 +00:00
yyh
b95d313128 refactor(web): improve workflow block selector (#39377) 2026-07-21 14:18:38 +00:00
github-actions[bot]
45ac70132c chore(i18n): sync translations with en-US (#39362)
Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Co-authored-by: yyh <92089059+lyzno1@users.noreply.github.com>
2026-07-21 11:54:20 +00:00
Joel
6e772259bb fix: update the agent roster documentation link (#39368) 2026-07-21 09:56:21 +00:00
QuantumGhost
af465fb527 fix(api): scope HITL snapshot message lookup to utilize db index (#39351) 2026-07-21 09:47:17 +00:00
Xiyuan Chen
62bbc0dbeb feat(webapp-access): add WEBAPP_PUBLIC_ACCESS_ENABLED toggle (#38567)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-21 08:46:28 +00:00
zyssyz123
ed1289281d fix(agent): include workflow runs in monitoring stats (#39354) 2026-07-21 08:33:23 +00:00
Asuka Minato
e37f32e4a0 test: add SQLite session fixture for providers (#38982) 2026-07-21 08:29:44 +00:00
Asuka Minato
150613cc05 test: use sqlite3 session in test_build_from_mapping (#38769) 2026-07-21 08:21:36 +00:00
Asuka Minato
a5194ff17b test: move human input delivery coverage to unit tests (#38926)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-21 08:18:32 +00:00
Asuka Minato
cdaf5d4562 test: use sqlite3 session in test_tool_file_manager (#38771) 2026-07-21 08:10:23 +00:00
Asuka Minato
145b0e622e test: use sqlite3 session in test_workspace_account (#38757) 2026-07-21 08:07:57 +00:00
Asuka Minato
4bab62d458 test: use sqlite3 session in test_agent_app_parameters (#38759) 2026-07-21 07:59:00 +00:00
Asuka Minato
b99f8941bb test: use sqlite3 session in test_database_retrieval (#38743) 2026-07-21 07:56:34 +00:00
Asuka Minato
32d2594877 test: move app import API coverage to unit tests (#38920) 2026-07-21 07:54:32 +00:00
Asuka Minato
7b188287da test: use sqlite3 session in test_accounts (#38752) 2026-07-21 07:50:05 +00:00
Asuka Minato
f6db23444d test: move API token service coverage to unit tests (#38918) 2026-07-21 07:48:10 +00:00
Asuka Minato
a5c989d82b test: use sqlite3 session in test_conversation_service (#38774)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-21 07:38:53 +00:00
Asuka Minato
2622b1ce0a test: use sqlite3 session in test_based_generate_task_pipeline (#38738)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-21 07:37:20 +00:00
Asuka Minato
1e672530c4 test: use sqlite3 session in test_built_in_retrieval (#38735) 2026-07-21 07:36:42 +00:00
Asuka Minato
852169d99c test: use SQLite sessions in unit misc (#39118) 2026-07-21 07:27:13 +00:00
Asuka Minato
d7860571aa test: use SQLite sessions in services workflow (#39115) 2026-07-21 07:24:52 +00:00
Asuka Minato
3683831738 test: use sqlite3 session in test_account_service (#38751) 2026-07-21 07:22:05 +00:00
非法操作
f5024f5440 fix(workflow): avoid false draft save error during Strict Mode initia… (#39353) 2026-07-21 07:11:19 +00:00
Joel
4f8477427e fix: not support jump to detail in marketplace (#39347)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-21 07:01:00 +00:00
非法操作
8d406aec31 fix(dev): use gevent WebSocket server for local API (#39349) 2026-07-21 06:42:55 +00:00
落尘
f8754286ec fix(watercrawl): handle non-json error responses (#37514) 2026-07-21 06:41:06 +00:00
yyh
7da6b2ce36 refactor(web): remove permission catalog service hooks (#39342) 2026-07-21 06:01:00 +00:00
Harsh Kashyap
aa718add24 fix(api): return 400 instead of 500 when 'file' is missing from trial-app audio-to-text (#39305)
Co-authored-by: Harsh Kashyap <Harsh23Kashyap@users.noreply.github.com>
2026-07-21 05:59:48 +00:00
yyh
fcc1d39f5e fix(web): restore billing access boundary (#39343) 2026-07-21 05:35:36 +00:00
yyh
861831f176 fix(api): keep workflow log archives owner-admin only (#39338) 2026-07-21 04:31:14 +00:00
Asuka Minato
d333aa31ea test: use SQLite sessions in services workflow (#39116)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-21 03:40:02 +00:00
Asuka Minato
97e6a14c13 test: use SQLite sessions in unit misc (#39119)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-21 03:20:59 +00:00
shakti
6a338654fb fix: return 400 instead of 500 when file field is missing in audio-to-text endpoints (#39303) (#39322) 2026-07-21 02:19:24 +00:00
Checo
8f075c82bc fix(configs): reject host:port-shaped PLUGIN_REMOTE_INSTALL_PORT with actionable hint (#39329)
Signed-off-by: sergioperezcheco <checo520@outlook.com>
2026-07-21 02:18:29 +00:00
林玮 (Jade Lin)
28d17da3b1 fix(api): use resource tenant for draft variable files (#39307) 2026-07-21 02:07:47 +00:00
Asuka Minato
891b2dc537 test: use SQLite sessions in unit misc (#39120)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-21 01:51:24 +00:00
WH-2099
75f7069541 ci: simplify test workflow execution (#39318) 2026-07-21 00:18:59 +00:00
yyh
b7193d1cba refactor(web): remove basePath from hydration boundary (#39308) 2026-07-20 14:46:37 +00:00
wangxiaolei
ef0115d340 chore: when dataset permission is not all team, update rbac config to… (#39227)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-20 12:59:29 +00:00
Checo
3afb9b3230 fix(web): stop doubling basePath in auth refresh redirects (#39273)
Co-authored-by: yyh <yuanyouhuilyz@gmail.com>
2026-07-20 12:22:40 +00:00
Joel
0862641533 feat: support export agent dsl in sidebar (#39299) 2026-07-20 10:41:26 +00:00
Asuka Minato
cbd7872520 test: use SQLite sessions in unit misc (#39121)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-20 10:38:52 +00:00
Asuka Minato
23882a704e test: use SQLite sessions in unit misc (#39122)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-20 10:38:49 +00:00
Asuka Minato
1bd5254ea7 test: use SQLite sessions in unit misc (#39123)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-20 10:38:46 +00:00
yyh
e13069dbe3 revert(ci): restore default Depot runners (#39297) 2026-07-20 10:18:52 +00:00
github-actions[bot]
edd3d4a218 chore(i18n): sync translations with en-US (#39296)
Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Co-authored-by: yyh <92089059+lyzno1@users.noreply.github.com>
2026-07-20 10:15:37 +00:00
Joel
79751f7622 chore: display non-LLM settings in integration tool details (#39295) 2026-07-20 09:52:54 +00:00
Jingyi
cb64446fa3 feat(web): add step-by-step tour shell (#38785)
Co-authored-by: hjlarry <hjlarry@163.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: yyh <yuanyouhuilyz@gmail.com>
Co-authored-by: yyh <92089059+lyzno1@users.noreply.github.com>
2026-07-20 09:23:25 +00:00
Joel
e77ee82526 fix: show persistent error when workflow draft save fails (#39293) 2026-07-20 08:48:38 +00:00
yyh
b3f163fb0f chore(deps): update pnpm and workspace dependencies (#39292) 2026-07-20 08:43:21 +00:00
yyh
873ef2b592 docs: refine frontend testing guidance (#39290) 2026-07-20 08:18:26 +00:00
Stephen Zhou
43d725a1ce feat(dataset): proxy KnowledgeFS Console requests (#39158)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-20 08:10:06 +00:00
Joel
c8ccfba960 fix: the input of agent chat would be replaced if conversation history updated (#39289) 2026-07-20 08:07:12 +00:00
Xiyuan Chen
eee8d6cf7b feat(web): add webapp access control to agent access point (#39285)
Co-authored-by: yyh <yuanyouhuilyz@gmail.com>
2026-07-20 08:05:29 +00:00
zyssyz123
11016563b1 fix(agent): preserve complete model usage pricing (#39201) 2026-07-20 08:03:13 +00:00
Ingram Z
b7edc5ef0c refactor: use catalog for workflow archive maintenance (#39001) 2026-07-20 07:59:29 +00:00
林玮 (Jade Lin)
f93a5b95c6 fix(api, web): scope trial app file uploads to the app tenant (#39149)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-20 07:00:45 +00:00
Kevin9703
6022939bf0 fix: prevent hidden-tab collaboration leader from saving stale drafts (#38997)
Co-authored-by: hjlarry <hjlarry@163.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: yyh <yuanyouhuilyz@gmail.com>
Co-authored-by: yyh <92089059+lyzno1@users.noreply.github.com>
2026-07-20 06:58:01 +00:00
非法操作
30df1433cc fix: can't create chat app when get tenant default model schema error (#39266) 2026-07-20 06:47:16 +00:00
dependabot[bot]
aa7b65c602 chore: bump the github-actions-dependencies group with 5 updates (#39247)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-20 06:47:01 +00:00
yyh
ba24745c07 fix(web): restore permission selector semantics (#39269)
Signed-off-by: yyh <yuanyouhuilyz@gmail.com>
2026-07-20 06:30:09 +00:00
pepepeboom
38ea0de907 refactor(web): avoid direct setState in effect in jina reader crawler (#25194) (#39216)
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: Wu Tianwei <30284043+WTW0313@users.noreply.github.com>
2026-07-20 06:28:08 +00:00
Joel
bbc31a3403 fix: text generation web app keeps loading after timeout (#39268) 2026-07-20 06:27:32 +00:00
Wan Xiankai
605c0fe02b refactor(web): avoid setState in website crawler effects (#39237)
Co-authored-by: Wu Tianwei <30284043+WTW0313@users.noreply.github.com>
2026-07-20 06:26:50 +00:00
yyh
15674a9db6 test(web): align test state boundaries (#39239) 2026-07-20 06:06:17 +00:00
非法操作
9a2d039e93 chore: the node should not draggable when preview a workflow (#39131)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-20 05:59:14 +00:00
yyh
58d1dd8873 ci: route default Depot jobs to 4-core runners (#39277) 2026-07-20 05:42:56 +00:00
Checo
5ea884f799 fix(dataset_service): use flush() instead of commit() to preserve caller transaction (#39223) 2026-07-19 07:00:50 +00:00
yyh
2ec34b2cfb feat(workflow): improve block selector navigation and previews (#39212)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-18 09:56:36 +00:00
yyh
fa65f45bff refactor(web): align integrations sidebar components (#39202)
Co-authored-by: Jingyi <jingyi.qi@dify.ai>
2026-07-17 22:52:47 +00:00
yyh
63ca2b94b5 refactor(web): use generated OAuth query options (#39204)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-17 14:50:56 +00:00
yyh
a7ef41a8f5 refactor(web): use generated dataset card queries (#39203) 2026-07-17 14:50:40 +00:00
Yunlu Wen
5c6372d2f7 chore: bump version to 1.16.0 (#39196) 2026-07-17 09:28:32 +00:00
yyh
5fd06fafe0 test(web): remove low-value unit tests (#39193) 2026-07-17 08:59:26 +00:00
zyssyz123
af4b65b295 fix(agent): allow dangling refs in workflow drafts (#39192) 2026-07-17 08:42:58 +00:00
Yunlu Wen
6e5fc1081b feat: refact agent shell output (#39190)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-17 08:27:00 +00:00
Joel
0e84ae7338 fix: can not typing in the change node search field (#39189) 2026-07-17 08:01:46 +00:00
zyssyz123
5a792945f5 fix(agent): bound streams and cancel zombie workflow runs (#39186) 2026-07-17 07:46:42 +00:00
Wu Tianwei
2f3c785f27 feat: add Responses API tip for GPT-5.6 and later models in multiple languages (#39188)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-17 07:34:38 +00:00
Joel
38045078dc fix: can not create app from learn dify in app list page (#39187) 2026-07-17 07:20:31 +00:00
sahasweety
83f40b85f4 fix: remove patch logger in test, use caplog instead (Closes #37468) (#39159)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-17 06:22:20 +00:00
非法操作
aff8a49bbf fix: change email not work (#39182) 2026-07-17 06:05:20 +00:00
Joel
b0329cd53c chore: add agent tooltip (#39183) 2026-07-17 06:00:29 +00:00
yyh
2a008423d8 chore: upgrade Vite+ to 0.2.5 (#39181) 2026-07-17 05:39:02 +00:00
yyh
f962c9e47a fix(web): settle running nodes after workflow failure (#39173) 2026-07-17 05:15:01 +00:00
yyh
af7e59de7c fix(web): show current profile in main navigation (#39172) 2026-07-17 04:11:35 +00:00
非法操作
61b07ab17d feat: default plugins for new user (#39167) 2026-07-17 02:49:58 +00:00
Joel
a7aff83d52 chore: remove useless agent tip (#39171) 2026-07-17 02:47:57 +00:00
Crazywoola
9de7e0fe44 perf(workflow-generator): parallelize node config generation (#38975)
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-17 02:34:15 +00:00
Jingyi
50341357b3 fix(web): unify workspace avatar usage (#39160) 2026-07-17 01:35:03 +00:00
Yunlu Wen
96e34e7b24 fix: clean up env in example (#39044)
Co-authored-by: -LAN- <laipz8200@outlook.com>
2026-07-16 16:51:04 +00:00
Asuka Minato
1aea3460af test: use sqlite3 session in test_customized_retrieval (#38741)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-16 14:09:40 +00:00
yyh
48e536ba39 test(e2e): enforce behavior-driven quality gates (#39148) 2026-07-16 13:42:10 +00:00
Asuka Minato
33fe0dfd60 test: use sqlite3 session in test_human_input_form (#38780)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-16 13:17:50 +00:00
Asuka Minato
a8ffc93a5a test: move plugin parameter service coverage to unit tests (#38934) 2026-07-16 13:06:04 +00:00
Asuka Minato
14ac8dfbf6 test: use sqlite3 session in test_passport (#38763) 2026-07-16 12:59:52 +00:00
Asuka Minato
b820ccf086 test: use sqlite3 session in test_tool_label_manager (#38762) 2026-07-16 12:56:08 +00:00
Asuka Minato
415c0db22e test: use sqlite3 session in test_tool_providers (#38754) 2026-07-16 12:28:26 +00:00
Asuka Minato
6ad1a66a50 test: use sqlite3 session in test_remote_retrieval (#38737) 2026-07-16 10:56:00 +00:00
Asuka Minato
2f2d7c26d4 test: use sqlite3 session in test_api (#38736) 2026-07-16 10:38:33 +00:00
Joel
18f4640ad1 chore: remove empty advanced setting (#39147) 2026-07-16 10:24:23 +00:00
Joel
f4ad6ce978 chore: show package installed status in marketplace page (#39146) 2026-07-16 10:18:30 +00:00
Asuka Minato
e9c0e9de9e test: use SQLite sessions in tasks (#39117)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-16 10:17:26 +00:00
Yunlu Wen
8a33161080 fix: downgrade to landlock v1 (#39139) 2026-07-16 10:04:01 +00:00
KeiKurosawa
752af8a270 fix(readme): remove trailing whitespace (#39143) 2026-07-16 09:48:55 +00:00
林玮 (Jade Lin)
678ce2ab37 refactor(api): pass tenant_id explicitly to workflow repositories (#39042) 2026-07-16 09:36:30 +00:00
Asuka Minato
b737833e2a test: use SQLite sessions in services core (#39112)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-16 09:32:11 +00:00
Asuka Minato
872b6906f2 test: use SQLite sessions in core workflow (#39110)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-16 09:18:55 +00:00
Joel
d876f6dba5 fix: validate inline agent files and skills in the workflow checklist (#39137) 2026-07-16 08:39:20 +00:00
zyssyz123
cd98193234 fix(agent): import workflow agents as inline (#39135) 2026-07-16 08:28:34 +00:00
github-actions[bot]
bfffcb7d0f chore(i18n): sync translations with en-US (#39134)
Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
2026-07-16 08:13:37 +00:00
yyh
d66de8a47b test(e2e): harden behavior coverage and CI gates (#39043)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-16 07:32:11 +00:00
Joel
1a2ba2237d chore: new agent enchance (#39040)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-16 06:46:41 +00:00
yyh
8ff92c9ef8 fix(ci): run CLI checks for contract changes (#39047) 2026-07-16 04:56:18 +00:00
Yunlu Wen
511dbb9974 fix(agent): add new envs to .env.example (#39041) 2026-07-16 03:31:16 +00:00
zyssyz123
4381ec8fee fix(agent): accept legacy missing asset placeholders (#39039)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-16 03:11:08 +00:00
林玮 (Jade Lin)
cb41fb3e76 fix(api): serialize trial workflow conversation variables (#39038)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-16 02:57:06 +00:00
wangxiaolei
7dfd84472f fix: fix miss create rbac binding (#39023) 2026-07-16 02:25:42 +00:00
非法操作
62bdbc8628 fix(web): hide broken table actions in Streamdown fullscreen (#38894) 2026-07-16 01:58:31 +00:00
非法操作
85cc183501 feat: improve ai-credits display (#38589)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-16 01:51:46 +00:00
yyh
5af8f6af4d test(dify-ui): focus component tests on behavior (#39030) 2026-07-16 01:49:03 +00:00
yyh
abb9972e19 test: simplify dify ui browser test setup (#39028) 2026-07-15 15:37:28 +00:00
zyssyz123
79662d49af fix(agent): aggregate monitor sources by workflow app (#39021)
Co-authored-by: yyh <92089059+lyzno1@users.noreply.github.com>
2026-07-15 14:08:57 +00:00
yyh
4571c4f276 test: align dify ui tests with browser mode (#39024) 2026-07-15 14:00:29 +00:00
yyh
fe96bea1f0 fix(e2e): follow agent roster create menu (#39020) 2026-07-15 12:39:51 +00:00
zyssyz123
73c3048599 fix(agent): preserve DSL asset placeholders and count draft references (#39015)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-15 11:49:11 +00:00
WH-2099
dcbedbd3bc docs: update Star History chart token (#39019) 2026-07-15 11:11:55 +00:00
Yunlu Wen
71709f03c3 feat: protect agent HOME with landlock (#39000)
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-07-15 10:07:24 +00:00
Joel
9e6a2cd19c feat: new agent support import and export in frontend (#39012) 2026-07-15 09:54:09 +00:00
yyh
dfabe4cb28 refactor(dify-ui): clarify overlay style semantics (#39016) 2026-07-15 09:53:59 +00:00
Wu Tianwei
1121a17c11 fix: allow workflow comments for layout users (#39014) 2026-07-15 09:53:45 +00:00
Coding On Star
e5b7281eb9 fix(auth): keep login redirects on current deployment (#39013)
Co-authored-by: CodingOnStar <hanxujiang@dify.com>
2026-07-15 09:48:58 +00:00
WH-2099
6a511da325 fix(api): bind scoped lookups to nested owner refs (#38470) 2026-07-15 09:31:09 +00:00
yyh
b721e7a32d fix(web): align agent activity disclosure (#38999) 2026-07-15 08:51:21 +00:00
zyssyz123
71d5c35e8f fix(agent): preserve Unicode separators in SSE streams (#39008) 2026-07-15 08:38:08 +00:00
wangxiaolei
d914ece3fb fix: fix conversation title is overwrite empty (#39004)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-15 08:24:11 +00:00
Xin Zhang
120c38bad8 feat(enterprise): reject member invites that would exceed licensed seats (#38995) 2026-07-15 07:59:16 +00:00
Wu Tianwei
10da5e8f9d fix: restore responding state after HITL resume (#38992) 2026-07-15 06:59:25 +00:00
Byron.wang
ab3e4daa95 refactor: explicit DB session propagation across backend paths (#38559)
Co-authored-by: WH-2099 <wh2099@pm.me>
2026-07-15 06:48:28 +00:00
github-actions[bot]
7d5835fbc0 chore(i18n): sync translations with en-US (#38979)
Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Co-authored-by: yyh <92089059+lyzno1@users.noreply.github.com>
2026-07-15 06:24:11 +00:00
wangxiaolei
2c1313d13a feat: redis support keepalive and retry more error (#38973)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-15 06:20:19 +00:00
Xiyuan Chen
651111fb0d chore(deps): bump httplib2, setuptools, wandb for CVE fixes (#38976) 2026-07-15 06:12:38 +00:00
林玮 (Jade Lin)
edca982b1e fix(api): harden trial apps access for recommended apps (#38970) 2026-07-15 06:04:07 +00:00
wangxiaolei
b3386192cc chore: workflow comment remove rbac check (#38978) 2026-07-15 06:01:38 +00:00
Blackoutta
7dc3126ff4 fix: preserve and display workflow retry details (#38854)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-15 05:58:37 +00:00
yyh
7dd33929c7 fix(agent-v2): use default select composition for time range picker (#38977) 2026-07-15 05:47:22 +00:00
Asuka Minato
c17a0f4e18 test: move feedback service coverage to unit tests (#38927)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-15 05:42:12 +00:00
Asuka Minato
15acaf1fa6 test: use sqlite3 session in test_provider_configuration (#38689) 2026-07-15 04:54:49 +00:00
Asuka Minato
3afd81a028 test: move MCP controller coverage to unit tests (#38930)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-15 04:40:34 +00:00
Asuka Minato
fbd6e04810 test: move console app API coverage to unit tests (#38915)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-15 04:40:15 +00:00
yyh
e05eb7d7bf fix(e2e): probe shellctl health in preflight (#38971) 2026-07-15 04:15:16 +00:00
Asuka Minato
c277f48084 test: move email registration coverage to unit tests (#38928)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-15 04:05:59 +00:00
Asuka Minato
70462d96bd test: move RAG pipeline controller coverage to unit tests (#38939)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-15 03:59:57 +00:00
Asuka Minato
22429d275a test: move console forgot-password coverage to unit tests (#38922) 2026-07-15 03:56:41 +00:00
Asuka Minato
0c15a71cc4 test: move API key authentication coverage to unit tests (#38919)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-15 03:52:20 +00:00
Asuka Minato
557d92735d test: move account deletion sync coverage to unit tests (#38917)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-15 03:47:55 +00:00
Asuka Minato
65e676b880 test: move recommendation database retrieval coverage to unit tests (#38921) 2026-07-15 03:44:36 +00:00
Asuka Minato
c77c06c1e9 test: move hit testing service coverage to unit tests (#38925) 2026-07-15 03:37:16 +00:00
yyh
1e6d73fdb5 fix(e2e): restore shellctl external runtime (#38968) 2026-07-15 03:26:55 +00:00
Asuka Minato
571e50175e test: move RAG pipeline dataset coverage to unit tests (#38933) 2026-07-15 03:26:34 +00:00
Asuka Minato
a4b64d1fd7 test: move tool provider controller coverage to unit tests (#38944)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-15 03:12:43 +00:00
Asuka Minato
02bf198d41 test: remove unit-only authentication integration cases (#38948) 2026-07-15 03:08:56 +00:00
Asuka Minato
bf2654eff6 test: remove duplicate code executor integration coverage (#38947) 2026-07-15 03:03:30 +00:00
Jingyi
0f0fb1ca3d fix(web): gate console atom consumers on bootstrap (#38962)
Co-authored-by: yyh <yuanyouhuilyz@gmail.com>
2026-07-15 03:01:56 +00:00
Asuka Minato
7d20b8cc1b test: use sqlite3 session in test_audio_service (#38768)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-15 03:01:34 +00:00
Asuka Minato
d1d2cfbdba test: move plugin service coverage to unit tests (#38935)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-15 02:32:23 +00:00
yyh
e134c947c1 refactor(web): standardize hotkey ownership and typing (#38960) 2026-07-15 02:22:40 +00:00
zyssyz123
f86bfb2a31 feat(agent): support new Agent DSL import and export (#38849)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-15 02:02:14 +00:00
非法操作
38aec8b506 chore: chatflow api should check workflow_id and sandbox plan (#38892) 2026-07-15 02:01:53 +00:00
Yunlu Wen
302d7b1e1b feat(agent): shellctl rewritten in go (#38841)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-15 01:58:36 +00:00
Asuka Minato
40df83de66 test: move trigger provider coverage to unit tests (#38942) 2026-07-14 14:56:22 +00:00
Asuka Minato
141257aefb test: move web forgot-password coverage to unit tests (#38943) 2026-07-14 14:09:28 +00:00
Asuka Minato
3adf279422 test: move recommended app service coverage to unit tests (#38940) 2026-07-14 13:55:06 +00:00
yyh
e2fccb604a refactor(web): rebuild goto anything dialog (#38914) 2026-07-14 10:38:45 +00:00
wangxiaolei
c278148c8f feat: when knowledge permission is all team need update rbac setttings (#38911)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-14 09:07:33 +00:00
Snakinya
ae0d6ee214 fix: SSRF bypass via raw httpx.get in API tool schema fetch (#37746)
Co-authored-by: 归青 <guiqing.lzw@antgroup.com>
Co-authored-by: QuantumGhost <obelisk.reg+git@gmail.com>
2026-07-14 08:43:57 +00:00
非法操作
f09d2b191f feat: archive logs export (#38207)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-14 08:25:37 +00:00
林玮 (Jade Lin)
82ff93cbdd feat(oauth): preserve redirect_url through OAuth state for post-login… (#38900)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-14 08:23:39 +00:00
wangxiaolei
f71a30bebf feat: allow user specific home dir (#38903) 2026-07-14 08:07:47 +00:00
Coding On Star
2c4d8ef098 fix(auth): preserve redirect URL across auth flows (#38905)
Co-authored-by: CodingOnStar <hanxujiang@dify.com>
2026-07-14 07:47:34 +00:00
yyh
35ace0ea18 docs: simplify frontend testing guidance (#38909) 2026-07-14 07:45:08 +00:00
Asuka Minato
995de4994d test: use sqlite3 session in test_workspaces_members (#38775) 2026-07-14 07:15:11 +00:00
Asuka Minato
e21071cbb8 test: use sqlite3 session in test_remote_fetcher (#38773) 2026-07-14 07:01:23 +00:00
yyh
81c3aa2d7e fix(web): improve explore banner responsiveness (#38899) 2026-07-14 06:52:58 +00:00
Xin Zhang
28a036066a feat(enterprise): enforce licensed seats cap at account creation (#38883)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-14 06:51:19 +00:00
Asuka Minato
713c577b51 test: use sqlite3 session in test_dataset_service_lock_not_owned (#38755) 2026-07-14 06:40:31 +00:00
Asuka Minato
c12d4662db test: use sqlite3 session in test_file_tenant_validator (#38756) 2026-07-14 06:39:33 +00:00
Asuka Minato
7da854555e test: use sqlite3 session in test_file_factory (#38758) 2026-07-14 06:37:25 +00:00
yyh
67cce8eb86 fix(web): align workspace card hover state (#38898) 2026-07-14 06:16:13 +00:00
yyh
46ad6ef6f6 fix(e2e): harden failure lifecycle diagnostics (#38896) 2026-07-14 06:15:57 +00:00
Yunlu Wen
fbda0a67cd fix(deps): upgrade fickling, pillow, click (#38893) 2026-07-14 05:43:01 +00:00
dependabot[bot]
94f7ed4a73 chore(deps): bump transformers from 5.3.0 to 5.5.0 in /api (#38877)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-14 04:10:40 +00:00
dependabot[bot]
0277f87bd2 chore(deps): bump json-repair from 0.59.4 to 0.60.1 in /dify-agent (#38878)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-14 04:10:17 +00:00
dependabot[bot]
47073bf1dc chore(deps): bump json-repair from 0.59.4 to 0.60.1 in /api (#38879)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-14 04:10:01 +00:00
Asuka Minato
1d0e198262 test: use sqlite3 session in test_agent_drive_service (#38709) 2026-07-14 04:06:43 +00:00
Asuka Minato
36e978b8b9 test: use sqlite3 session in test_credential_permission_service (#38711) 2026-07-14 03:58:34 +00:00
Asuka Minato
8d0cf0e38b test: use sqlite3 session in test_skill_standardize_service (#38712) 2026-07-14 03:57:17 +00:00
Asuka Minato
82b2ed3185 test: use sqlite3 session in test_audio (#38713) 2026-07-14 03:55:05 +00:00
Asuka Minato
6fa71ef7ab test: use sqlite3 session in test_annotation_reply (#38714) 2026-07-14 03:52:52 +00:00
Asuka Minato
e044292518 test: use sqlite3 session in test_app_dsl_service (#38715) 2026-07-14 03:51:04 +00:00
Asuka Minato
747773d4b6 test: use sqlite3 session in test_data_migration_wizard (#38708) 2026-07-14 03:44:52 +00:00
Asuka Minato
99d23135de test: use sqlite3 session in test_schedule_service (#38707) 2026-07-14 03:43:19 +00:00
Asuka Minato
78a7c39d63 test: use sqlite3 session in test_plugin (#38710) 2026-07-14 03:42:55 +00:00
非法操作
b34a5940b3 fix(web): monitoring chart zero-value color and date range indicator (#38821) 2026-07-14 03:30:56 +00:00
yyh
509a8b1452 fix: align member invitation state and errors (#38885)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-14 03:05:44 +00:00
github-actions[bot]
d97a29317c chore(i18n): sync translations with en-US (#38873)
Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
2026-07-13 15:59:19 +00:00
Stephen Zhou
5ca1048c3c chore: simplify lint plugin configuration (#38872) 2026-07-13 15:47:25 +00:00
yyh
323654afe2 fix: align member invitation flow and API contracts (#38856)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-13 15:16:23 +00:00
Stephen Zhou
5e635c059b chore: update deps (#38868)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
2026-07-13 12:50:29 +00:00
Stephen Zhou
61d2ad572a chore: improve static check performance (#38866) 2026-07-13 10:30:52 +00:00
Coding On Star
c68e5e5ed3 fix(auth): prevent open redirects in post-login flows (#38864)
Co-authored-by: CodingOnStar <hanxujiang@dify.com>
2026-07-13 10:11:36 +00:00
Crazywoola
7865ffd429 chore: Improve workflow generator accessibility and API contracts (#38838)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-13 09:15:54 +00:00
林玮 (Jade Lin)
8e0d10bf5e fix(api): require trial app registration for reads (#38858) 2026-07-13 09:12:44 +00:00
Stephen Zhou
e35187f376 chore: migrate static checks to vp check (#38850) 2026-07-13 08:00:39 +00:00
Asuka Minato
b03385ffb0 test: use sqlite3 session in test_create_document_index (#38690) 2026-07-13 07:53:32 +00:00
Joel
cb209bc049 chore: add skill upload fail tip (#38851) 2026-07-13 07:52:12 +00:00
Asuka Minato
9905e6eceb test: use sqlite3 session in test_oauth_device_flow (#38782) 2026-07-13 07:48:15 +00:00
Asuka Minato
2188e2e172 test: use sqlite3 session in test_app_event_signals (#38776) 2026-07-13 07:46:50 +00:00
Asuka Minato
213b28f17b test: use sqlite3 session in test_retrieval_attachment_access (#38766) 2026-07-13 07:27:15 +00:00
Asuka Minato
0cea67e72d test: use sqlite3 session in test_remote_retrieval (#38748) 2026-07-13 07:25:38 +00:00
Asuka Minato
57f325df27 test: use sqlite3 session in test_billing_service (#38779) 2026-07-13 07:23:48 +00:00
Xiyuan Chen
c21a248df6 chore(deps): bump python-engineio and python-socketio for CVE fixes (#38844) 2026-07-13 07:22:27 +00:00
Joel
514409814d fix: prevent chat attachments from scrolling out of view (#38846) 2026-07-13 06:42:15 +00:00
Stephen Zhou
eb71e47f3b chore: migrate linting to vp lint with ESLint fallback (#38834)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-13 06:41:53 +00:00
Joel
12a2628794 fix: max token params can not be disabled in follow-up model parameters (#38842) 2026-07-13 06:34:36 +00:00
Asuka Minato
a997b90230 test: use sqlite3 session in test_buildin_retrieval (#38745) 2026-07-13 06:21:10 +00:00
Asuka Minato
e6d598065e test: use sqlite3 session in test_banner (#38746) 2026-07-13 06:20:40 +00:00
Asuka Minato
9740c35f6f test: use sqlite3 session in test_credential_utils (#38747) 2026-07-13 06:19:23 +00:00
Asuka Minato
5f8ef3c321 test: use sqlite3 session in test_trace_session_metadata (#38750) 2026-07-13 06:05:07 +00:00
Asuka Minato
831443b45c test: use sqlite3 session in test_wraps (#38749) 2026-07-13 06:04:14 +00:00
Asuka Minato
7909c0c0df test: use sqlite3 session in test_comment_models (#38767) 2026-07-13 05:51:35 +00:00
Asuka Minato
8072b64292 test: use sqlite3 session in test_completion (#38783) 2026-07-13 05:25:41 +00:00
yyh
ab521c4cfd refactor(chat): modernize speech-to-text pipeline (#38653)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Yansong Zhang <916125788@qq.com>
2026-07-13 04:21:29 +00:00
dependabot[bot]
408cd12835 chore(deps): bump the storage group in /api with 5 updates (#38825)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-13 11:32:27 +08:00
dependabot[bot]
ca46d07ea8 build(deps): bump soupsieve from 2.8 to 2.8.4 in /api (#38631)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-13 11:32:06 +08:00
dependabot[bot]
e721801b37 chore(deps): bump the google group in /api with 2 updates (#38811)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-13 11:31:53 +08:00
dependabot[bot]
f03648435a chore(deps): bump flask-cors from 6.0.2 to 6.0.5 in /api in the flask group (#38810)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-13 11:31:37 +08:00
Joel
41683013e3 fix: marketplace page header jitter when it in sticky status (#38832) 2026-07-13 03:19:10 +00:00
Asuka Minato
0e84444809 test: use sqlite3 session in test_data_migration_commands (#38672) 2026-07-13 03:04:37 +00:00
Asuka Minato
b893b53f0a test: use sqlite3 session in test_plugin_tool (#38781) 2026-07-13 03:03:12 +00:00
Asuka Minato
4c1c92eb2f test: use sqlite3 session in test_remove_app_and_related_data_task (#38778) 2026-07-13 03:02:30 +00:00
非法操作
7311f1ba6d chore: sandbox plan should not execution special workflow (#38662)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-13 02:55:39 +00:00
Wu Tianwei
f4dfac7214 fix: update role selector to use max height for scroll area (#38831) 2026-07-13 02:38:15 +00:00
dependabot[bot]
6d8e390c95 chore(deps): bump the github-actions-dependencies group with 4 updates (#38807)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-13 01:39:28 +00:00
Stephen Zhou
a84c2d36a3 style: format with vp fmt (#38803)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-12 15:57:46 +00:00
Yufeng He
fde08d24fe fix: eagerly validate conversation on service-api and explore chat endpoints (#38801)
Signed-off-by: Yufeng He <40085740+he-yufeng@users.noreply.github.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-12 15:19:07 +00:00
Stephen Zhou
b54107e9b9 chore: migrate formatting to vp fmt (#38705)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-12 14:59:00 +00:00
yyh
594c21d98c fix(web): split model selection and settings actions (#38797)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-12 14:24:27 +00:00
yyh
6e59c723c9 fix(agent-v2): restore keyboard access to row actions (#38792) 2026-07-12 14:23:49 +00:00
yyh
4efab8d7a3 chore(dify-ui): enforce strict ESLint rules (#38793) 2026-07-12 14:23:39 +00:00
yyh
2a2193dabb fix(web): correct knowledge dialog draft state (#38794) 2026-07-12 14:23:28 +00:00
yyh
1246aa7f3a refactor(web): normalize z-index layering (#38796) 2026-07-12 14:23:14 +00:00
yyh
3defd50709 fix(web): improve marketplace install dialog accessibility (#38798) 2026-07-12 14:18:39 +00:00
yyh
6e5ba18d65 refactor(dify-ui): standardize primitive boundary names (#38669) 2026-07-10 14:17:10 +00:00
Stephen Zhou
e3a08b40f2 test(web): centralize i18n mocks (#38670) 2026-07-10 14:08:33 +00:00
Stephen Zhou
6f47950fe2 perf(web): lazy-load Vite plugins (#38663) 2026-07-10 11:13:09 +00:00
林玮 (Jade Lin)
4043adacd7 fix(trigger): return 429 instead of 500 when API quota is exceeded (#38664) 2026-07-10 10:57:50 +00:00
Stephen Zhou
b9fde89781 refactor(web): migrate i18n to selector optimize mode (#38657)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-10 09:35:31 +00:00
github-actions[bot]
d612307658 chore(i18n): sync translations with en-US (#38658)
Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Co-authored-by: yyh <92089059+lyzno1@users.noreply.github.com>
2026-07-10 09:34:41 +00:00
wangxiaolei
7e05f28a46 feat: create app init rbac scope to all and add workspace members. (#38636)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-10 09:31:41 +00:00
林玮 (Jade Lin)
44fb074359 fix(trigger): surface webhook trigger quota exceeded as 429 response (#38656) 2026-07-10 08:50:25 +00:00
无能的迪拜巧克力
775ed70bac feat(web): refine web app customization options (#38650) 2026-07-10 08:35:26 +00:00
KVOJJJin
3c8e0e2113 fix(web): support punctuation in markdown form field names (#38651) 2026-07-10 07:08:07 +00:00
yyh
489e77658e fix(web): simplify infotip icon variants (#38644) 2026-07-10 06:37:36 +00:00
Joel
4a8c6773a3 fix: final answer in new agent would clear after sse if agent thought has answer (#38649) 2026-07-10 06:33:26 +00:00
Asuka Minato
d0f0134314 test: use sqlite3 session (#38641) 2026-07-10 06:11:24 +00:00
zyssyz123
9b3650e2ca fix(agent): surface knowledge retrieval failures (#38640) 2026-07-10 04:40:46 +00:00
KVOJJJin
0038bcc4bb fix(web): agent tool credentials mismatch (#38637) 2026-07-10 04:35:52 +00:00
yyh
b325597d29 test(e2e): consume agent service API SSE incrementally (#38634) 2026-07-10 04:26:04 +00:00
Stephen Zhou
b7255e6f27 chore: migrate js-yaml to v5 (#38639) 2026-07-10 04:03:30 +00:00
yyh
c3fb5344cb fix: simplify help menu upgrade item (#38635) 2026-07-10 03:58:27 +00:00
Yunlu Wen
888bea9911 feat: ee agent sandbox support (#38528)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-07-10 03:56:55 +00:00
Asuka Minato
2da37a9416 test: Mock to sqlite3 (#38499)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-10 03:49:06 +00:00
chariri
f902551d0c chore(api): Prohibit new direct SQLAlchemy in controller (#38624)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-10 03:10:27 +00:00
Dresden
faba726a45 chore: Replace @patch logger.warning with caplog fixture in credit_pool_service test (#38626) 2026-07-10 03:08:17 +00:00
wangxiaolei
7da3d7074a chore: remove unused param (#38628) 2026-07-10 02:20:16 +00:00
Stephen Zhou
f9dd37420b chore: update deps (#38627)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-10 02:07:57 +00:00
yyh
eb74946b25 fix(web): save agent configure draft on route leave (#38620) 2026-07-09 13:55:34 +00:00
QuantumGhost
b5e35fc2fc fix: remove hardcoded sandbox path in configuration file (#38618) 2026-07-09 13:30:56 +00:00
wangxiaolei
7bfbb2bbe8 fix: fix auth prefix duplicate (#38616) 2026-07-09 12:55:58 +00:00
QuantumGhost
d177998255 chore: Bump version to 1.16.0-rc1 (#38600) 2026-07-09 11:42:09 +00:00
wangxiaolei
74ee665af6 fix: fix miss session param (#38612)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-09 11:26:16 +00:00
Stephen Zhou
d655153a3d fix(web): update docs links (#38591) 2026-07-09 11:25:31 +00:00
zyssyz123
925f97be20 feat: daily sync (#38593)
Co-authored-by: 盐粒 Yanli <mail@yanli.one>
Co-authored-by: yyh <yuanyouhuilyz@gmail.com>
Co-authored-by: Joel <iamjoel007@gmail.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: QuantumGhost <obelisk.reg+git@gmail.com>
Co-authored-by: yyh <92089059+lyzno1@users.noreply.github.com>
Co-authored-by: 盐粒 Yanli <yanli@dify.ai>
2026-07-09 10:35:15 +00:00
Leilei
9252d81826 docs: remove Dify Premium on AWS Marketplace section from all READMEs (#38607)
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-09 10:09:59 +00:00
Harsh Kashyap
9d5819a9c1 fix(api): ignore invalid utf8 cache payloads (#37835)
Co-authored-by: Harsh Kashyap <Harsh23Kashyap@users.noreply.github.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Harsh Kashyap <harshkashyap@Harshs-MacBook-Pro.local>
2026-07-09 09:52:49 +00:00
Ingram Z
99e3b1a401 fix: harden workflow archive DB retries (#38170)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-09 09:46:28 +00:00
Asuka Minato
45957225cd chore: batch example #38419 (#38474)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-09 09:14:52 +00:00
Coding On Star
2f99652203 fix: chunk workflow failure tracking data (#38598)
Co-authored-by: CodingOnStar <hanxujiang@dify.com>
2026-07-09 08:33:47 +00:00
melooooooo
dc1131b6df refactor(tests): replace logger mocks with caplog in trace provider tests (#38569)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-09 08:33:28 +00:00
Stephen Zhou
a5a7c762a3 refactor(web): split app context state atoms (#38588) 2026-07-09 07:42:02 +00:00
Coding On Star
063e390c5d fix(web): preserve attribution from auth redirect (#38583)
Co-authored-by: CodingOnStar <hanxujiang@dify.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-09 07:40:55 +00:00
Joel
3b3c25273a fix: guard chat tree against out-of-order parents (#38590) 2026-07-09 07:05:05 +00:00
Xiyuan Chen
3775f569f1 fix: run user_connect authorization inside Flask app context (#38585) 2026-07-09 06:00:29 +00:00
chariri
6540d178c6 refactor(api): migrate service app endpoints to BaseModel (#37960)
Co-authored-by: Asuka Minato <i@asukaminato.eu.org>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-09 04:23:47 +00:00
chariri
458aa4892d refactor(api): migrate web chat endpoints to BaseModel (#37962) 2026-07-09 04:23:13 +00:00
chariri
89d5f74a40 refactor(api): migrate dataset endpoints to BaseModel (#37957)
Co-authored-by: Asuka Minato <i@asukaminato.eu.org>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-09 04:22:30 +00:00
chariri
9bb3b1fa98 refactor(api): migrate snippet workspace endpoints to BaseModel (#37956)
Co-authored-by: Asuka Minato <i@asukaminato.eu.org>
2026-07-09 04:21:27 +00:00
chariri
3cd8d850fa refactor(api): migrate workspace model endpoints to BaseModel (#37963)
Co-authored-by: Asuka Minato <i@asukaminato.eu.org>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Byron Wang <byron@dify.ai>
2026-07-09 04:05:32 +00:00
Stephen Zhou
c5cef80ea4 chore: generate fastopenapi console contracts (#38580) 2026-07-09 03:52:42 +00:00
Stephen Zhou
cee88de684 refactor(web): add prefetched query atom (#38572) 2026-07-09 02:47:51 +00:00
非法操作
5741f8f9d1 fix: when delete custom model remove its cache (#38577) 2026-07-09 02:12:23 +00:00
Stephen Zhou
512f39dede chore: upgrade TypeScript 7 (#38575)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-09 01:42:40 +00:00
Xiyuan Chen
d72ee32ba1 fix: preserve ResponseStreamFilter state across workflow pause/resume (#38540)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-09 01:05:47 +00:00
yyh
2b35f48d77 test(e2e): fix agent build note runtime connection (#38574) 2026-07-09 00:36:20 +00:00
Stephen Zhou
caf1a22020 refactor(web): sync app context effects with jotai (#38570) 2026-07-08 15:55:25 +00:00
yyh
9416d04163 test(e2e): stabilize agent build draft note scenario (#38571) 2026-07-08 15:38:47 +00:00
Stephen Zhou
23b936aeb5 refactor(web): remove app context provider (#38568) 2026-07-08 13:52:45 +00:00
mengnanjiugaipeifense
eb3362e646 perf: batch-load messages in advanced-chat workflow run list to remove N+1 (#38359)
Co-authored-by: Yunlu Wen <yunlu.wen@dify.ai>
2026-07-08 13:32:32 +00:00
yyh
98d9b11f7b chore(agent-v2): sync changes (#38513)
Co-authored-by: Joel <iamjoel007@gmail.com>
Co-authored-by: 林玮 (Jade Lin) <linw1995@icloud.com>
Co-authored-by: 盐粒 Yanli <mail@yanli.one>
Co-authored-by: Asuka Minato <i@asukaminato.eu.org>
Co-authored-by: Jashwanth Reddy Gummula <gmrnlg1971@gmail.com>
Co-authored-by: WH-2099 <wh2099@pm.me>
Co-authored-by: 非法操作 <hjlarry@163.com>
Co-authored-by: wangxiaolei <fatelei@gmail.com>
Co-authored-by: FFXN <31929997+FFXN@users.noreply.github.com>
Co-authored-by: Yansong Zhang <916125788@qq.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-08 12:05:04 +00:00
Stephen Zhou
d67123e5fd refactor(web): remove remaining app context consumers (#38565)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-08 11:28:25 +00:00
yyh
1340bef096 test: scope agent build draft e2e selector (#38563) 2026-07-08 10:32:57 +00:00
Stephen Zhou
94ba597d32 refactor(web): migrate shell navigation app context consumers (#38560)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-08 10:11:27 +00:00
chariri
9465dc2477 refactor(api): remove remaining legacy field remnants (#37967) 2026-07-08 09:59:10 +00:00
chariri
74f177efe6 refactor(api): migrate workspace tool endpoints to BaseModel (#37959) 2026-07-08 09:56:04 +00:00
Stephen Zhou
af5b08ac5c refactor(web): migrate agent v2 app context consumers (#38558) 2026-07-08 09:42:49 +00:00
Stephen Zhou
eca2d419b2 refactor(web): migrate workflow app context consumers (#38552) 2026-07-08 09:01:30 +00:00
Asuka Minato
a278d21741 test: more caplog (#38452)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-08 08:24:31 +00:00
Stephen Zhou
dce45ef6ae refactor(web): migrate account settings app context consumers (#38544)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-08 08:15:54 +00:00
Crazywoola
5ffd4345dc fix: display errors for oauth page (#38546)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-08 08:07:14 +00:00
yyh
16ae1dd131 chore: remove superpowers artifacts (#38547) 2026-07-08 07:59:32 +00:00
Xiyuan Chen
ae1e180b54 fix(cli): --insecure also skips TLS certificate verification (#38531) 2026-07-08 07:58:31 +00:00
zyssyz123
5d61318860 feat(api): use billing quota for credit pool (#38028)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-08 07:10:18 +00:00
Stephen Zhou
5a210cf03e refactor(web): migrate billing app context consumers (#38541) 2026-07-08 07:02:47 +00:00
Yuzi
3523da508f fix(web): guard invite-settings activate button against double-click (#38337) 2026-07-08 06:28:43 +00:00
Stephen Zhou
503d80be1d refactor(web): migrate plugins and tools app context consumers (#38533)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-08 06:26:56 +00:00
Evan
98f67e9c82 fix(ci): make no-new-getattr guard stable in shallow PR checkouts (#38480)
Co-authored-by: QuantumGhost <obelisk.reg+git@gmail.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-08 06:22:59 +00:00
i晟
af4538e942 fix: raise clear error on unsupported language in execute_code (#38448)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-08 06:20:10 +00:00
yyh
10cf9be3c7 test(web): align auth e2e with console home (#38538) 2026-07-08 06:17:14 +00:00
yyh
41fb479957 fix(web): cache server console context (#38535) 2026-07-08 06:16:59 +00:00
yyh
6ac7ff6586 chore(deps): upgrade vite-plus toolchain (#38534) 2026-07-08 04:33:10 +00:00
Stephen Zhou
76a6cd3335 refactor(web): migrate app context consumers (#38530) 2026-07-08 03:51:50 +00:00
yyh
6c0aa3ed0d test(dify-ui): remove brittle primitive assertions (#38529) 2026-07-08 03:24:22 +00:00
Asuka Minato
68d8328b9c chore: clean Db session from service (#38227)
Co-authored-by: chariri <w@chariri.moe>
Co-authored-by: WH-2099 <wh2099@pm.me>
2026-07-08 03:07:27 +00:00
Stephen Zhou
ee0068eed4 refactor(web): migrate dataset access context (#38523)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-08 02:35:54 +00:00
L1nSn0w
915655683c refactor(openapi): resource-oriented paths for /openapi/v1 + difyctl version gate (#38367)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-08 02:22:59 +00:00
Nian
abd720146d test(services): cover DSL import and plugin migration regressions (#36072)
Co-authored-by: WH-2099 <wh2099@pm.me>
2026-07-07 15:31:04 +00:00
Stephen Zhou
5308b95aff refactor(web): reduce query atom subscriptions (#38521) 2026-07-07 15:10:58 +00:00
ojasarora.eth
09c5c5e5ed refactor(test): replace SimpleNamespace with typed mocks in schedule service tests (#38393) 2026-07-07 14:36:17 +00:00
chariri
64aa142681 chore(api): cache the setup status to cut down DB access (#36966)
Co-authored-by: Asuka Minato <i@asukaminato.eu.org>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Byron.wang <byron@dify.ai>
2026-07-07 14:30:28 +00:00
Stephen Zhou
56f3d0a11e refactor(web): clarify app context bootstrap graph (#38516)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-07 14:08:38 +00:00
非法操作
6edce14e88 fix: can't debug model plugins (#38500) 2026-07-07 13:03:32 +00:00
yyh
3ddfba5ca5 fix(web): add backdrop blur to skip nav (#38517) 2026-07-07 13:02:30 +00:00
yyh
2c6ec1a761 refactor(web): move app context layout styles to shell (#38511) 2026-07-07 09:47:30 +00:00
yyh
31b17513c2 docs(component): document focus-visible guidance (#38509) 2026-07-07 08:58:35 +00:00
FFXN
fb92e9a347 chore: improve cherry pick missed message (#38496) 2026-07-07 07:53:14 +00:00
wangxiaolei
6922c45489 chore: update editor permission (#38505) 2026-07-07 07:53:01 +00:00
非法操作
faaa4708a6 fix: editor should not manage member (#38503) 2026-07-07 07:39:24 +00:00
Jashwanth Reddy Gummula
dd0c4a2296 fix: resolve 36288 mypy errors (#37850)
Co-authored-by: WH-2099 <wh2099@pm.me>
2026-07-07 06:37:20 +00:00
Asuka Minato
f3ba28463b chore: add sqlite3 to conftest (#38475) 2026-07-07 05:04:44 +00:00
Stephen Zhou
800c9f4fca test(e2e): stabilize Agent v2 external runtime checks (#38493)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-07 04:48:12 +00:00
Charles Yao
5a342f9258 feat(mcp): support MCP protocol 2025-06-18 for workflow-as-MCP server (version negotiation + structured output) (#37892)
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: yunlu.wen <yunlu.wen@dify.ai>
2026-07-07 03:26:50 +00:00
Copilot
dbd3316615 chore: set NEXT_PUBLIC_ENABLE_FEATURE_PREVIEW default to true (#38362)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
2026-07-07 02:20:15 +00:00
WH-2099
0a3426ea38 refactor(api): clarify DSL import and plugin migration boundaries (#38483)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-07 02:06:49 +00:00
Jingyi
b9c7199d34 fix(web): unify detail sidebar home control (#38487) 2026-07-07 01:44:14 +00:00
QuantumGhost
fc01d112a0 refactor(api): Stop masking refresh-token service errors as 401 (#38463)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-06 18:14:54 +00:00
yyh
d0ea5a5e0d chore(agent-v2): sync changes (#38442)
Co-authored-by: Joel <iamjoel007@gmail.com>
Co-authored-by: zyssyz123 <916125788@qq.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: 林玮 (Jade Lin) <linw1995@icloud.com>
Co-authored-by: 盐粒 Yanli <mail@yanli.one>
2026-07-06 13:51:33 +00:00
yyh
bdb3469ca0 refactor(dify-ui): consolidate radio family API (#38479) 2026-07-06 12:27:49 +00:00
非法操作
c47663d77b chore: Update sidebar web app menu translations (#38473) 2026-07-06 10:09:36 +00:00
非法操作
1247fa28f1 fix(web): redirect imported apps with creator permissions (#38460) 2026-07-06 09:11:56 +00:00
Ryuta KOBAYASHI
64d72c6fb9 feat(api): pass app_id to model plugins for provider-side cost attribution (#35859)
Co-authored-by: WH-2099 <wh2099@pm.me>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-06 08:54:16 +00:00
Harsh Kashyap
78ca1a8a76 fix(api): resolve plugin external user ids in backwards invocation (#38098)
Co-authored-by: Harsh Kashyap <Harsh23Kashyap@users.noreply.github.com>
Co-authored-by: Harsh Kashyap <harshkashyap@Harshs-MacBook-Pro.local>
2026-07-06 08:25:26 +00:00
chariri
5aae5c15b3 refactor(api): migrate web auth endpoints to BaseModel (#37961)
Co-authored-by: Asuka Minato <i@asukaminato.eu.org>
2026-07-06 07:53:21 +00:00
Asuka Minato
b1724073fc test: example use sqlite3 as unittest backend (#38159) 2026-07-06 07:31:51 +00:00
chariri
904fadde20 refactor(api): remove member field compatibility (#37966)
Co-authored-by: WH-2099 <wh2099@pm.me>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Asuka Minato <i@asukaminato.eu.org>
2026-07-06 07:00:43 +00:00
chariri
77ae583b44 refactor(api): migrate dataset rag pipeline endpoints to BaseModel (#37958)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Asuka Minato <i@asukaminato.eu.org>
2026-07-06 07:00:04 +00:00
chariri
c3b1508712 refactor(api): migrate workspace account endpoints to BaseModel (#37954) 2026-07-06 06:57:40 +00:00
yyh
8208b786ee docs(dify-ui): clarify radio composition stories (#38456) 2026-07-06 06:40:17 +00:00
Pranav Agarwal
d9c99daf29 fix(api): isolate side-effect session writes in multimodal and RAG handlers (#38210)
Co-authored-by: FFXN <31929997+FFXN@users.noreply.github.com>
2026-07-06 05:17:12 +00:00
KVOJJJin
93eb6d32b5 fix(web): update snippet placeholder icon color (#38445) 2026-07-06 05:10:36 +00:00
dependabot[bot]
de5af6c2da build(deps): bump the github-actions-dependencies group across 1 directory with 12 updates (#38430)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-06 04:39:10 +00:00
i晟
586c8de1a0 refactor: drop redundant len(tag_ids)==0 check in get_target_ids_by_tag_ids (#38447) 2026-07-06 04:35:58 +00:00
chariri
94c0967e30 refactor(api): migrate console explore endpoints to BaseModel (#37953) 2026-07-06 02:51:10 +00:00
Harsh Kashyap
ff5c5f3ca6 fix(api/tasks): use f-string for raise messages in resume_workflow_ex… (#37607)
Co-authored-by: Harsh Kashyap <Harsh23Kashyap@users.noreply.github.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Harsh Kashyap <harshkashyap@Harshs-MacBook-Pro.local>
2026-07-06 02:36:14 +00:00
yyh
95102479c6 test(e2e): split agent build draft apply coverage (#38431) 2026-07-06 01:03:01 +00:00
yyh
6dff7c0a85 fix(dify-ui): preserve radio value generics (#38429) 2026-07-05 14:01:36 +00:00
yyh
e742e0ec17 fix(dify-ui): improve picker type inference (#38428) 2026-07-05 14:01:21 +00:00
yyh
acfef79a8f fix(web): prevent plugin cards from overlapping marketplace panel (#38427) 2026-07-05 14:01:07 +00:00
Copilot
abaf6b1337 ci: extract external E2E into dedicated post-merge workflow (#38426)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: yyh <yuanyouhuilyz@gmail.com>
2026-07-05 14:00:53 +00:00
yyh
750075c859 style: fix provider card dropdown menu seperator margin (#38422)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-05 14:00:40 +00:00
yyh
1b3e8e9943 chore(agent-v2): sync daily changes (#38298)
Signed-off-by: yyh <yuanyouhuilyz@gmail.com>
Co-authored-by: 盐粒 Yanli <mail@yanli.one>
Co-authored-by: Joel <iamjoel007@gmail.com>
Co-authored-by: zyssyz123 <916125788@qq.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: 盐粒 Yanli <yanli@dify.ai>
Co-authored-by: 林玮 (Jade Lin) <linw1995@icloud.com>
2026-07-05 08:09:38 +00:00
Copilot
f8d47616c1 refactor(dify-ui): render ContextMenu story trigger as a semantic area (#38420)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: yyh <yuanyouhuilyz@gmail.com>
2026-07-05 01:45:21 +00:00
Yuzi
f755830607 fix(models): correct onupdate typo on trigger.py updated_at columns (#38341)
Co-authored-by: Asuka Minato <i@asukaminato.eu.org>
2026-07-04 17:14:01 +00:00
yyh
5d7ae56deb fix(dify-ui): standardize story focus indicators (#38417) 2026-07-04 14:59:24 +00:00
yyh
a0f8347513 test(dify-ui): remove low-value style assertions (#38418) 2026-07-04 14:35:00 +00:00
Checo
2e1ab194b7 refactor: replace db.paginate with plain SQLAlchemy pagination (#38280)
Co-authored-by: Asuka Minato <i@asukaminato.eu.org>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-04 04:50:01 +00:00
Byron.wang
070aed81d9 refactor: make session boundaries explicit for migration flows (#38379) 2026-07-04 04:43:01 +00:00
Wu Tianwei
5b4ceacbe7 fix(chat): enhance pointer event handling in chat components (#38385) 2026-07-03 09:46:22 +00:00
林玮 (Jade Lin)
5e17af4530 feat(api): add sandbox info endpoint for Agent App conversations (#38390)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-03 09:43:57 +00:00
KVOJJJin
d3ed533716 fix(web): adjust snippets input count badge color (#38386) 2026-07-03 09:05:52 +00:00
非法操作
91cc50371b chore: use zstd for plugin model provider cache (#38382) 2026-07-03 08:58:30 +00:00
非法操作
81cc43b753 fix: incorrect backgroud when dark mode and no plugins (#38378)
Co-authored-by: yyh <yuanyouhuilyz@gmail.com>
2026-07-03 08:21:50 +00:00
Byron.wang
5cb76f5eff refactor: manage rag pipeline sessions explicitly (#38274) 2026-07-03 08:15:37 +00:00
L1nSn0w
262b0b1a89 fix(cli): report GitHub API rate limits in difyctl install scripts (#38375) 2026-07-03 08:12:58 +00:00
非法操作
059a1fe090 chore: compress large plugin_model obj in redis (#38374)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-03 07:32:07 +00:00
KVOJJJin
7b7956f3e7 feat: snippet siderbar update (#38371) 2026-07-03 07:18:13 +00:00
林玮 (Jade Lin)
5622e8f7ea feat(api): abort active workflow runs during Celery warm shutdown (#38220) 2026-07-03 04:51:53 +00:00
github-actions[bot]
c080e2c3b8 chore(i18n): sync translations with en-US (#38355)
Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
2026-07-03 04:22:13 +00:00
AsperforMias
1bc279e7d4 fix: handle Xinference model credential context (#38348) 2026-07-03 04:12:00 +00:00
QuantumGhost
f4ec608ef4 chore(api): upgrade graphon to v0.6.0, migrate HITL logic back to Dify (#38247)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-03 03:45:21 +00:00
蒜香飞行矮堇瓜
cb6179356c fix(web): align external API and service API buttons vertically in datasets header (#38139) 2026-07-03 02:34:38 +00:00
Xiyuan Chen
374bdb7cdd feat(device-flow): redirect SSO-complete failures to a dedicated device error view (#38185) 2026-07-03 02:11:54 +00:00
mengnanjiugaipeifense
cf0f42a8da perf(memory): batch-load message files in TokenBufferMemory to remove N+1 queries (#38002)
Co-authored-by: xiaweiwei67-stack <293320877+xiaweiwei67-stack@users.noreply.github.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-03 01:59:48 +00:00
Jingyi
d120995efc fix: prevent app card meta overflow (#38349) 2026-07-03 01:50:05 +00:00
yyh
57f687fb45 fix(web): align main nav app item states (#38326)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Jingyi-Dify <jingyi.qi@dify.ai>
2026-07-02 21:03:30 +00:00
Byron.wang
2f0c6c10bd refactor: thread explicit sessions through app retrieval paths (#38309)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-02 17:00:47 +00:00
Escape0707
dcc06dee20 test: migrate tag service tests to testcontainers (#38313) 2026-07-02 11:58:56 +00:00
Stephen Zhou
12c06a61be fix(web): keep app sort filter with header filters (#38324)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
2026-07-02 11:53:33 +00:00
yyh
ff56fb7e23 fix(workspace): expose last opened in contract (#38323)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-02 11:14:35 +00:00
Stephen Zhou
3f92e38616 fix: normalize query array params for oRPC (#38322)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-02 11:07:10 +00:00
非法操作
3d10f6c510 fix: Notion sync empty state width in knowledge creation (#38321) 2026-07-02 10:37:54 +00:00
林玮 (Jade Lin)
92618f5e20 feat(agent-v2): resolve Dify core tools in agent runtime runner (#38316) 2026-07-02 09:25:11 +00:00
FFXN
88864ae086 fix: enhance SQL query safety and add metadata key validation (#38307) 2026-07-02 09:02:54 +00:00
github-actions[bot]
49cee348b5 chore(i18n): sync translations with en-US (#38301)
Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Co-authored-by: yyh <92089059+lyzno1@users.noreply.github.com>
2026-07-02 08:59:36 +00:00
Stephen Zhou
eb67c9c0ee refactor(web): move marketplace contract to contracts package (#38311) 2026-07-02 08:41:02 +00:00
非法操作
e13271ba29 fix: support multi-worker workflow collaboration (#38242)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Blackoutta <hyytez@gmail.com>
Co-authored-by: Blackoutta <37723456+Blackoutta@users.noreply.github.com>
2026-07-02 08:16:03 +00:00
yyh
6ec56e7bd1 fix(web): fill dataset create layout height (#38308) 2026-07-02 08:10:24 +00:00
Stephen Zhou
451faa0e68 fix(web): align monitoring overview charts (#38292) 2026-07-02 07:30:25 +00:00
林玮 (Jade Lin)
1af535a173 fix(agent-v2): preserve oauth2 credential refs when converting tool c… (#38303) 2026-07-02 07:07:42 +00:00
wangxiaolei
826b259d9f fix: Working outside of application context. (#38300) 2026-07-02 06:47:35 +00:00
QuantumGhost
2ee7db27be chore(api): disallow builtins getattr variants in new code (#38250)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-02 06:32:46 +00:00
Harsh Kashyap
31bb8abbf1 fix(api): stop swallowing document indexing errors in create handler (#38192)
Co-authored-by: Harsh Kashyap <Harsh23Kashyap@users.noreply.github.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Harsh Kashyap <harshkashyap@Harshs-MacBook-Pro.local>
Co-authored-by: yunlu.wen <yunlu.wen@dify.ai>
2026-07-02 06:29:56 +00:00
FFXN
d9884efaee fix: sql injection (#38295)
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-07-02 06:22:39 +00:00
yyh
1ae2f95f7c test(e2e): add agent v2 core coverage (#38209)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-02 06:18:38 +00:00
Joel
0bd359bb8f fix: web detail adjustment before release (#38296)
Co-authored-by: Jingyi-Dify <jingyi.qi@dify.ai>
2026-07-02 06:16:55 +00:00
Manan Bansal
6c08a43af1 fix(templates): make End output variable names unique in built-in templates (#38293) 2026-07-02 06:06:07 +00:00
Manan Bansal
41fb484491 fix(api): tolerate legacy service_api end-user type on load (#38271)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 05:34:36 +00:00
WH-2099
7fb797c121 fix(api): keep provider refresh waiters single-flight (#38226) 2026-07-02 04:46:10 +00:00
chariri
5d0576de0a refactor(api): migrate console app chat endpoints to BaseModel (#37952)
Co-authored-by: Asuka Minato <i@asukaminato.eu.org>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-02 04:43:58 +00:00
Stephen Zhou
61650d34ce refactor(web): remove custom console contract loaders (#38284)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-02 03:32:02 +00:00
chariri
4fc8f0ddd1 refactor(api): migrate console app common endpoints to BaseModel (#37951)
Co-authored-by: Asuka Minato <i@asukaminato.eu.org>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-02 03:24:38 +00:00
Xiyuan Chen
2429b757d8 fix(web): add missing i18n for CLI device flow login page (#38282) 2026-07-02 03:09:02 +00:00
QuantumGhost
51156fef07 chore: remove empty .codex file (#38286) 2026-07-02 03:01:00 +00:00
Stephen Zhou
ca8b680322 refactor(web): migrate trial app console contracts (#38254)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-01 16:31:49 +00:00
Stephen Zhou
8540ca9242 refactor(web): migrate snippet console contracts (#38258)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-01 16:31:39 +00:00
Stephen Zhou
37bcb60c26 refactor(web): migrate plugin console contracts (#38252)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-01 15:34:52 +00:00
Stephen Zhou
6eb9928df7 refactor(web): migrate trigger console contracts (#38255)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-01 14:46:30 +00:00
Stephen Zhou
f98c6cb2a6 refactor(web): migrate model provider console contracts (#38253)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-01 14:46:17 +00:00
Stephen Zhou
ee1d33eaa6 refactor(web): migrate rbac access console contracts (#38256)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-01 14:45:34 +00:00
yyh
f1f6ab0ac6 refactor(ui): use inset ring utilities (#38275) 2026-07-01 12:23:23 +00:00
eux
bf46b82303 fix(web): clarify unpublished explore app handling (#38260) 2026-07-01 11:04:01 +00:00
Joel
c1d03a888f chore: remove useless tag params logic in use effect (#38269) 2026-07-01 10:19:55 +00:00
Stephen Zhou
befe7ec269 fix(web): improve card grid responsiveness (#38263) 2026-07-01 09:58:11 +00:00
yyh
76391b0383 chore(github): add e2e labeler and code owner (#38257) 2026-07-01 07:16:03 +00:00
非法操作
583bc34c3b fix: order main nav account classes (#38251) 2026-07-01 06:54:35 +00:00
coslog
005bc54c38 refactor: use Pydantic for sensitive word avoidance config (Fixes #37… (#37660)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Asuka Minato <i@asukaminato.eu.org>
2026-07-01 06:46:48 +00:00
Checo
3390be3978 refactor: pass db.session explicitly in DatasetIndexToolCallbackHandler (#38082) 2026-07-01 06:16:13 +00:00
Stephen Zhou
edf21269b3 refactor(web): decouple detail sidebars from main nav (#38241) 2026-07-01 06:07:07 +00:00
Stephen Zhou
93981cf75f refactor(web): migrate console contracts to generated routes (#38233)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
2026-07-01 05:41:37 +00:00
yyh
0923ebaf88 chore(agent-v2): sync daily changes (#38162)
Co-authored-by: yunlu.wen <yunlu.wen@dify.ai>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Yunlu Wen <wylswz@163.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Joel <iamjoel007@gmail.com>
Co-authored-by: Yanli 盐粒 <yanli@dify.ai>
Co-authored-by: 盐粒 Yanli <beautyyuyanli@gmail.com>
Co-authored-by: zyssyz123 <916125788@qq.com>
Co-authored-by: 盐粒 Yanli <mail@yanli.one>
2026-07-01 05:07:23 +00:00
Jingyi
f816ae2e95 fix: handle integration marketplace install callbacks (#38236)
Co-authored-by: hjlarry <hjlarry@163.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-07-01 03:14:40 +00:00
dependabot[bot]
4f1030b94d build(deps): bump pydantic-ai-slim from 1.85.1 to 1.102.0 in /dify-agent (#38135)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-01 11:12:17 +08:00
github-actions[bot]
a3ce7aced7 chore(i18n): sync translations with en-US (#38239)
Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
2026-07-01 11:09:51 +08:00
Crazywoola
8809cc036d feat(workflow-generator): enhance the AI auto-creation flow end-to-end (#38175)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
2026-07-01 02:28:58 +00:00
Stephen Zhou
3ad06bebd9 refactor(web): migrate console contracts to generated types (#38231)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
2026-07-01 01:40:12 +00:00
蒜香飞行矮堇瓜
089c3f4af0 fix(api): avoid infinite loop in _delete_records when batch deletion fails (#38118)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-06-30 14:40:37 +00:00
Stephen Zhou
4b17f968a6 perf(web): lazy load console contract shards (#38230) 2026-06-30 14:15:29 +00:00
Stephen Zhou
baf2191ee3 fix(web): hide deployment access sidebar tab (#38229) 2026-06-30 11:52:31 +00:00
Stephen Zhou
9393df9d00 fix(web): hide deployment access tab (#38222) 2026-06-30 10:54:57 +00:00
Stephen Zhou
b1bb6ef977 perf(web): improve vinext home startup time (#38219) 2026-06-30 10:36:38 +00:00
Pyuyi
200f8b800f fix(api): prevent plugin provider cache stampedes (#37388)
Co-authored-by: VeraPyuyi <204892921+VeraPyuyi@users.noreply.github.com>
2026-06-30 10:09:05 +00:00
chariri
44e85c0023 fix(api): Fixing API contract generation infrastructure (#38042) 2026-06-30 08:51:32 +00:00
Xiyuan Chen
5ce13d1773 fix(api): register rbac-migrate-dataset-permissions CLI command (#38204)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-06-30 08:20:24 +00:00
WH-2099
62cb5b5865 fix(api): scope nested resource lookups by owner refs (#38177)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-06-30 08:19:58 +00:00
yyh
f8afa49ab9 chore(dify-ui): update theme tokens (#38189) 2026-06-30 07:54:13 +00:00
Blackoutta
b4be4d90a5 fix: stress test setup process and report structure workflow for Dify 1.15.0+ (#38194) 2026-06-30 07:29:42 +00:00
非法操作
4303103304 fix: debug plugin permission setting not work (#38197) 2026-06-30 07:29:20 +00:00
Bond Zhu
03d59dba47 fix(workflow): guard on_tool_execution stdout traces behind DEBUG (#38200) 2026-06-30 07:19:48 +00:00
Asuka Minato
102e1ede6e chore: inject more db.session (#38045)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-06-30 06:55:54 +00:00
wangxiaolei
528bf95d1b feat: support dataset permission migrate to rbac (#38166) 2026-06-30 06:43:46 +00:00
yyh
444d164aea test(e2e): add agent v2 test infrastructure (#38191) 2026-06-30 06:25:20 +00:00
Wu Tianwei
46163c68bd fix: update documentation links in permission set and role modals (#38188) 2026-06-30 05:41:55 +00:00
Wu Tianwei
54a8ff2c1d chore(i18n): update role management permission keys for multiple languages (#38186) 2026-06-30 03:28:34 +00:00
Sanket Shakya
9521c7fe7d feat(mcp): support dynamic HTTP request headers in MCPClient (#37938) 2026-06-30 03:28:24 +00:00
Muhammad Zeeshan
995ba6b00e fix(api): skip uuidv7() creation when PostgreSQL 18 provides it natively (#36998)
Co-authored-by: Yunlu Wen <yunlu.wen@dify.ai>
2026-06-30 02:34:27 +00:00
wangxiaolei
49a92f096f perf: make command rbac-migrate-member-roles use less mem and make it… (#38151) 2026-06-29 12:42:10 +00:00
非法操作
fa1ac75922 fix: editor can view the logs (#38165) 2026-06-29 10:05:32 +00:00
林玮 (Jade Lin)
cb35c6fa98 perf(api): retrieve published workflows via app.workflow_id (#38153) 2026-06-29 09:51:21 +00:00
非法操作
34f62e7df6 fix: editor should not query billing subscriptions (#38157) 2026-06-29 09:45:54 +00:00
shiyuanfang2nd
07b5dcbb19 fix(vdb): remove deprecated SQL options for ADB-PG 7.0 compatibility (#38004) 2026-06-29 09:30:01 +00:00
非法操作
23917c7b3e fix: agent app log detail modal not display well (#38014) 2026-06-29 09:29:35 +00:00
Blackoutta
8a6ce28855 fix: multimodal segment attachment indexing (#38080) 2026-06-29 09:18:29 +00:00
Xiyuan Chen
0d5f43520c fix(api): wire dedicated timeout into inner RBAC requests (#38150) 2026-06-29 07:03:50 +00:00
linhongkuan
d8f3be4bcd fix(api): isolate side-effect database writes (#37895)
Co-authored-by: FFXN <31929997+FFXN@users.noreply.github.com>
2026-06-29 06:20:34 +00:00
yyh
fc16fcba36 fix(web): align web app nav item width (#38146) 2026-06-29 06:18:19 +00:00
FFXN
ca2755e0c1 feat: refine snippet siderbar and support RBAC. (#38134)
Co-authored-by: JzoNg <jzongcode@gmail.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-06-29 06:03:40 +00:00
Wu Tianwei
d2216fe181 fix: support Unicode characters in form field names (#38138)
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-06-29 05:00:49 +00:00
Stephen Zhou
0d2084494e chore: downgrade openapi-ts (#38141) 2026-06-29 04:18:24 +00:00
Stephen Zhou
358cf8be33 chore: update deps (#38128) 2026-06-29 02:41:30 +00:00
wangxiaolei
93d6506443 fix: CAN_REPLACE_LOGO should be false (#38126) 2026-06-29 01:52:58 +00:00
yyh
77d624e7a4 fix(web): improve main nav focus outline (#38114) 2026-06-29 01:11:37 +00:00
yyh
9d3ac1b7b3 fix: simplify scroll area composition (#38113) 2026-06-29 01:05:12 +00:00
Yunlu Wen
7a111c2226 refactor: shell provider protocol (#38077)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-06-28 08:23:13 +00:00
yyh
7bb94cb6fe fix: gate deployments in route layout (#38078) 2026-06-27 13:35:37 +00:00
yyh
484633d261 fix: prevent exiting toasts from blocking page clicks (#38063) 2026-06-27 07:35:25 +00:00
Stephen Zhou
a14310fc62 refactor(web): organize deployment feature state (#38065)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
2026-06-27 07:34:46 +00:00
Byron.wang
8218694691 fix: improve workflow run archive idempotency and batching (#38027) 2026-06-27 11:09:57 +08:00
yyh
17bee5fb32 fix: improve members role chip accessibility (#38037) 2026-06-26 18:40:03 +00:00
yyh
446b3962c1 fix: remove aria-busy from loading button (#38036) 2026-06-26 18:39:42 +00:00
github-actions[bot]
00b4cdc68e chore(i18n): sync translations with en-US (#38035)
Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
2026-06-26 13:54:30 +00:00
Dx.
449b46b863 fix(web): download markdown file-preview links as attachments (#38030) 2026-06-26 13:46:44 +00:00
Asuka Minato
8d09b32cd5 chore: inject session (#37941)
Co-authored-by: WH-2099 <wh2099@pm.me>
2026-06-26 13:42:47 +00:00
盐粒 Yanli
52c106b532 feat(agent-v2): sync nightly updates to main (2026-06-25) (#37915)
Co-authored-by: Joel <iamjoel007@gmail.com>
Co-authored-by: yyh <yuanyouhuilyz@gmail.com>
Co-authored-by: Yansong Zhang <916125788@qq.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-06-26 13:13:35 +00:00
Harsh Kashyap
5b8679468d docs(web): fix testing guide link (#38006)
Co-authored-by: Harsh Kashyap <Harsh23Kashyap@users.noreply.github.com>
2026-06-26 12:50:12 +00:00
Evan
4fbfedd287 refactor: replace patch logger with caplog in test_version.py (#38029) 2026-06-26 12:07:44 +00:00
Cyber
051f4b32e3 feat(web): add customizable input placeholder for Agent/Chatflow/Chatbot web app (#37790)
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
Co-authored-by: yyh <92089059+lyzno1@users.noreply.github.com>
Co-authored-by: yyh <yuanyouhuilyz@gmail.com>
Co-authored-by: hjlarry <hjlarry@163.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-06-26 09:57:31 +00:00
非法操作
e22fd9efd6 fix: plugin installation task popover layout when some failed too long (#38000) 2026-06-26 09:36:36 +00:00
Coding On Star
35eeb743d1 fix(web): capture blog UTM/slug attribution reliably under CSP (#38022)
Co-authored-by: CodingOnStar <hanxujiang@dify.com>
2026-06-26 08:35:43 +00:00
林玮 (Jade Lin)
1dbda1463e feat(api): cache workflow provider configurations (#37980) 2026-06-26 08:04:37 +00:00
Mr_xie
3f2ef24755 refactor: pass db session into service calls (#37403) (#38016)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-06-26 07:53:27 +00:00
Escape0707
eb4ec93cea chore: migrate account role test to testcontainers (#38010) 2026-06-26 05:51:14 +00:00
Xiyuan Chen
fa6f4b0ea5 refactor(api): enforce enums over string literals on openapi surface (#38009) 2026-06-26 05:48:21 +00:00
Manan Bansal
267b34caaf fix(web): keep HITL input-field save button visible in the edit dialog (#38007)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-26 05:40:51 +00:00
yyh
6ab1dd06ac fix: isolate node selector keyboard events (#37998) 2026-06-26 05:38:10 +00:00
Stephen Zhou
113d6d7e00 refactor: align deployment detail state ownership (#38008) 2026-06-26 05:37:21 +00:00
Mohammed Aqib
a66b1de477 refactor: Use pytest caplog instead of logger patching in test_spec.py (#37997)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-06-26 04:48:22 +00:00
Stephen Zhou
16b698b54d refactor: simplify deployment access ownership (#37994) 2026-06-26 04:10:56 +00:00
yyh
4cd8b8c733 fix(web): make marketplace URL builder SSR-safe (#37944) 2026-06-26 03:35:22 +00:00
akou
677ab01806 refactor(tests): use caplog in workflow collaboration service tests (#37468) (#37991)
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 03:14:06 +00:00
Stephen Zhou
f4e832f35c fix: decouple deployment access control dialog (#37936) 2026-06-26 02:16:29 +00:00
kurokobo
1c5e1280cb feat(webapp): display app description on chat and text-generation app screens (#37345)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-06-26 02:03:16 +00:00
-LAN-
0035d90e36 fix(api): require edit access for trace config changes (#37973)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-06-26 00:51:39 +00:00
Xiyuan Chen
2047e0dc12 fix(cli): use a(n) article in difyctl prerelease warning (#37976) 2026-06-26 00:49:42 +00:00
chariri
2e9c0a3c7a refactor(api): migrate response contract tooling to BaseModel (#37950) 2026-06-26 00:11:04 +00:00
ojasarora.eth
a246dc8b17 ci: emit pyrefly diagnostics as GitHub workflow commands (#37974) 2026-06-25 18:27:46 +00:00
ojasarora.eth
bb921bcc45 test: replace logger mock with caplog in workflow collaboration test (#37971) 2026-06-25 16:45:59 +00:00
QuantumGhost
4f4ac27de2 chore(api): surface pyrefly output on type-check failures (#37934) 2026-06-25 13:47:10 +00:00
14374 changed files with 1226312 additions and 875592 deletions

View File

@@ -1,168 +1,40 @@
---
name: backend-code-review
description: Review backend code for quality, security, maintainability, and best practices based on established checklist rules. Use when the user requests a review, analysis, or improvement of backend files (e.g., `.py`) under the `api/` directory. Do NOT use for frontend files (e.g., `.tsx`, `.ts`, `.js`). Supports pending-change review, code snippets review, and file-focused review.
description: Use only when the user explicitly requests a review or audit of backend code under `api/`. Supports pending-change, file-focused, and pasted-diff reviews. Do not use for implementation-only requests, diagnosis without review intent, frontend code, or backend code outside `api/`.
---
# Backend Code Review
## When to use this skill
Review the requested scope for concrete, reproducible defects. The nearest `AGENTS.md` owns package facts and commands; this skill owns the review workflow and routes to its bundled rule packs.
Use this skill whenever the user asks to **review, analyze, or improve** backend code (e.g., `.py`) under the `api/` directory. Supports the following review modes:
## Evidence First
- **Pending-change review**: when the user asks to review current changes (inspect staged/working-tree files slated for commit to get the changes).
- **Code snippets review**: when the user pastes code snippets (e.g., a function/class/module excerpt) into the chat and asks for a review.
- **File-focused review**: when the user points to specific files and asks for a review of those files (one file or a small, explicit set of files, e.g., `api/...`, `api/app.py`).
1. Establish the requested review scope and inspect the relevant diff or files.
2. Read the changed lines, their behavior owner, nearby tests, and local docstrings or comments that define contracts.
3. Trace callers, persistence boundaries, authorization, generated schemas, or external I/O only when they decide correctness.
4. Report only findings tied to an observable failure, violated contract, security boundary, data integrity risk, or demonstrated maintenance problem.
Do NOT use this skill when:
## Rule Routing
- The request is about frontend code or UI (e.g., `.tsx`, `.ts`, `.js`, `web/`).
- The user is not asking for a review/analysis/improvement of backend code.
- The scope is not under `api/` (unless the user explicitly asks to review backend-related changes outside `api/`).
Read only the packs matched by the diff:
## How to use this skill
- Models or migrations: [`references/db-schema-rule.md`][db-schema]
- Controller, service, core/domain, library, or model dependency direction: [`references/architecture-rule.md`][architecture]
- Table access outside an established repository boundary: [`references/repositories-rule.md`][repositories]
- SQLAlchemy sessions, queries, transactions, CRUD, concurrency, or raw SQL: [`references/sqlalchemy-rule.md`][sqlalchemy]
Follow these steps when using this skill:
When no pack applies, review correctness, security, behavior changes, and test evidence directly. Check current official documentation only when local code and contracts do not settle framework or library behavior.
1. **Identify the review mode** (pending-change vs snippet vs file-focused) based on the user’s input. Keep the scope tight: review only what the user provided or explicitly referenced.
2. Follow the rules defined in **Checklist** to perform the review. If no Checklist rule matches, apply **General Review Rules** as a fallback to perform the best-effort review.
3. Compose the final output strictly follow the **Required Output Format**.
## Severity And Output
Notes when using this skill:
- Always include actionable fixes or suggestions (including possible code snippets).
- Use best-effort `File:Line` references when a file path and line numbers are available; otherwise, use the most specific identifier you can.
- **P0**: security or privacy exposure, data loss, or a production-wide outage.
- **P1**: user-visible regression, broken authorization or tenant isolation, invalid public contract, or failed primary workflow.
- **P2**: concrete correctness, performance, maintainability, or test defect likely to cause incorrect behavior.
- **P3**: minor actionable cleanup; omit unless the user requested a thorough audit.
## Checklist
Lead with findings ordered by severity. Include a tight file and line reference, the failing contract or reproduction path, impact, and a concrete fix direction. If there are no findings, say `No issues found.` and state any material verification gap. Do not add praise sections, speculative risks, or an unsolicited offer to implement fixes.
- db schema design: if the review scope includes code/files under `api/models/` or `api/migrations/`, follow [references/db-schema-rule.md](references/db-schema-rule.md) to perform the review
- architecture: if the review scope involves controller/service/core-domain/libs/model layering, dependency direction, or moving responsibilities across modules, follow [references/architecture-rule.md](references/architecture-rule.md) to perform the review
- repositories abstraction: if the review scope contains table/model operations (e.g., `select(...)`, `session.execute(...)`, joins, CRUD) and is not under `api/repositories`, `api/core/repositories`, or `api/extensions/*/repositories/`, follow [references/repositories-rule.md](references/repositories-rule.md) to perform the review
- sqlalchemy patterns: if the review scope involves SQLAlchemy session/query usage, db transaction/crud usage, or raw SQL usage, follow [references/sqlalchemy-rule.md](references/sqlalchemy-rule.md) to perform the review
## General Review Rules
### 1. Security Review
Check for:
- SQL injection vulnerabilities
- Server-Side Request Forgery (SSRF)
- Command injection
- Insecure deserialization
- Hardcoded secrets/credentials
- Improper authentication/authorization
- Insecure direct object references
### 2. Performance Review
Check for:
- N+1 queries
- Missing database indexes
- Memory leaks
- Blocking operations in async code
- Missing caching opportunities
### 3. Code Quality Review
Check for:
- Code forward compatibility
- Code duplication (DRY violations)
- Functions doing too much (SRP violations)
- Deep nesting / complex conditionals
- Magic numbers/strings
- Poor naming
- Missing error handling
- Incomplete type coverage
### 4. Testing Review
Check for:
- Missing test coverage for new code
- Tests that don't test behavior
- Flaky test patterns
- Missing edge cases
## Required Output Format
When this skill invoked, the response must exactly follow one of the two templates:
### Template A (any findings)
```markdown
# Code Review Summary
Found <X> critical issues need to be fixed:
## 🔴 Critical (Must Fix)
### 1. <brief description of the issue>
FilePath: <path> line <line>
<relevant code snippet or pointer>
#### Explanation
<detailed explanation and references of the issue>
#### Suggested Fix
1. <brief description of suggested fix>
2. <code example> (optional, omit if not applicable)
---
... (repeat for each critical issue) ...
Found <Y> suggestions for improvement:
## 🟡 Suggestions (Should Consider)
### 1. <brief description of the suggestion>
FilePath: <path> line <line>
<relevant code snippet or pointer>
#### Explanation
<detailed explanation and references of the suggestion>
#### Suggested Fix
1. <brief description of suggested fix>
2. <code example> (optional, omit if not applicable)
---
... (repeat for each suggestion) ...
Found <Z> optional nits:
## 🟢 Nits (Optional)
### 1. <brief description of the nit>
FilePath: <path> line <line>
<relevant code snippet or pointer>
#### Explanation
<explanation and references of the optional nit>
#### Suggested Fix
- <minor suggestions>
---
... (repeat for each nits) ...
## ✅ What's Good
- <Positive feedback on good patterns>
```
- If there are no critical issues or suggestions or option nits or good points, just omit that section.
- If the issue number is more than 10, summarize as "Found 10+ critical issues/suggestions/optional nits" and only output the first 10 items.
- Don't compress the blank lines between sections; keep them as-is for readability.
- If there is any issue requires code changes, append a brief follow-up question to ask whether the user wants to apply the fix(es) after the structured output. For example: "Would you like me to use the Suggested fix(es) to address these issues?"
### Template B (no issues)
```markdown
## Code Review Summary
✅ No issues found.
```
[architecture]: references/architecture-rule.md
[db-schema]: references/db-schema-rule.md
[repositories]: references/repositories-rule.md
[sqlalchemy]: references/sqlalchemy-rule.md

View File

@@ -1,91 +1,15 @@
# Rule Catalog — Architecture
# Architecture review
## Scope
- Covers: controller/service/core-domain/libs/model layering, dependency direction, responsibility placement, observability-friendly flow.
The [API agent guide](../../../../api/AGENTS.md) owns package boundaries. In particular, `api/core/` is migration-only: do not propose new files or extracted implementations there.
## Rules
## Transport and domain boundaries
### Keep business logic out of controllers
- Category: maintainability
- Severity: critical
- Description: Controllers should parse input, call services, and return serialized responses. Business decisions inside controllers make behavior hard to reuse and test.
- Suggested fix: Move domain/business logic into the service or core/domain layer. Keep controller handlers thin and orchestration-focused.
- Example:
- Bad:
```python
@bp.post("/apps/<app_id>/publish")
def publish_app(app_id: str):
payload = request.get_json() or {}
if payload.get("force") and current_user.role != "admin":
raise ValueError("only admin can force publish")
app = App.query.get(app_id)
app.status = "published"
db.session.commit()
return {"result": "ok"}
```
- Good:
```python
@bp.post("/apps/<app_id>/publish")
def publish_app(app_id: str):
payload = PublishRequest.model_validate(request.get_json() or {})
app_service.publish_app(app_id=app_id, force=payload.force, actor_id=current_user.id)
return {"result": "ok"}
```
Controllers own request parsing, service calls, and response serialization. Trace business decisions to their service or domain owner; flag controller policy when it duplicates or bypasses that owner. Move extracted behavior to an appropriate owner outside `core/`.
### Preserve layer dependency direction
- Category: best practices
- Severity: critical
- Description: Controllers may depend on services, and services may depend on core/domain abstractions. Reversing this direction (for example, core importing controller/web modules) creates cycles and leaks transport concerns into domain code.
- Suggested fix: Extract shared contracts into core/domain or service-level modules and make upper layers depend on lower, not the reverse.
- Example:
- Bad:
```python
# core/policy/publish_policy.py
from controllers.console.app import request_context
## Dependency direction
def can_publish() -> bool:
return request_context.current_user.is_admin
```
- Good:
```python
# core/policy/publish_policy.py
def can_publish(role: str) -> bool:
return role == "admin"
Transport layers may depend on services and domain contracts. Domain code must not import controller or request context. Pass validated actor, tenant, and resource data explicitly instead of reaching upward for it. Check existing owners and import-linter contracts before proposing a shared abstraction.
# service layer adapts web/user context to domain input
allowed = can_publish(role=current_user.role)
```
## Business-agnostic libraries
### Keep libs business-agnostic
- Category: maintainability
- Severity: critical
- Description: Modules under `api/libs/` should remain reusable, business-agnostic building blocks. They must not encode product/domain-specific rules, workflow orchestration, or business decisions.
- Suggested fix:
- If business logic appears in `api/libs/`, extract it into the appropriate `services/` or `core/` module and keep `libs` focused on generic, cross-cutting helpers.
- Keep `libs` dependencies clean: avoid importing service/controller/domain-specific modules into `api/libs/`.
- Example:
- Bad:
```python
# api/libs/conversation_filter.py
from services.conversation_service import ConversationService
def should_archive_conversation(conversation, tenant_id: str) -> bool:
# Domain policy and service dependency are leaking into libs.
service = ConversationService()
if service.has_paid_plan(tenant_id):
return conversation.idle_days > 90
return conversation.idle_days > 30
```
- Good:
```python
# api/libs/datetime_utils.py (business-agnostic helper)
def older_than_days(idle_days: int, threshold_days: int) -> bool:
return idle_days > threshold_days
# services/conversation_service.py (business logic stays in service/core)
from libs.datetime_utils import older_than_days
def should_archive_conversation(conversation, tenant_id: str) -> bool:
threshold_days = 90 if has_paid_plan(tenant_id) else 30
return older_than_days(conversation.idle_days, threshold_days)
```
`api/libs/` must not own product policy or orchestration. Flag service/controller dependencies and domain-specific decisions in library helpers. Move that behavior to its existing service or domain owner outside `core/`; retain only reusable infrastructure in `libs/`.

View File

@@ -8,7 +8,6 @@
### Do not query other tables inside `@property`
- Category: [maintainability, performance]
- Severity: critical
- Description: A model `@property` must not open sessions or query other tables. This hides dependencies across models, tightly couples schema objects to data access, and can cause N+1 query explosions when iterating collections.
- Suggested fix:
- Keep model properties pure and local to already-loaded fields.
@@ -41,7 +40,6 @@
### Prefer including `tenant_id` in model definitions
- Category: maintainability
- Severity: suggestion
- Description: In multi-tenant domains, include `tenant_id` in schema definitions whenever the entity belongs to tenant-owned data. This improves data isolation safety and keeps future partitioning/sharding strategies practical as data volume grows.
- Suggested fix:
- Add a `tenant_id` column and ensure related unique/index constraints include tenant dimension when applicable.
@@ -52,6 +50,7 @@
```python
from sqlalchemy.orm import Mapped
class Dataset(TypeBase):
__tablename__ = "datasets"
id: Mapped[str] = mapped_column(StringUUID, primary_key=True)
@@ -61,6 +60,7 @@
```python
from sqlalchemy.orm import Mapped
class Dataset(TypeBase):
__tablename__ = "datasets"
id: Mapped[str] = mapped_column(StringUUID, primary_key=True)
@@ -70,7 +70,6 @@
### Detect and avoid duplicate/redundant indexes
- Category: performance
- Severity: suggestion
- Description: Review index definitions for leftmost-prefix redundancy. For example, index `(a, b, c)` can safely cover most lookups for `(a, b)`. Keeping both may increase write overhead and can mislead the optimizer into suboptimal execution plans.
- Suggested fix:
- Before adding an index, compare against existing composite indexes by leftmost-prefix rules.
@@ -94,7 +93,6 @@
### Avoid PostgreSQL-only dialect usage in models; wrap in `models.types`
- Category: maintainability
- Severity: critical
- Description: Model/schema definitions should avoid PostgreSQL-only constructs directly in business models. When database-specific behavior is required, encapsulate it in `api/models/types.py` using both PostgreSQL and MySQL dialect implementations, then consume that abstraction from model code.
- Suggested fix:
- Do not directly place dialect-only types/operators in model columns when a portable wrapper can be used.
@@ -105,6 +103,7 @@
from sqlalchemy.dialects.postgresql import JSONB
from sqlalchemy.orm import Mapped
class ToolConfig(TypeBase):
__tablename__ = "tool_configs"
config: Mapped[dict] = mapped_column(JSONB, nullable=False)
@@ -115,6 +114,7 @@
from models.types import AdjustedJSON
class ToolConfig(TypeBase):
__tablename__ = "tool_configs"
config: Mapped[dict] = mapped_column(AdjustedJSON(), nullable=False)
@@ -122,7 +122,6 @@
### Guard migration incompatibilities with dialect checks and shared types
- Category: maintainability
- Severity: critical
- Description: Migration scripts under `api/migrations/versions/` must account for PostgreSQL/MySQL incompatibilities explicitly. For dialect-sensitive DDL or defaults, branch on the active dialect (for example, `conn.dialect.name == "postgresql"`), and prefer reusable compatibility abstractions from `models.types` where applicable.
- Suggested fix:
- In migration upgrades/downgrades, bind connection and branch by dialect for incompatible SQL fragments.
@@ -151,7 +150,5 @@
default_expr = sa.text("'database'::character varying") if _is_pg(conn) else sa.text("'database'")
with op.batch_alter_table("dataset_keyword_tables") as batch_op:
batch_op.add_column(
sa.Column("data_source_type", sa.String(255), server_default=default_expr, nullable=False)
)
batch_op.add_column(sa.Column("data_source_type", sa.String(255), server_default=default_expr, nullable=False))
```

View File

@@ -8,20 +8,17 @@
### Introduce repositories abstraction
- Category: maintainability
- Severity: suggestion
- Description: If a table/model already has a repository abstraction, all reads/writes/queries for that table should use the existing repository. If no repository exists, introduce one only when complexity justifies it, such as large/high-volume tables, repeated complex query logic, or likely storage-strategy variation.
- Suggested fix:
- First check `api/repositories`, `api/core/repositories`, and `api/extensions/*/repositories/` to verify whether the table/model already has a repository abstraction. If it exists, route all operations through it and add missing repository methods instead of bypassing it with ad-hoc SQLAlchemy access.
- If no repository exists, add one only when complexity warrants it (for example, repeated complex queries, large data domains, or multiple storage strategies), while preserving dependency direction (service/core depends on abstraction; infra provides implementation).
- If no repository exists, add one only when complexity warrants it (for example, repeated complex queries, large data domains, or multiple storage strategies). Follow `api/AGENTS.md`: put new abstractions and implementations outside migration-only `api/core/`, with services/domain code depending on abstractions and infrastructure providing implementations.
- Example:
- Bad:
```python
# Existing repository is ignored and service uses ad-hoc table queries.
class AppService:
def archive_app(self, app_id: str, tenant_id: str) -> None:
app = self.session.execute(
select(App).where(App.id == app_id, App.tenant_id == tenant_id)
).scalar_one()
app = self.session.execute(select(App).where(App.id == app_id, App.tenant_id == tenant_id)).scalar_one()
app.archived = True
self.session.commit()
```
@@ -34,6 +31,7 @@
app.archived = True
self.app_repo.save(app)
# If the query is missing, extend the existing abstraction.
active_apps = self.app_repo.list_active_for_tenant(tenant_id=tenant_id)
```
@@ -51,9 +49,10 @@
class ConversationRepository(Protocol):
def list_recent_for_app(self, app_id: str, tenant_id: str, limit: int) -> list[Conversation]: ...
class SqlAlchemyConversationRepository:
def list_recent_for_app(self, app_id: str, tenant_id: str, limit: int) -> list[Conversation]:
...
def list_recent_for_app(self, app_id: str, tenant_id: str, limit: int) -> list[Conversation]: ...
class ConversationService:
def __init__(self, conversation_repo: ConversationRepository):

View File

@@ -8,7 +8,6 @@
### Use Session context manager with explicit transaction control behavior
- Category: best practices
- Severity: critical
- Description: Session and transaction lifecycle must be explicit and bounded on write paths. Missing commits can silently drop intended updates, while ad-hoc or long-lived transactions increase contention, lock duration, and deadlock risk.
- Suggested fix:
- Use **explicit `session.commit()`** after completing a related write unit.
@@ -47,7 +46,6 @@
### Enforce tenant_id scoping on shared-resource queries
- Category: security
- Severity: critical
- Description: Reads and writes against shared tables must be scoped by `tenant_id` to prevent cross-tenant data leakage or corruption.
- Suggested fix: Add `tenant_id` predicate to all tenant-owned entity queries and propagate tenant context through service/repository interfaces.
- Example:
@@ -67,7 +65,6 @@
### Prefer SQLAlchemy expressions over raw SQL by default
- Category: maintainability
- Severity: suggestion
- Description: Raw SQL should be exceptional. ORM/Core expressions are easier to evolve, safer to compose, and more consistent with the codebase.
- Suggested fix: Rewrite straightforward raw SQL into SQLAlchemy `select/update/delete` expressions; keep raw SQL only when required by clear technical constraints.
- Example:
@@ -89,7 +86,6 @@
### Protect write paths with concurrency safeguards
- Category: quality
- Severity: critical
- Description: Multi-writer paths without explicit concurrency control can silently overwrite data. Choose the safeguard based on contention level, lock scope, and throughput cost instead of defaulting to one strategy.
- Suggested fix:
- **Optimistic locking**: Use when contention is usually low and retries are acceptable. Add a version (or updated_at) guard in `WHERE` and treat `rowcount == 0` as a conflict.
@@ -130,10 +126,8 @@
# 3) Pessimistic lock with SELECT ... FOR UPDATE (high contention)
run = session.execute(
select(WorkflowRun)
.where(WorkflowRun.id == run_id, WorkflowRun.tenant_id == tenant_id)
.with_for_update()
select(WorkflowRun).where(WorkflowRun.id == run_id, WorkflowRun.tenant_id == tenant_id).with_for_update()
).scalar_one()
run.status = "cancelled"
session.commit()
```
```

View File

@@ -1,79 +1,33 @@
---
name: e2e-cucumber-playwright
description: Write, update, or review Dify end-to-end tests under `e2e/` that use Cucumber, Gherkin, and Playwright. Use when the task involves `.feature` files, `features/step-definitions/`, `features/support/`, `DifyWorld`, scenario tags, locator/assertion choices, or E2E testing best practices for this repository.
description: Use when writing, changing, or reviewing Cucumber and Playwright tests under `e2e/`, including feature files, step definitions, support code, scenario tags, locators, and assertions. Do not use for Vitest, React Testing Library, backend tests, or generic browser automation outside the E2E suite.
---
# Dify E2E Cucumber + Playwright
# E2E Cucumber And Playwright
Use this skill for Dify's repository-level E2E suite in `e2e/`. Use [`e2e/AGENTS.md`](../../../e2e/AGENTS.md) as the canonical guide for local architecture and conventions, then apply Playwright/Cucumber best practices only where they fit the current suite.
`e2e/AGENTS.md` owns the suite architecture, lifecycle, commands, tags, generated-client boundaries, fixtures, and cleanup contracts. Read the nearest feature-scoped `AGENTS.md` when one exists. This skill adds no parallel package policy.
## Scope
Cucumber owns scenario and hook execution and reporting. Playwright provides browser automation, contexts, pages, locators, actions, assertions, request, and tracing APIs; protocol exceptions remain with the package-defined owner. Their timeout domains remain separate, and importing from `@playwright/test` does not make Playwright Test runner configuration, fixtures, or retries applicable to this suite.
- Use this skill for `.feature` files, Cucumber step definitions, `DifyWorld`, hooks, tags, and E2E review work under `e2e/`.
- Do not use this skill for Vitest or React Testing Library work under `web/`; use `frontend-testing` instead.
- Do not use this skill for backend test or API review tasks under `api/`.
## Topic Routing
## Read Order
Read only the bundled reference required by the change:
1. Read [`e2e/AGENTS.md`](../../../e2e/AGENTS.md) first.
2. Read only the files directly involved in the task:
- target `.feature` files under `e2e/features/`
- related step files under `e2e/features/step-definitions/`
- `e2e/features/support/hooks.ts` and `e2e/features/support/world.ts` when session lifecycle or shared state matters
- `e2e/scripts/run-cucumber.ts` and `e2e/cucumber.config.ts` when tags or execution flow matter
3. Read [`references/playwright-best-practices.md`](references/playwright-best-practices.md) only when locator, assertion, isolation, or waiting choices are involved.
4. Read [`references/cucumber-best-practices.md`](references/cucumber-best-practices.md) only when scenario wording, step granularity, tags, or expression design are involved.
5. Re-check official Playwright or Cucumber docs with the available documentation tools before introducing a new framework pattern.
- Locator, assertion, isolation, or waiting decisions: [`references/playwright-best-practices.md`][playwright]
- Scenario wording, step granularity, expressions, World state, hook visibility, or tag design: [`references/cucumber-best-practices.md`][cucumber]
## Local Rules
- `e2e/` uses Cucumber for scenarios and Playwright as the browser layer.
- `DifyWorld` is the per-scenario context object. Type `this` as `DifyWorld` and use `async function`, not arrow functions.
- Keep glue organized by capability under `e2e/features/step-definitions/`; use `common/` only for broadly reusable steps.
- Browser session behavior comes from `features/support/hooks.ts`:
- default: authenticated session with shared storage state
- `@unauthenticated`: clean browser context
- `@authenticated`: readability/selective-run tag only unless implementation changes
- `@fresh`: only for `e2e:full*` flows
- Do not import Playwright Test runner patterns that bypass the current Cucumber + `DifyWorld` architecture unless the task is explicitly about changing that architecture.
Check current official Playwright or Cucumber documentation before introducing a framework pattern that local code and references do not already establish.
## Workflow
1. Rebuild local context.
- Inspect the target feature area.
- Reuse an existing step when wording and behavior already match.
- Add a new step only for a genuinely new user action or assertion.
- Keep edits close to the current capability folder unless the step is broadly reusable.
2. Write behavior-first scenarios.
- Describe user-observable behavior, not DOM mechanics.
- Keep each scenario focused on one workflow or outcome.
- Keep scenarios independent and re-runnable.
3. Write step definitions in the local style.
- Keep one step to one user-visible action or one assertion.
- Prefer Cucumber Expressions such as `{string}` and `{int}`.
- Scope locators to stable containers when the page has repeated elements.
- Avoid page-object layers or extra helper abstractions unless repeated complexity clearly justifies them.
4. Use Playwright in the local style.
- Prefer user-facing locators: `getByRole`, `getByLabel`, `getByPlaceholder`, `getByText`, then `getByTestId` for explicit contracts.
- Use web-first `expect(...)` assertions.
- Do not use `waitForTimeout`, manual polling, or raw visibility checks when a locator action or retrying assertion already expresses the behavior.
5. Validate narrowly.
- Run the narrowest tagged scenario or flow that exercises the change.
- Run `pnpm -C e2e check`.
- Broaden verification only when the change affects hooks, tags, setup, or shared step semantics.
1. Add E2E coverage only for a critical user journey with a cross-boundary outcome that cheaper owner-level tests do not already prove.
2. Identify the user-visible behavior and its feature owner. Start from real product defaults and actor roles; setup may establish preconditions but must not manufacture the opposite state to make the scenario meaningful.
3. Read the target scenario, matching step definitions, and lifecycle files only when session or shared state matters.
4. Reuse an existing step when wording and behavior match; add one coherent scenario or step when they do not.
5. Keep browser actions and assertions at the public user boundary; keep setup, seed, polling, and cleanup at their package-defined owners.
6. For changes, run the narrowest tagged scenario and package checks documented in `e2e/AGENTS.md`; broaden only for shared hooks, tags, or support changes.
## Review Checklist
For review requests, lead with reproducible correctness failures, flake sources, or demonstrated architecture drift. Report the behavior verified and any external-runtime, browser, or environment gap.
- Does the scenario describe behavior rather than implementation?
- Does it fit the current session model, tags, and `DifyWorld` usage?
- Should an existing step be reused instead of adding a new one?
- Are locators user-facing and assertions web-first?
- Does the change introduce hidden coupling across scenarios, tags, or instance state?
- Does it document or implement behavior that differs from the real hooks or configuration?
Lead findings with correctness, flake risk, and architecture drift.
## References
- [`references/playwright-best-practices.md`](references/playwright-best-practices.md)
- [`references/cucumber-best-practices.md`](references/cucumber-best-practices.md)
[cucumber]: references/cucumber-best-practices.md
[playwright]: references/playwright-best-practices.md

View File

@@ -1,18 +1,21 @@
# Cucumber Best Practices For Dify E2E
# Cucumber Best Practices
Use this reference when writing or reviewing Gherkin scenarios, step definitions, parameter expressions, and step reuse in Dify's `e2e/` suite.
Use this reference when writing or reviewing Gherkin scenarios, step definitions, parameter expressions, and step reuse.
Official sources:
- https://cucumber.io/docs/guides/10-minute-tutorial/
- https://cucumber.io/docs/cucumber/step-definitions/
- https://cucumber.io/docs/cucumber/cucumber-expressions/
- https://cucumber.io/docs/bdd/better-gherkin
- https://cucumber.io/docs/gherkin/reference
- https://cucumber.io/docs/gherkin/step-organization
- https://cucumber.io/docs/cucumber/state
- https://cucumber.io/docs/cucumber/cucumber-expressions
- https://github.com/cucumber/cucumber-js/blob/main/docs/support_files/world.md
## What Matters Most
### 1. Treat scenarios as executable specifications
Cucumber scenarios should describe examples of behavior, not test implementation recipes.
Cucumber scenarios should usually describe behavior declaratively, not reproduce an interaction script.
Apply it like this:
@@ -20,15 +23,15 @@ Apply it like this:
- avoid UI-internal wording such as selector details, DOM structure, or component names
- keep language concrete enough that the scenario reads like living documentation
Procedural detail is appropriate when the interaction mechanism is the behavior under test, such as keyboard navigation, focus movement, or a required multi-actor sequence.
### 2. Keep scenarios focused
A scenario should usually prove one workflow or business outcome. If a scenario wanders across several unrelated behaviors, split it.
A scenario should prove one business rule or coherent outcome. Cucumber's three-to-five-step recommendation is a review heuristic, not a hard limit: when a scenario is longer, check for multiple outcomes, incidental setup, or UI procedure that can move behind a domain step.
In Dify's suite, this means:
Use `Given` for initial context, `When` for the event, and `Then` for the expected outcome. Restarting those phases is a prompt to review the narrative, not an automatic failure. Avoid hidden dependencies on another scenario's side effects.
- one capability-focused scenario per feature path
- no long setup chains when existing bootstrap or reusable steps already cover them
- no hidden dependency on another scenario's side effects
Use `Rule` when several examples illustrate one named business rule. Use a short `Background` only for shared context the reader needs to understand; do not hide fixture preparation, runtime readiness, or long setup there.
### 3. Reuse steps, but only when behavior really matches
@@ -39,6 +42,7 @@ Prefer reuse when:
- the user action is genuinely the same
- the expected outcome is genuinely the same
- the wording stays natural across features
- the parameter is a real product domain value such as a named surface, mode, resource, or status
Write a new step when:
@@ -46,6 +50,10 @@ Write a new step when:
- reusing the old wording would make the scenario misleading
- a supposedly generic step would become an implementation-detail wrapper
Do not optimize for a low step count by making vague steps. Optimize for a small set of truthful, domain-owned steps.
Step definitions share one global matching namespace regardless of their directory. Organize them by domain capability and avoid feature-coupled glue or expressions broad enough to overlap unrelated behavior.
### 4. Prefer Cucumber Expressions
Use Cucumber Expressions for parameters unless regex is clearly necessary.
@@ -59,35 +67,28 @@ Common examples:
Keep expressions readable. If a step needs complicated parsing logic, first ask whether the scenario wording should be simpler.
Use regex for a bounded natural-language alternative only when it keeps Gherkin readable, for example `/(Web app|Backend service API)/`. Avoid broad regexes that accept unowned language.
### 5. Keep step definitions thin and meaningful
Step definitions are glue between Gherkin and automation, not a second abstraction language.
Step definitions are glue between Gherkin and automation, not a second abstraction language. A step should express one coherent domain action or outcome; it may call several implementation helpers when that keeps UI mechanics out of the specification.
For Dify:
Cucumber creates a new World for each scenario. Keep scenario state there rather than in module globals. Cucumber.js supports a `world` proxy for arrow functions, but this suite consistently uses typed `async function (this: DifyWorld, ...)` so ownership and TypeScript discovery remain explicit.
- type `this` as `DifyWorld`
- use `async function`
- keep each step to one user-visible action or assertion
- rely on `DifyWorld` and existing support code for shared context
- avoid leaking cross-scenario state
Hooks are invisible to feature readers. Keep them for low-level browser lifecycle, cleanup, and diagnostics; express business-relevant context in Gherkin.
### 6. Use tags intentionally
Tags should communicate run scope or session semantics, not become ad hoc metadata.
In Dify's current suite:
- capability tags group related scenarios
- `@unauthenticated` changes session behavior
- `@authenticated` is descriptive/selective, not a behavior switch by itself
- `@fresh` belongs to reset/full-install flows only
If a proposed tag implies behavior, verify that hooks or runner configuration actually implement it.
Tags may communicate stable capability grouping, selection, fixture dependency, or conditional-hook intent. A tag changes runtime behavior only when a runner, seed profile, or hook owns that meaning.
## Review Questions
- Does the scenario read like a real example of product behavior?
- Does it prove one outcome, or combine several independent phases?
- Are the steps behavior-oriented instead of implementation-oriented?
- Is procedural wording necessary to the behavior being tested?
- Is a reused step still truthful in this feature?
- Could a new expression overlap an existing step in the global namespace?
- Would `Rule` clarify the business rule, or would `Background` hide important setup?
- Is a new tag documenting real behavior, or inventing semantics that the suite does not implement?
- Would a new reader understand the outcome without opening the step-definition file?

View File

@@ -1,48 +1,46 @@
# Playwright Best Practices For Dify E2E
# Playwright Best Practices
Use this reference when writing or reviewing locator, assertion, isolation, or synchronization logic for Dify's Cucumber-based E2E suite.
Use this reference when writing or reviewing locator, assertion, isolation, or synchronization logic.
Official sources:
- https://playwright.dev/docs/best-practices
- https://playwright.dev/docs/locators
- https://playwright.dev/docs/actionability
- https://playwright.dev/docs/test-assertions
- https://playwright.dev/docs/test-timeouts
- https://playwright.dev/docs/browser-contexts
- https://playwright.dev/docs/events
- https://playwright.dev/docs/trace-viewer
## What Matters Most
### 1. Keep scenarios isolated
Playwright's model is built around clean browser contexts so one test does not leak into another. In Dify's suite, that principle maps to per-scenario session setup in `features/support/hooks.ts` and `DifyWorld`.
Playwright's model is built around clean browser contexts so one test does not leak into another.
Apply it like this:
- do not depend on another scenario having run first
- do not persist ad hoc scenario state outside `DifyWorld`
- do not couple ordinary scenarios to `@fresh` behavior
- when a flow needs special auth/session semantics, express that through the existing tag model or explicit hook changes
- keep scenario state in the runner's scenario-owned context rather than module globals
- model special authentication or session setup through explicit per-scenario fixtures rather than shared mutable state
### 2. Prefer user-facing locators
### 2. Select locators by user contract
Playwright recommends built-in locators that reflect what users perceive on the page.
Prefer built-in locators that match how the target is exposed to users:
Preferred order in this repository:
- interactive controls: role and accessible name
- form controls: associated label; use placeholder when it is the relevant stable contract, especially when no label exists
- non-interactive content: visible text or the relevant text alternative
- elements without a meaningful user-facing contract: an intentional test id
1. `getByRole`
2. `getByLabel`
3. `getByPlaceholder`
4. `getByText`
5. `getByTestId` when an explicit test contract is the most stable option
This is a semantic choice, not a fixed ranking. Do not add incorrect roles or accessible names solely to satisfy a locator. When the product element should have user-facing semantics, fix that contract instead.
Avoid raw CSS/XPath selectors unless no stable user-facing contract exists and adding one is not practical.
Also remember:
Locators are strict for single-element actions. Scope to a stable region or use `filter({ has, hasText })` to make the intended target unique. Treat `.first()`, `.last()`, or `.nth()` as a review signal: the positional choice should be intentional and stable, not merely silence ambiguity.
- repeated content usually needs scoping to a stable container
- exact text matching is often too brittle when role/name or label already exists
- `getByTestId` is acceptable when semantics are weak but the contract is intentional
### 3. Use web-first assertions
### 3. Use web-first assertions with the right timeout owner
Playwright assertions auto-wait and retry. Prefer them over manual state inspection.
@@ -62,6 +60,10 @@ Avoid:
If a condition genuinely needs custom retry logic, use Playwright's polling/assertion tools deliberately and keep that choice local and explicit.
Use `expect.poll` for non-DOM truth such as API state, backend eventual consistency, generated resources, or captured browser events. For DOM state, use locator assertions so Playwright can apply actionability and web-first retry semantics.
Cucumber step and hook timeouts, Playwright locator/action timeouts, and Playwright assertion timeouts are separate budgets. `browserContext.setDefaultTimeout()` does not change the default five-second assertion timeout. Put an explicit longer assertion timeout only on the readiness owner that needs it; do not raise an outer timeout to mask a shorter inner failure.
### 4. Let actions wait for actionability
Locator actions already wait for the element to be actionable. Do not preface every click/fill with extra timing logic unless the action needs a specific visible/ready assertion for clarity.
@@ -75,22 +77,20 @@ Bad pattern:
- stack arbitrary waits before every action
- wait on unstable implementation details instead of the visible state the user cares about
- use `force: true` to bypass a real hit-target, overlay, or disabled-state failure
### 5. Match debugging to the current suite
When synchronizing on a one-shot popup, download, request, or response, create the wait before triggering the action, then await the event. A scenario-owned listener may instead capture events for a later assertion. Do not use `networkidle` as an application-readiness assertion; wait for the user-visible state or owned backend contract.
Playwright's wider ecosystem supports traces and rich debugging tools. Dify's current suite already captures:
### 5. Match debugging to the active harness
- full-page screenshots
- page HTML
- console errors
- page errors
Use the existing artifact flow by default. If a task is specifically about improving diagnostics, confirm the change fits the current Cucumber architecture before importing broader Playwright tooling.
Playwright supports traces, screenshots, page snapshots, and browser logs. Configure artifact capture in Cucumber hooks instead of adding parallel diagnostics to individual scenarios. If tracing is introduced, use `browserContext.tracing`; Playwright Test options such as `trace: 'on-first-retry'`, projects, workers, fixtures, reporters, and retries do not configure this harness.
## Review Questions
- Would this locator survive DOM refactors that do not change user-visible behavior?
- Is a positional locator expressing product order, or hiding an ambiguous match?
- Is this assertion using Playwright's retrying semantics?
- Is any explicit wait masking a real readiness problem?
- Does an explicit timeout belong to the condition that is actually slow?
- Was an event wait registered before the action that emits it?
- Does this code preserve per-scenario isolation?
- Is a new abstraction really needed, or does it bypass the existing `DifyWorld` + step-definition model?
- Is a new abstraction really needed, or does it bypass the runner's scenario-owned context and lifecycle?

View File

@@ -1,94 +1,48 @@
---
name: frontend-code-review
description: Review Dify frontend code for correctness, accessibility, component design, dify-ui usage, data/query boundaries, performance, and tests. Trigger for `.tsx`, `.ts`, `.js`, UI, React, Next.js, pending-change, or focused frontend review requests.
description: Use only when the user explicitly requests a review or audit of frontend code under `web/` or `packages/dify-ui/`. Supports pending-change, file-focused, and pasted-diff reviews. Do not use for implementation-only requests, diagnosis without review intent, or backend-only code.
---
# Frontend Code Review
## When To Use
Review the requested scope for concrete defects and violations of explicit project contracts. This skill owns review decisions; its references route to canonical rules without activating another skill's implementation workflow.
Use this skill when the user asks to review, audit, analyze, or sanity-check frontend code under `web/`, `packages/dify-ui/`, or frontend-adjacent TypeScript files.
## Evidence First
Supported modes:
1. Establish the review scope from the requested files or current diff.
2. Read the changed lines, their behavior owner, and the nearest scoped `AGENTS.md`.
3. Trace public consumers, generated contracts, primitive APIs, or runtime configuration only when they decide correctness.
4. Report findings tied to an observable failure, violated contract, security boundary, or demonstrated maintenance risk. Explicit team conventions are contracts: establish their scope and exceptions, and do not invent user impact to justify a convention finding.
- **Pending-change review**: inspect staged and working-tree changes.
- **File-focused review**: inspect explicitly named files or paths.
- **Diff/snippet review**: review pasted diffs or snippets using best-effort references.
## Rule Routing
Do not use this skill for backend-only code under `api/`; use `backend-code-review` instead.
Read only the packs matched by the diff:
## Required Context
- DOM semantics, focus, keyboard, forms, disabled state, or visible interaction: [`references/accessibility-ui.md`][accessibility]
- Dify UI imports, Base UI wrappers, overlays, tokens, or primitive contracts: [`references/dify-ui.md`][dify-ui]
- Component ownership, props, state, Effects, navigation, or module boundaries: [`references/component-architecture.md`][component-architecture]
- Generated clients, Query, mutations, auth, SSR, URL state, or persistence: [`references/data-query-contracts.md`][data-query]
- Test files or a concrete missing-regression-test finding: [`references/testing.md`][testing]
- Bundle, waterfall, rendering, or subscription cost supported by evidence: [`references/performance.md`][performance]
- Stable Dify runtime invariants in the named paths: [`references/dify-invariants.md`][dify-invariants]
- General TypeScript or styling quality not owned above: [`references/code-quality.md`][code-quality]
Before reviewing, read the relevant local contracts:
Read `packages/dify-ui/README.md`, `packages/dify-ui/AGENTS.md`, `packages/dify-ui/docs/overlays.md`, or `web/docs/test.md` only when the reviewed code falls under that contract. Check current official documentation when local code and bundled references do not settle a framework, browser, or accessibility behavior.
- `web/AGENTS.md` for Dify frontend workflow, overlays, design tokens, state, and tests.
- `packages/dify-ui/README.md` and `packages/dify-ui/AGENTS.md` when code uses or changes `@langgenius/dify-ui/*`.
- `web/docs/overlay.md` when reviewing dialogs, drawers, popovers, tooltips, menus, selects, comboboxes, or other floating UI.
- `web/docs/test.md` and the `frontend-testing` skill when reviewing tests or testability.
- `karpathy-guidelines` for scope control and focused, verifiable changes.
- `how-to-write-component` when reviewing React component structure, ownership, effects, query/mutation contracts, or memoization.
## Severity And Output
For any UI, UX, or accessibility review, fetch the latest Web Interface Guidelines before finalizing findings. Treat them as a required baseline, not the complete source of accessibility truth:
- **P0**: security or privacy leak, data loss, production crash, or inaccessible critical workflow.
- **P1**: user-visible regression, invalid API or authorization contract, hydration failure, or broken primary interaction.
- **P2**: concrete maintainability, performance, test, or accessibility defect, or a material violation of an explicit project contract.
- **P3**: minor actionable cleanup; omit unless the user requested a thorough audit.
```text
https://raw.githubusercontent.com/vercel-labs/web-interface-guidelines/main/command.md
```
Lead with findings ordered by severity. Include a tight file and line reference, the observed failure or applicable project rule, and a concrete fix direction. Explain the rule's applicability for convention findings; describe downstream consequences only when supported by evidence. When no findings remain, say so briefly and state any material verification gap. Do not add praise sections, speculative risks, or an unsolicited offer to implement fixes.
If the review depends on a current framework, SDK, browser API, or accessibility behavior and local code does not settle it, check the current official docs first. For browser compatibility, deprecation, or behavior-sensitive frontend APIs, verify MDN or the relevant standard.
## Rule Packs
Apply every relevant rule pack:
- [references/accessibility-ui.md](references/accessibility-ui.md) — accessibility, semantic HTML, focus, forms, keyboard, disabled states, copy, and long-content behavior. Combines Web Interface Guidelines with Dify UI, Base UI, MDN, and local primitive contracts.
- [references/dify-ui.md](references/dify-ui.md) — Dify UI primitive usage, Base UI semantics, overlays, forms, tokens, radius mapping, and primitive boundaries.
- [references/component-architecture.md](references/component-architecture.md) — component ownership, props, state, effects, exports, wrappers, and feature organization.
- [references/data-query-contracts.md](references/data-query-contracts.md) — generated contracts, TanStack Query, mutations, workspace/auth/SSR boundaries, URL/local storage state.
- [references/performance.md](references/performance.md) — React/Next performance review rules from Vercel guidance, scoped to real risk.
- [references/testing.md](references/testing.md) — frontend test review rules.
- [references/dify-invariants.md](references/dify-invariants.md) — stable Dify-specific runtime invariants that generic React/a11y rules will not catch.
- [references/code-quality.md](references/code-quality.md) — general TypeScript, styling, naming, and maintainability rules.
## Review Process
1. Identify the review scope. For pending changes, inspect `git diff --stat`, `git diff`, and staged diff if relevant. For file-focused reviews, stay within the named files unless a referenced owner/contract must be read.
2. Read code around the changed lines and the owning module. Do not review by isolated snippets when nearby ownership, labels, query inputs, or overlay structure decide correctness.
3. Check user-visible regressions first: accessibility, broken interaction, auth/permission leaks, query/hydration errors, data loss, navigation mistakes, and impossible states.
4. Then check maintainability and performance: ownership, effects, wrappers, memoization, bundle/waterfall risks, tests, and design-system drift.
5. Report only actionable findings. Do not list speculative risks, style preferences, or broad refactors unless they are directly tied to a reproducible issue in scope.
## Severity
- **P0**: security/privacy/auth leak, data loss, production crash, inaccessible critical flow, or broken primary workflow.
- **P1**: user-visible regression, hydration/SSR failure, invalid API/query contract, broken keyboard/focus behavior, or serious design-system/a11y violation.
- **P2**: maintainability or performance issue likely to cause bugs, duplicated state, incorrect ownership, missing tests for risky behavior, or non-critical a11y issue.
- **P3**: minor cleanup with clear value. Omit unless the user asked for a thorough audit.
## Output Format
Lead with findings, ordered by severity. Use this structure:
```markdown
## Findings
- [P1] Short issue title
File: `path/to/file.tsx:123`
Why it matters and how to reproduce or reason about it.
Suggested fix: concrete fix direction.
## Open Questions
- Question or assumption, if any.
## Summary
Brief secondary context. Mention tests not run or residual risk.
```
Rules:
- If there are no findings, say `No issues found.` and mention any test gaps or residual risk.
- Always include file and line when available.
- Keep findings concrete and reproducible.
- Do not include praise sections by default.
- Do not ask to apply fixes unless the user explicitly wants review plus implementation.
[accessibility]: references/accessibility-ui.md
[code-quality]: references/code-quality.md
[component-architecture]: references/component-architecture.md
[data-query]: references/data-query-contracts.md
[dify-invariants]: references/dify-invariants.md
[dify-ui]: references/dify-ui.md
[performance]: references/performance.md
[testing]: references/testing.md

View File

@@ -2,32 +2,51 @@
Accessibility findings are first-class review findings. Treat broken keyboard access, missing accessible names, focus loss, and unreachable popup content as correctness bugs, not polish.
Before finalizing UI or accessibility findings, fetch the latest Web Interface Guidelines as a required baseline:
## Review Evidence
```text
https://raw.githubusercontent.com/vercel-labs/web-interface-guidelines/main/command.md
```
Do not treat that document as the complete accessibility rule set. Combine it with:
Use the sources relevant to the changed contract:
- `packages/dify-ui/README.md`, `packages/dify-ui/AGENTS.md`, and the relevant primitive implementation when code uses `@langgenius/dify-ui/*`.
- Base UI docs and local `.d.ts` contracts when primitive semantics, focus target, labels, or popup reachability are unclear.
- MDN or relevant WAI-ARIA/browser standards when behavior, compatibility, or deprecation status matters.
- The current feature's product semantics, because an accessible primitive can still be used in an inaccessible workflow.
Consult current official documentation or standards when these sources leave a behavior unresolved. The [Web Interface Guidelines] are an optional broader UI reference, not a required fetch for each review.
## Semantic HTML
Flag:
- Clickable `div` or `span` used for actions.
- Router navigation implemented with button or `onClick` when a `Link` / `<a>` is the real semantic element.
- Icon-only buttons without `aria-label` or `aria-labelledby`.
- Icon-only controls without an accessible name; follow the naming rules below and the Dify UI `IconButton` contract.
- Decorative icons missing `aria-hidden="true"`.
- Images without `alt`; use `alt=""` only when truly decorative.
- Heading levels that skip hierarchy in page-level content.
Prefer semantic HTML before ARIA.
## Page Landmarks
When reviewing Web page layouts, navigation, or landmark changes, read [Page landmarks].
Inspect the composed page with its parent layouts for missing or duplicate main regions,
inappropriate nesting or roles, and ambiguous or broken landmark names. Check affected
unit and E2E locators when semantic elements change. Web owns these composition rules;
use the existing naming contract for label-source decisions.
## Accessible Names And Descriptions
Read [Accessible names and descriptions] when a change affects labels, ARIA naming, help/error relationships, or hidden text. That document owns the shared implementation and review contract.
Flag violations supported by the final rendered behavior:
- Missing or insufficient names, redundant name overrides, or naming attributes prohibited by the element's role.
- Overrides that omit visible label wording or suppress necessary descendant information.
- Broken or stale label/description references, including relationships lost when responsive content or overlays unmount.
- Descriptions used instead of names, repeated help text, or essential structured content available only as a flattened description.
Inspect the computed name and description in the relevant state. Matching an `aria-label` string to nearby text alone does not prove redundancy.
## Keyboard And Focus
Flag:
@@ -48,7 +67,6 @@ Flag:
- Missing stable `name` on form fields that submit or validate.
- Incorrect input `type`, `inputMode`, `autoComplete`, or `spellCheck` for email, token, URL, number, search, code, or username fields.
- Labels that are not clickable.
- Submit buttons disabled before a request starts, preventing normal submit behavior.
- Non-submit buttons inside forms missing `type="button"`.
- Errors not associated with fields or not reachable by screen readers.
- Error recovery that does not focus or expose the first invalid field.
@@ -56,16 +74,20 @@ Flag:
- Placeholder text used as the only label.
- Password managers accidentally triggered on non-auth fields because autocomplete is missing or wrong.
Prefer visible labels. If visible surrounding text already labels the control, use a visually hidden label or a precise `aria-label`.
Prefer visible labels and associate them through the appropriate field primitive, a native `label`, or `aria-labelledby`. Do not duplicate an existing label with hidden text or `aria-label`; follow [Accessible names and descriptions] when no suitable visible label exists.
## Disabled, Loading, And Async States
Flag:
- Loading state without `aria-busy`, `role="status"`, or another accessible update path when it changes user interaction.
- Loading controls whose accessible name disappears, or whose user-relevant progress has no
feature-owned status path. Follow the Dify UI Button contract for focused loading buttons; do not
add `aria-busy` to a button as a generic pending-state substitute.
- The same pending state passed to both Dify UI Button `loading` and `disabled`, which duplicates
state ownership and obscures whether `disabled` expresses independent unavailability.
- Spinner or decorative loading icon exposed to screen readers.
- Disabled controls that hide the reason users cannot proceed.
- `aria-disabled` used without manually blocking click, Space, and Enter.
- Controls marked `aria-disabled` that still activate through supported pointer or keyboard input. Check the primitive's handling before requesting manual event guards.
- Toasts, inline validation, or async status changes that are not announced when users need the update to continue.
- Icon-only loading/error affordances without text or accessible status where the state matters.
@@ -90,7 +112,7 @@ Use Popover for explanatory content, rich help, and infotips. Use Tooltip only a
Flag:
- Text in flex/grid children without `min-w-0` when it can overflow.
- Names, labels, file names, model names, workspace names, or user content lacking `truncate`, `line-clamp`, or `break-words`.
- Long names, labels, or user content that overflow, obscure adjacent controls, or become unreadable in supported layouts.
- Right-side icons, badges, checks, or actions that shrink before the text area.
- Empty arrays or empty strings rendering broken layout instead of an empty state.
- Button, tab, badge, chip, menu item, or card text that can overlap sibling controls at common viewport widths.
@@ -107,3 +129,7 @@ Flag:
- Images without dimensions.
- Loading copy using `...` instead of `…`.
- Hardcoded dates, times, numbers, or currency formats instead of `Intl.*`.
[Accessible names and descriptions]: ../../../../packages/dify-ui/docs/accessible-names-and-descriptions.md
[Page landmarks]: ../../../../web/docs/landmarks.md
[Web Interface Guidelines]: https://raw.githubusercontent.com/vercel-labs/web-interface-guidelines/main/command.md

View File

@@ -26,15 +26,17 @@ Prefer:
## Styling
For Dify UI/Base UI state styling and callback composition, apply the package's [Styling] contract,
including its documented reasons for direct state access.
Flag:
- New CSS modules or ad hoc CSS when Tailwind utilities and Dify tokens cover the need.
- Component-level plain `.css` files or component CSS imported through `globals.css`; use scoped `*.module.css` only when Tailwind and component variants cannot express the style.
- Generic color utilities where Dify semantic tokens exist.
- Hardcoded magic class values for colors, spacing, radius, shadow, z-index, or typography when Dify tokens, component variants, or documented radius mappings exist.
- Hardcoded magic class values for colors, spacing, radius, shadow, z-index, or typography when Dify tokens, component variants, or standard Tailwind radius classes match the required design value. Apply [Styling] when choosing radius classes.
- `!` important modifiers or important CSS overrides without a narrow, documented reason.
- Manual string concatenation, template strings, array `.join(' ')`, or custom ternaries for conditional or multi-line classes.
- JS conditional class branches for primitive visual states already exposed by Dify UI/Base UI `data-*` selectors.
- Manual class-list assembly through string concatenation, template strings, array `.join(' ')`, or a custom conditional combiner instead of `cn(...)`. Conditional values passed to `cn(...)` remain valid.
- Incoming `className` placed before default classes in `cn(...)`, preventing call-site overrides.
- Arbitrary z-index or one-off layering fixes on overlays.
@@ -43,7 +45,6 @@ Use:
- `cn(...)` from the local package or utility already used by the file.
- Dify semantic tokens and Tailwind v4 utilities.
- Existing component variants before one-off class forks.
- Primitive selectors such as `data-disabled:*`, `data-checked:*`, `data-highlighted:*`, `group-data-*`, `peer-data-*`, and `has-[:focus-visible]` before adding React state or boolean props solely for styling.
- Component-level variants, semantic tokens, and normal cascade/order before `!` overrides. Use `!` only for a contained compatibility override that cannot be expressed through the component API or local selector structure.
## Imports
@@ -66,3 +67,5 @@ Flag:
- Error messages that state only the failure and not the next step.
Use feature-local translation keys by default. Alias only when crossing namespaces. `pnpm i18n:check --file <name>` should pass for any touched translation namespace.
[Styling]: ../../../../packages/dify-ui/docs/styling.md

View File

@@ -1,89 +1,31 @@
# Component Architecture Rules
# Component Architecture Review
Use these rules for React component structure, ownership, state, props, effects, and module organization.
Use the canonical reference for the changed concern. These links share rules; they do not activate the implementation skill or its workflow.
## Ownership
| Concern | Canonical rules |
| --- | --- |
| Vertical modules, public entrypoints, data/handler placement, wrappers, Props, and types | [Ownership] |
| Local/Jotai state, form drafts, route identity, URL state, and persistence | [State] |
| Effects, navigation, memoization, and subscriptions | [Runtime] |
| Hotkeys, focus, and secondary surfaces | [Interactions] |
Flag:
## Apply Rules In Their Actual Scope
- State, query, mutation, or handlers hoisted above the lowest component that actually uses them.
- Parent components owning row/item actions that do not coordinate a workflow.
- Prop drilling through multiple pass-through layers.
- A page/tab-level section component becoming the data owner without needing a shared snapshot or shared loading/error/empty UI.
- Feature code promoted to shared only because it appears once or might be reused later.
Explicit team conventions are reviewable contracts, including module organization and public API boundaries. Check the documented exception before reporting a violation. Do not infer an exception solely because the code appears to work, or invent a user-facing failure for a convention finding.
Accept repeated TanStack Query calls in siblings when each component independently consumes the data. Cache deduplication is not a reason to hoist by itself.
- For owner placement, trace the consumers and required lifetime. Establish whether the parent coordinates a snapshot, submission, navigation, shared UI, or persistence before asking to move state or handlers.
- For component boundaries, identify the ownership or encapsulation the proposed extraction would improve; file length alone establishes neither.
- For props and types, check the domain contract and public API. Do not report private props typing style alone; declaration/export syntax matters only for a documented package rule or concrete type, export, or framework defect.
- For state and Effects, trace the source of truth, external synchronization target, and mount/reset boundary. Controlledness alone does not prove that a draft is lifted or persisted; follow the form and overlay contracts linked by [State].
- For navigation, distinguish ordinary links from mutation success, guarded redirects, command flows, and submission side effects.
## Component Boundaries
## Preserve Existing Product Contracts
Flag:
During refactors, trace the interaction being moved through its real consumer. Navigation, sidebar, dropdown, webapp-list, and app-switching changes must preserve expansion controls, hover persistence, pin/delete actions, routing, keyboard/focus handling, and open-state ownership where present.
- React component files over 300 lines when the file mixes multiple responsibilities that can be split into focused colocated components, hooks, or utilities.
- Shallow wrappers that only rename props or hide the real primitive.
- Extra DOM wrappers that do not provide layout, semantics, accessibility, state ownership, or library integration.
- Dialog/dropdown/popover hidden surfaces that obscure the parent flow when they should be extracted into a small local component.
- Business forms, menu bodies, or one-off helpers moved away from their owner without reuse or semantic value.
Check that the changed owner still handles reachable empty, loading, and missing optional-data states, and that primitive wrappers preserve accessible semantics and the public controlled-state contract. Report the actual lost behavior or explicit rule violation; use the package testing policy when assessing regression coverage.
Prefer colocated components split by actual data and state needs.
## Bad Component Design Patterns
Flag:
- Refactors of existing navigation, sidebar, dropdown, webapp list, or app-switching UI that do not preserve behavior-sensitive interactions such as expand/collapse arrows, hover persistence, pin/delete controls, routing, keyboard/focus handling, or open-state ownership.
- Components that mix data fetching, mutation side effects, popup state, form validation, layout, and row rendering without a clear owner.
- Generic components with many boolean props that encode one feature's workflow.
- A shared component that imports feature-specific copy, routes, or API contracts.
- A feature component that accepts pre-rendered fragments only to avoid placing ownership correctly.
- A child component that receives both raw server data and separately derived flags for the same concept.
- A wrapper that changes accessible semantics of the primitive it wraps.
- A component that exposes controlled props but still keeps a competing private state for the same value.
- A component that cannot render empty, loading, or missing optional API fields without caller-side preprocessing.
When existing components already own interaction logic, prefer reusing or extending them. If a refactor is necessary, preserve the old interaction contract and add or update focused tests for changed behavior.
## Props And Types
Flag:
- `React.FC` / `FC`.
- Default exports outside framework-required files.
- Named `Props` types for trivial one-off props where inline typing is clearer.
- Props named by UI implementation instead of domain/API role.
- API data converted too early or under a generic name that breaks traceability.
- Callers duplicating fallback checks that the lowest rendering component already handles.
Prefer top-level `function` declarations for components and module helpers. Use arrow functions for callbacks and local lambdas.
## Effects
Flag effects that:
- Transform props/state for rendering.
- Copy one state value into another representing the same concept.
- Handle user actions that belong in event handlers.
- Reset state from props when a keyed reset, stable ID, or render-time derivation would work.
- Fetch data that belongs in framework APIs or TanStack Query.
If an effect remains, it must synchronize with a named external system: browser API, subscription, timer, analytics-on-visibility, non-React widget, or imperative DOM integration.
## State Modeling
Flag:
- Storing derived booleans, disabled flags, default tabs, or loading labels that can be calculated from current query/feature state.
- Local state used to fake server data or generated contract fields.
- UI state persisted to localStorage when it is live app state.
- Feature-local mock shells wired to unrelated existing APIs before the real API is confirmed.
Prefer render-time derivation. Keep true local state for user choices, transient input, controlled popups, and feature UI state that has no server source.
## Navigation
Flag:
- Imperative router navigation for ordinary links.
- Button semantics used for navigation.
- Navigation state hidden in component state when URL state is required for shareable filters, tabs, or pagination.
Use `Link` for normal navigation. Use router APIs for mutation success, guarded redirects, command flows, or form submission side effects.
[Interactions]: ../../how-to-write-component/references/interactions.md
[Ownership]: ../../how-to-write-component/references/ownership.md
[Runtime]: ../../how-to-write-component/references/runtime.md
[State]: ../../how-to-write-component/references/state.md

View File

@@ -1,74 +1,28 @@
# Data, Query, And Contract Rules
# Data, Query, And Contract Review
Use these rules for generated contracts, TanStack Query, mutations, auth/SSR boundaries, URL state, and client persistence.
[Data and queries] owns generated-client, Query options, mutation/cache, imperative access, SSR, authentication, and tenant rules. [State ownership] owns URL state and persistence. Read only the reference needed by the diff; reading a shared reference does not activate its implementation skill.
## Generated Contracts
## Generated Contracts And Query Conventions
Flag:
Review explicit team conventions as contracts, including direct generated options, `skipToken` for missing required input, and shared cache policy. A lint rule may enforce part of a convention; neither a green lint result nor a suppression proves the full contract is satisfied.
- New legacy service/helper wrappers around generated `queryOptions()` or `mutationOptions()`.
- Continuing to use deprecated contract operations when a ready generated contract exists.
- Assuming a generated file means an operation is ready without checking deprecated markers, schema shape, and the actual UI consumer.
- Re-declaring API DTOs in components.
- Adding compatibility layers instead of migrating the pointed line and deleting the old layer.
- Establish whether the changed call belongs to a new or migrated surface and whether the generated operation is ready. Check deprecated markers, schema shape, and the real UI consumer before prescribing a migration.
- Distinguish a pass-through wrapper from a feature hook with actual orchestration. Check whether an independent execution condition or Promise composition justifies the documented query/mutation exception.
- Trace generated input and output types through their boundaries. Identify the exact DTO mirror, field widening, placeholder input, or lost intentional empty value when reporting a violation.
- Check whether a local mutation callback owns feature feedback or replaces shared invalidation, retry, or cache defaults. Match optimistic changes to the current list/detail owner.
Use `web/contract/*` as the API shape source of truth. Follow existing `{ params, query?, body? }` input shape.
## Imperative Access And SSR
## Queries
- Check freshness, projection, retries, and the caller's execution condition separately against [Data and queries]. Trace Promise ownership to distinguish an awaited hard gate from soft prefetching with an explicit failure owner.
- For Server Components, identify who renders the data and who may revalidate it. Check dehydration, the same-key client consumer, error handling, and the intended Suspense/server-rendered-content contract when the diff changes streaming.
- For auth, setup, roles, branding, or availability, trace authoritative data and the loading/fallback path. A static redirect or placeholder value cannot stand in for a request-dependent decision.
Flag:
## Tenant, URL, And Persistence Boundaries
- `enabled` used to hide missing required input instead of `input: skipToken`.
- Fake fallback IDs or placeholder inputs used to force a query to run.
- Query results copied into local state for rendering.
- Shared query behavior such as invalidation, stale defaults, or retry rules reimplemented at call sites.
- `prefetchQuery` treated as a hard gate or as returning data/errors to the caller.
- Trace the current workspace-switch flow and cache lifetime before reporting missing identity in a query key. Verify backend meaning before treating `workspace_id` and `tenant_id` as interchangeable.
- For URL and storage changes, identify whether the value is shareable navigation state, live app state, a one-shot signal, or a low-frequency preference. Apply [State ownership] to that category and verify its write/reset owner.
Use `useQuery(consoleQuery.xxx.queryOptions(...))` or `useQuery(marketplaceQuery.xxx.queryOptions(...))` directly unless a feature hook performs real orchestration.
Report the violated rule and applicable scope or the concrete failing path. Do not invent runtime impact when the finding is a team-convention violation.
## Mutations
Flag:
- Deprecated `useInvalid` or `useReset`.
- `mutateAsync` used without a need for Promise semantics.
- Awaited mutations without `try/catch`.
- Components owning shared cache invalidation that belongs in query defaults.
- Optimistic updates that do not match current list/detail ownership.
Use generated `mutationOptions()` directly when possible. Put shared cache behavior in `createTanstackQueryUtils(...experimental_defaults...)`.
## SSR, Auth, And Route Boundaries
Flag:
- Request-time auth, setup, workspace role, or tenant decisions moved into static `next.config redirects()`.
- Dynamic role gates depending on `workspaces.current` implemented as static path redirects.
- Authorization logic depending on soft `prefetchQuery`.
- Removing a client fallback before server API unavailable behavior is defined.
- Global placeholder query contracts introduced to solve a route-local Suspense issue.
- Branding-sensitive UI reading placeholder defaults without checking pending/placeholder state.
Separate hard gates from soft prefetches. `fetchQuery` can be a server decision boundary; `prefetchQuery` is cache warmup.
## Workspace And Tenant
Flag:
- Treating workspace switch as ordinary CRUD invalidation when the current app flow performs server switch plus full reload.
- Query keys that omit workspace/tenant identity when the query truly varies by workspace and no full reload boundary applies.
- Mixing `workspace_id` and `tenant_id` without tracing the current backend/API contract.
Current Dify workspace switch should be reviewed as a tenant cache boundary first.
## URL State And Local Storage
Flag:
- Shareable filters, tabs, pagination, selected panels, or search state hidden only in component state.
- One-shot navigation signals modeled as subscribed persistent state.
- Live app state stored in localStorage.
- Direct `window.localStorage`, `globalThis.localStorage`, or raw storage calls in app code.
- High-frequency interaction state persisted on every change instead of on commit/settle.
Use URL state for shareable UI state, feature/Jotai/store state for live UI state, and `@/hooks/use-local-storage` only for low-frequency client-only preferences, dismissed notices, and UI defaults.
[Data and queries]: ../../how-to-write-component/references/data.md
[State ownership]: ../../how-to-write-component/references/state.md

View File

@@ -1,134 +1,29 @@
# Dify UI Rules
# Dify UI Review Routing
Use these rules whenever a review touches `packages/dify-ui/` or code consuming `@langgenius/dify-ui/*`.
Use this reference when a review touches `packages/dify-ui/` or consumes
`@langgenius/dify-ui/*`. It routes to owner documentation; it does not redefine package
contracts.
Before finalizing findings for those files, read the current local docs that apply:
Read `packages/dify-ui/AGENTS.md` and the primitive implementation first, then only the matching
owner:
- `packages/dify-ui/README.md`
- `packages/dify-ui/AGENTS.md`
- `web/docs/overlay.md` for floating UI
- `packages/dify-ui/src/<primitive>/index.tsx` for the primitive being changed or consumed
| Review area | Canonical owner |
| ------------------------------------------ | ------------------------------------------------------------------- |
| Package boundary and document routing | `packages/dify-ui/AGENTS.md` |
| Imports, exports, public types, and anatomy | `packages/dify-ui/docs/authoring.md` |
| Button or icon-only actions | `packages/dify-ui/src/button/README.md`, `packages/dify-ui/src/icon-button/README.md` |
| Compound inputs | `packages/dify-ui/src/input-group/README.md` |
| Forms and field semantics | `packages/dify-ui/docs/forms.md` |
| Selection and typed values | `packages/dify-ui/docs/selection.md` |
| Portals, layers, and floating surfaces | `packages/dify-ui/docs/overlays.md` |
| State styling, callbacks, and Tailwind | `packages/dify-ui/docs/styling.md` |
| Package tests and Storybook | `packages/dify-ui/docs/testing.md` |
## Package Boundary
For consumer code under `web/`, also read `web/AGENTS.md` for application-owned reuse policy and
`packages/dify-ui/README.md` for the available public subpaths.
Flag in `packages/dify-ui`:
- Imports from `web/`.
- Dependencies on Next.js, i18n, ky, Jotai, Zustand, TanStack Query, oRPC, or business APIs.
- Business-specific component behavior that belongs in `web/`.
- Multiple unrelated primitives in one component folder.
`packages/dify-ui` is a primitive layer: Base UI headless components + `cva` + `cn` + Dify design tokens.
## Imports And Exports
Flag:
- Consumer imports from `@langgenius/dify-ui` without a subpath.
- Missing `package.json#exports` entry for a new primitive.
- Internal package imports using workspace subpaths instead of relative paths.
- Exported props using internal-only types that consumers cannot import from the component subpath.
Consumers use subpath exports such as `@langgenius/dify-ui/button`.
## Props And State
Flag:
- Flattened props where related values need a discriminated union, such as `value` / `defaultValue`, `multiple` / `value`, or `clearable` / `onChange`.
- React state used only to mirror Base UI state for class names.
- JavaScript conditional class logic for visual states that the Dify UI/Base UI primitive already exposes through `data-*` attributes or CSS variables.
- Controlled props added when uncontrolled DOM state or CSS variables would be enough.
- Thin wrappers that rename Base UI parts without adding semantics.
Prefer Base UI/Dify UI data attributes and CSS variables for visual state: `data-open`, `data-checked`, `data-disabled`, `data-highlighted`, `data-popup-open`, `group-data-*`, `peer-data-*`, `has-[:focus-visible]`, and primitive CSS variables such as anchor width or transform origin. Use JS conditional classes for product/business state that the primitive does not expose.
## Forms
Flag:
- Form-like UI using unrelated `Input` and `Button` pieces without a submit boundary.
- Text-like fields not composed through `FieldRoot`, `FieldLabel`, and `FieldControl` when using Dify UI form semantics.
- Select fields using `FieldLabel` instead of `SelectLabel`.
- Slider fields using a generic label instead of `SliderLabel`.
- Checkbox/radio groups missing `FieldsetRoot` and `FieldsetLegend`.
- Field errors or descriptions rendered without `FieldDescription` / `FieldError` relationships.
`Form` is the submit boundary. Dify UI form primitives are not a form state-management framework; business validation and schema-driven behavior belong in `web/`.
## Overlay Contract
Flag:
- Legacy web overlay imports in new or modified code.
- Manual portals around Dify UI overlay primitives.
- Call-site `z-*` overrides on overlays.
- Missing root `isolation: isolate` assumptions when debugging overlay stacking.
- Repeated backdrop, z-index, or portal chrome at call sites.
- Tooltip used for infotips, long text, or interactive content.
All Dify UI body-portalled overlays use `z-50`. Toast uses `z-60`. DOM order handles stacking between overlays.
## Primitive Selection
Flag:
- `Tabs` used for simple mode/filter/view selection where `SegmentedControl` is the semantic primitive.
- `SegmentedControl` used where `tablist` / `tabpanel` semantics are required.
- `Select` used for searchable or free-form input.
- `Combobox` used for unrestricted search text where no selected option is remembered.
- `Autocomplete` used for closed-list selection.
- Tooltip or PreviewCard used for content that must be reachable on touch or by screen readers.
Use:
- `Autocomplete` for free-form text with optional suggestions.
- `Combobox` for searchable selected values from a collection.
- `Select` for closed, scannable option sets.
- `Popover` for infotips, help text, rich content, or interactions.
## Bad Usage Patterns To Flag
Flag:
- Manually recreating UI behavior or chrome already owned by `@langgenius/dify-ui/*` or `web/app/components/base/*`, such as buttons, inputs, toggle groups, popovers, dropdown menus, alert dialogs, switches, avatars, scroll areas, toasts, borders, focus states, disabled states, segmented controls, or existing feature components.
- Styling a raw Base UI primitive directly in `web/` when a Dify UI primitive exists.
- Wrapping a Dify UI primitive in a feature component that hides its label, error, disabled, or focus contract.
- Replacing a semantic primitive with a generic `div` plus classes to match a screenshot.
- Using `Tooltip` because it is visually convenient when the content is actually help text or needs touch access.
- Adding a `z-*` override to make a child popup appear over a parent dialog.
- Adding a new app-level wrapper around Dialog, Drawer, Popover, Select, or Combobox that repeats portal/backdrop/positioner logic.
- Using dify-ui `Input` as a drop-in replacement for legacy inputs that include search, clear, copy, unit, localized placeholder, or number normalization behavior.
- Building a form row from loose text and controls instead of the matching Field/Form primitives.
- Adding component state only to style `data-open`, `data-checked`, `data-disabled`, or highlighted states that Base UI already exposes.
- Passing booleans down only so children can toggle classes already expressible with primitive `data-*` selectors.
## Tokens, Radius, And Styling
Flag:
- `radius-*` class names.
- Custom Tailwind `borderRadius` extension for Figma radius values.
- Generic colors where semantic Dify tokens exist.
- Hardcoded design values where Dify tokens, component variants, or documented Figma radius mappings exist.
- `!` important modifiers used to fight primitive styles instead of fixing the variant, selector, or component composition.
- Manual class strings that duplicate primitive variants.
- `min-w-(--anchor-width)` on picker popups when it defeats viewport clamping.
Use the Figma radius mapping from `packages/dify-ui/AGENTS.md`; for example `--radius/sm` maps to `rounded-md`, and `--radius/md` maps to `rounded-lg`.
Use `!` only for a tightly scoped compatibility override after confirming the primitive API, data attributes, and selector structure cannot express the state.
## Focus Details
Flag focus rings attached to the wrong element. For example, Base UI `Slider.Thumb` focuses an internal `input[type=range]`, so the visible thumb wrapper needs `has-[:focus-visible]` rather than direct wrapper `focus-visible`.
## Custom SVG Icons
Flag:
- New generated React icon components or JSON files under `web/app/components/base/icons/src/...` for custom SVG icons.
- Custom SVG icons consumed outside the Tailwind `i-custom-*` icon class pipeline.
- Generated `packages/iconify-collections/custom-*/icons.json` diffs where unrelated existing icons lost or changed intrinsic `width` or `height`.
New custom SVG icons belong in `packages/iconify-collections/assets/...`. Regenerate with `pnpm --filter @dify/iconify-collections generate`, validate with `pnpm --filter @dify/iconify-collections check:dimensions`, and consume the generated icon with Tailwind `i-custom-*` classes.
Treat the implementation, public types, tests, and stories as evidence for the documented
contract. If they disagree, identify the actual owner before reporting a finding. Read current
official Base UI documentation and installed type declarations for upstream-derived behavior.
Report only a reproducible contract violation or observable defect, not a preference inferred from
this routing file.

View File

@@ -71,8 +71,6 @@ Flag:
## React Flow
For workflow React Flow components, keep this Dify-specific rule:
Use [Dify invariants] for React Flow node/edge consumption and provider availability in RAG Pipe template rendering. Callback-only reads or mutations can use `useStoreApi`.
- UI consumption should use React Flow hooks such as `useNodes` / `useEdges`.
- Callback-only reads or mutations can use `useStoreApi`.
- Node components under `web/app/components/workflow/nodes/[nodeName]/node.tsx` must not depend on workflow stores that are absent in RAG Pipe template rendering.
[Dify invariants]: dify-invariants.md

View File

@@ -1,72 +1,37 @@
# Testing Review Rules
Use these rules when reviewing test files, testability of changed code, or risky frontend changes that should have tests.
Use `web/docs/test.md` for tests owned by `web/` and `packages/dify-ui/docs/testing.md` for tests owned by Dify UI. These owners define their test boundaries, environments, and checks; this reference only adds review questions.
## Missing Coverage
## Request Missing Tests When Risk Justifies Them
Flag missing tests when the change affects:
Flag missing coverage when a change alters a reachable contract such as:
- User-visible behavior, navigation, form submission, validation, permissions, or loading/error/empty states.
- Query/mutation cache behavior.
- Accessibility-critical behavior such as labels, keyboard flow, focus, disabled state, or popup reachability.
- URL state parsing/serialization.
- Storage persistence or one-shot signals.
- Regression-prone workflow or generated contract migration paths.
- User interaction, navigation, form submission, validation, or permissions.
- Query or mutation behavior, URL state, persistence, or one-shot signals.
- Loading, error, empty, and recovery states that users can encounter.
- A hidden surface whose close-and-reopen behavior changes whether in-progress state resets or persists.
- Accessibility-critical labels, keyboard flow, focus, disabled state, or overlay behavior.
- A regression-prone business rule or bug fix that can be reproduced through a public boundary.
Do not request tests for purely mechanical renames or styling-only changes unless the styling affects layout, focus, or interaction.
Do not request tests for mechanical changes, pass-through wrappers, implementation details, or incidental visual styling. Low coverage alone is not a finding.
## Selectors
## Flag Low-Value or Fragile Tests
Flag:
Flag tests that:
- `getByTestId` used where role, label, text, placeholder, landmark, or scoped dialog/menu queries are available.
- Production `data-testid` added only to satisfy tests.
- Assertions against decorative icons rather than the named control.
- Tests that cannot find controls semantically but leave broken markup unchanged.
- Assert internal state, refs, hook usage, effect dependencies, private DOM structure, or cosmetic classes.
- Exist only to render a component, exercise a prop, or cover generic invalid inputs without a product scenario.
- Mock away the behavior under review or use mocks that do not match the public contract.
- Add production `data-testid` attributes where semantic markup would work.
- Use fake timers without timer behavior, leave async work unawaited, or leak shared state.
- Duplicate a contract already protected at a more useful owner boundary.
Prefer `getByRole` with accessible name, then `getByLabelText`, `getByPlaceholderText`, `getByText`, and `within(...)`.
## Review the Test Boundary
## Mocking
- Prefer semantic queries and accessible names.
- Prefer real feature components when integration semantics matter.
- Check mocks against the owning package's policy; allowed mocks must preserve the public contract and leave the behavior under review real.
- Apply the owning package's admission policy before requesting new automation. Real-browser verification can be a one-off review; a simulator limitation alone does not justify a permanent test.
- Check that assertions prove the claimed outcome and add evidence beyond existing tests; a browser runtime does not make weak assertions stronger.
Flag:
- Mocking `@langgenius/dify-ui/*` primitives.
- Mocking `@/app/components/base/*` components when the real component is practical.
- Mocking sibling or child components in the same directory for integration behavior.
- Mocks that do not match the real component's conditional rendering.
- Module-level mock state not reset in `beforeEach`.
- `vi.clearAllMocks()` in `afterEach` instead of `beforeEach`.
Use real project components for integration behavior. Mock APIs, `next/navigation`, browser shims, or complex providers only when setup would dominate the test.
## Behavior
Flag:
- Tests inspecting implementation details instead of user-observable behavior.
- Assertions that hardcode brittle copy when pattern matching or semantic roles would express behavior better.
- Fake timers used without real timing behavior.
- Async assertions missing `await`, `findBy*`, or `waitFor`.
- Test data missing required fields because inline partial objects bypass real types.
Use typed factory functions with complete defaults and partial overrides.
## URL State
For `nuqs` or query-state hooks, flag tests that:
- Mock URL state when URL synchronization is the behavior under review.
- Do not test parser serialize/parse round trips for custom parsers.
- Do not assert default-clearing behavior when defaults should be removed from the URL.
Prefer shared `NuqsTestingAdapter` helpers when available.
## Organization
Flag:
- Component/hook/util tests outside sibling `__tests__/` directories.
- Directory-level reviews that test only `index.tsx` while other files in scope contain behavior.
- Large test files with repeated setup that should use local builders.
When a component is very complex, prefer a refactor finding before asking for exhaustive tests.
Treat test quality, determinism, and regression value as the review criteria. Do not use test count or coverage percentage as a proxy for quality.

View File

@@ -1,332 +1,13 @@
---
name: frontend-testing
description: Generate Vitest + React Testing Library tests for Dify frontend components, hooks, and utilities. Triggers on testing, spec files, coverage, Vitest, RTL, unit tests, integration tests, or write/review test requests.
description: Use when writing or changing Vitest or React Testing Library tests under `web/` or `packages/dify-ui/`, or when the user explicitly requests frontend test strategy, including evaluation of an existing strategy. Do not use for frontend code-review-only requests, general testability discussion, Python tests, or Cucumber/Playwright E2E.
---
# Dify Frontend Testing Skill
# Frontend Testing
This skill enables Codex to generate high-quality, comprehensive frontend tests for the Dify project following established conventions and best practices.
Read the testing policy for the package that owns the changed tests:
> **⚠️ Authoritative Source**: This skill is derived from `web/docs/test.md`. Use Vitest mock/timer APIs (`vi.*`).
- `web/`: `web/docs/test.md` owns Web test boundaries, environments, and commands.
- `packages/dify-ui/`: `packages/dify-ui/docs/testing.md` owns primitive test boundaries, environments, Storybook, and commands.
## When to Apply This Skill
Apply this skill when the user:
- Asks to **write tests** for a component, hook, or utility
- Asks to **review existing tests** for completeness
- Mentions **Vitest**, **React Testing Library**, **RTL**, or **spec files**
- Requests **test coverage** improvement
- Uses `pnpm analyze-component` output as context
- Mentions **testing**, **unit tests**, or **integration tests** for frontend code
- Wants to understand **testing patterns** in the Dify codebase
**Do NOT apply** when:
- User is asking about backend/API tests (Python/pytest)
- User is asking about E2E tests (Cucumber + Playwright under `e2e/`)
- User is only asking conceptual questions without code context
## Quick Reference
### Key Commands
Run these commands from `web/`. From the repository root, prefix them with `pnpm -C web`.
```bash
# Run all tests
pnpm test
# Watch mode
pnpm test --watch
# Run specific file
pnpm test path/to/file.spec.tsx
# Generate coverage report
pnpm test --coverage
# Analyze component complexity
pnpm analyze-component <path>
# Review existing test
pnpm analyze-component <path> --review
```
### File Naming
- Test files: `ComponentName.spec.tsx` inside a same-level `__tests__/` directory
- Placement rule: Component, hook, and utility tests must live in a sibling `__tests__/` folder at the same level as the source under test. For example, `foo/index.tsx` maps to `foo/__tests__/index.spec.tsx`, and `foo/bar.ts` maps to `foo/__tests__/bar.spec.ts`.
- Integration tests: `web/__tests__/` directory
## Test Structure Template
```typescript
import { render, screen, fireEvent, waitFor } from '@testing-library/react'
import Component from './index'
// ✅ Import real project components (DO NOT mock these)
// import Loading from '@/app/components/base/loading'
// import { ChildComponent } from './child-component'
// ✅ Mock external dependencies only
vi.mock('@/service/api')
vi.mock('next/navigation', () => ({
useRouter: () => ({ push: vi.fn() }),
usePathname: () => '/test',
}))
// ✅ Zustand stores: Use real stores (auto-mocked globally)
// Set test state with: useAppStore.setState({ ... })
// Shared state for mocks (if needed)
let mockSharedState = false
describe('ComponentName', () => {
beforeEach(() => {
vi.clearAllMocks() // ✅ Reset mocks BEFORE each test
mockSharedState = false // ✅ Reset shared state
})
// Rendering tests (REQUIRED)
describe('Rendering', () => {
it('should render without crashing', () => {
// Arrange
const props = { title: 'Test' }
// Act
render(<Component {...props} />)
// Assert
expect(screen.getByText('Test')).toBeInTheDocument()
})
})
// Props tests (REQUIRED when props change observable behavior)
describe('Props', () => {
it('should disable the action when disabled', () => {
render(<Component disabled />)
expect(screen.getByRole('button')).toBeDisabled()
})
})
// User Interactions
describe('User Interactions', () => {
it('should handle click events', () => {
const handleClick = vi.fn()
render(<Component onClick={handleClick} />)
fireEvent.click(screen.getByRole('button'))
expect(handleClick).toHaveBeenCalledTimes(1)
})
})
// Edge Cases (REQUIRED)
describe('Edge Cases', () => {
it('should handle null data', () => {
render(<Component data={null} />)
expect(screen.getByText(/no data/i)).toBeInTheDocument()
})
it('should handle empty array', () => {
render(<Component items={[]} />)
expect(screen.getByText(/empty/i)).toBeInTheDocument()
})
})
})
```
## Testing Workflow (CRITICAL)
### ⚠️ Incremental Approach Required
**NEVER generate all test files at once.** For complex components or multi-file directories:
1. **Analyze & Plan**: List all files, order by complexity (simple → complex)
1. **Process ONE at a time**: Write test → Run test → Fix if needed → Next
1. **Verify before proceeding**: Do NOT continue to next file until current passes
```
For each file:
┌────────────────────────────────────────┐
│ 1. Write test │
│ 2. Run: pnpm test <file>.spec.tsx │
│ 3. PASS? → Mark complete, next file │
│ FAIL? → Fix first, then continue │
└────────────────────────────────────────┘
```
### Complexity-Based Order
Process in this order for multi-file testing:
1. 🟢 Utility functions (simplest)
1. 🟢 Custom hooks
1. 🟡 Simple components (presentational)
1. 🟡 Medium components (state, effects)
1. 🔴 Complex components (API, routing)
1. 🔴 Integration tests (index files - last)
### When to Refactor First
- **Complexity > 50**: Break into smaller pieces before testing
- **500+ lines**: Consider splitting before testing
- **Many dependencies**: Extract logic into hooks first
> 📖 See `references/workflow.md` for complete workflow details and todo list format.
## Testing Strategy
### Path-Level Testing (Directory Testing)
When assigned to test a directory/path, test **ALL content** within that path:
- Test all components, hooks, utilities in the directory (not just `index` file)
- Use incremental approach: one file at a time, verify each before proceeding
- Goal: 100% coverage of ALL files in the directory
### Integration Testing First
**Prefer integration testing** when writing tests for a directory:
- ✅ **Import real project components** directly (including base components and siblings)
- ✅ **Only mock**: API services (`@/service/*`), `next/navigation`, complex context providers
- ❌ **DO NOT mock** base components (`@/app/components/base/*`) or dify-ui primitives (`@langgenius/dify-ui/*`)
- ❌ **DO NOT mock** sibling/child components in the same directory
> See [Test Structure Template](#test-structure-template) for correct import/mock patterns.
### `nuqs` Query State Testing (Required for URL State Hooks)
When a component or hook uses `useQueryState` / `useQueryStates`:
- ✅ Use `NuqsTestingAdapter` (prefer shared helpers in `web/test/nuqs-testing.tsx`)
- ✅ Assert URL synchronization via `onUrlUpdate` (`searchParams`, `options.history`)
- ✅ For custom parsers (`createParser`), keep `parse` and `serialize` bijective and add round-trip edge cases (`%2F`, `%25`, spaces, legacy encoded values)
- ✅ Verify default-clearing behavior (default values should be removed from URL when applicable)
- ⚠️ Only mock `nuqs` directly when URL behavior is explicitly out of scope for the test
## Core Principles
### 1. AAA Pattern (Arrange-Act-Assert)
Every test should clearly separate:
- **Arrange**: Setup test data and render component
- **Act**: Perform user actions
- **Assert**: Verify expected outcomes
### 2. Black-Box Testing
- Test observable behavior, not implementation details
- Test product contracts, not cosmetic implementation. Do not add or expand unit tests only to lock pure style classes, spacing, colors, backgrounds, or layout micro-adjustments. Cover visual-only fixes with browser/manual verification, screenshots, or E2E/visual checks when risk justifies it. Add unit tests only when the change affects user-observable behavior, accessibility semantics, state, data flow, routing, or a stable component API contract.
- Use semantic queries (`getByRole` with accessible `name`, `getByLabelText`, `getByPlaceholderText`, `getByText`, and scoped `within(...)`)
- Treat `getByTestId` as a last resort. If a control cannot be found by role/name, label, landmark, or dialog scope, fix the component accessibility first instead of adding or relying on `data-testid`.
- Remove production `data-testid` attributes when semantic selectors can cover the behavior. Keep them only for non-visual mocked boundaries, editor/browser shims such as Monaco, canvas/chart output, or third-party widgets with no accessible DOM in the test environment.
- Do not assert decorative icons by test id. Assert the named control that contains them, or mark decorative icons `aria-hidden`.
- Avoid testing internal state directly
- **Prefer pattern matching over hardcoded strings** in assertions:
```typescript
// ❌ Avoid: hardcoded text assertions
expect(screen.getByText('Loading...')).toBeInTheDocument()
// ✅ Better: role-based queries
expect(screen.getByRole('status')).toBeInTheDocument()
// ✅ Better: pattern matching
expect(screen.getByText(/loading/i)).toBeInTheDocument()
```
### 3. Single Behavior Per Test
Each test verifies ONE user-observable behavior:
```typescript
// ✅ Good: One behavior
it('should disable button when loading', () => {
render(<Button loading />)
expect(screen.getByRole('button')).toBeDisabled()
})
// ❌ Bad: Multiple behaviors
it('should handle loading state', () => {
render(<Button loading />)
expect(screen.getByRole('button')).toBeDisabled()
expect(screen.getByText('Loading...')).toBeInTheDocument()
expect(screen.getByRole('button')).toHaveClass('loading')
})
```
### 4. Semantic Naming
Use `should <behavior> when <condition>`:
```typescript
it('should show error message when validation fails')
it('should call onSubmit when form is valid')
it('should disable input when isReadOnly is true')
```
## Required Test Scenarios
### Always Required (All Components)
1. **Rendering**: Component renders without crashing
1. **Props**: Required props, optional props, default values that change observable behavior. Do not test pass-through styling props such as `className` unless they are an explicit, stable component API whose absence would break a real integration contract.
1. **Edge Cases**: null, undefined, empty values, boundary conditions
### Conditional (When Present)
| Feature | Test Focus |
|---------|-----------|
| `useState` | Initial state, transitions, cleanup |
| `useEffect` | Execution, dependencies, cleanup |
| Event handlers | All onClick, onChange, onSubmit, keyboard |
| API calls | Loading, success, error states |
| Routing | Navigation, params, query strings |
| `useCallback`/`useMemo` | Referential equality |
| Context | Provider values, consumer behavior |
| Forms | Validation, submission, error display |
## Coverage Goals (Per File)
For each test file generated, aim for:
- ✅ **100%** function coverage
- ✅ **100%** statement coverage
- ✅ **>95%** branch coverage
- ✅ **>95%** line coverage
> **Note**: For multi-file directories, process one file at a time with full coverage each. See `references/workflow.md`.
## Detailed Guides
For more detailed information, refer to:
- `references/workflow.md` - **Incremental testing workflow** (MUST READ for multi-file testing)
- `references/mocking.md` - Mock patterns, Zustand store testing, and best practices
- `references/async-testing.md` - Async operations and API calls
- `references/domain-components.md` - Workflow, Dataset, Configuration testing
- `references/common-patterns.md` - Frequently used testing patterns
- `references/checklist.md` - Test generation checklist and validation steps
## Authoritative References
### Primary Specification (MUST follow)
- **`web/docs/test.md`** - The canonical testing specification. This skill is derived from this document.
### Reference Examples in Codebase
- `web/utils/classnames.spec.ts` - Utility function tests
- `web/app/components/base/radio/__tests__/index.spec.tsx` - Component tests
- `web/__mocks__/provider-context.ts` - Mock factory example
### Project Configuration
- `web/vite.config.ts` - Vite/Vitest configuration
- `web/vitest.setup.ts` - Test environment setup
- `web/scripts/analyze-component.js` - Component analysis tool
- Modules are not mocked automatically. Global mocks live in `web/vitest.setup.ts` (for example `react-i18next`, `next/image`); mock other modules like `ky` or `mime` locally in test files.
This skill adds no parallel policy or check sequence. Follow the selected owner's requirements, including its validation commands. Recommend deleting low-value tests as readily as adding missing behavior coverage, and report the contract verified and any material verification gap.

View File

@@ -1,293 +0,0 @@
/**
* Test Template for React Components
*
* WHY THIS STRUCTURE?
* - Organized sections make tests easy to navigate and maintain
* - Mocks at top ensure consistent test isolation
* - Factory functions reduce duplication and improve readability
* - describe blocks group related scenarios for better debugging
*
* INSTRUCTIONS:
* 1. Replace `ComponentName` with your component name
* 2. Update import path
* 3. Add/remove test sections based on component features (use analyze-component)
* 4. Follow AAA pattern: Arrange → Act → Assert
*
* RUN FIRST: pnpm analyze-component <path> to identify required test scenarios
*/
import { render, screen, fireEvent, waitFor } from '@testing-library/react'
import userEvent from '@testing-library/user-event'
// import ComponentName from './index'
// ============================================================================
// Mocks
// ============================================================================
// WHY: Mocks must be hoisted to top of file (Vitest requirement).
// They run BEFORE imports, so keep them before component imports.
// i18n (automatically mocked)
// WHY: Global mock in web/vitest.setup.ts is auto-loaded by Vitest setup
// The global mock provides: useTranslation, Trans, useMixedTranslation, useGetLanguage
// No explicit mock needed for most tests
//
// Override only if custom translations are required:
// import { createReactI18nextMock } from '@/test/i18n-mock'
// vi.mock('react-i18next', () => createReactI18nextMock({
// 'my.custom.key': 'Custom Translation',
// 'button.save': 'Save',
// }))
// Router (if component uses useRouter, usePathname, useSearchParams)
// WHY: Isolates tests from Next.js routing, enables testing navigation behavior
// const mockPush = vi.fn()
// vi.mock('@/next/navigation', () => ({
// useRouter: () => ({ push: mockPush }),
// usePathname: () => '/test-path',
// }))
// API services (if component fetches data)
// WHY: Prevents real network calls, enables testing all states (loading/success/error)
// vi.mock('@/service/api')
// import * as api from '@/service/api'
// const mockedApi = vi.mocked(api)
// Shared mock state (for portal/dropdown components)
// WHY: Portal components like PortalToFollowElem need shared state between
// parent and child mocks to correctly simulate open/close behavior
// let mockOpenState = false
// ============================================================================
// Test Data Factories
// ============================================================================
// WHY FACTORIES?
// - Avoid hard-coded test data scattered across tests
// - Easy to create variations with overrides
// - Type-safe when using actual types from source
// - Single source of truth for default test values
// const createMockProps = (overrides = {}) => ({
// // Default props that make component render successfully
// ...overrides,
// })
// const createMockItem = (overrides = {}) => ({
// id: 'item-1',
// name: 'Test Item',
// ...overrides,
// })
// ============================================================================
// Test Helpers
// ============================================================================
// const renderComponent = (props = {}) => {
// return render(<ComponentName {...createMockProps(props)} />)
// }
// ============================================================================
// Tests
// ============================================================================
describe('ComponentName', () => {
// WHY beforeEach with clearAllMocks?
// - Ensures each test starts with clean slate
// - Prevents mock call history from leaking between tests
// - MUST be beforeEach (not afterEach) to reset BEFORE assertions like toHaveBeenCalledTimes
beforeEach(() => {
vi.clearAllMocks()
// Reset shared mock state if used (CRITICAL for portal/dropdown tests)
// mockOpenState = false
})
// --------------------------------------------------------------------------
// Rendering Tests (REQUIRED - Every component MUST have these)
// --------------------------------------------------------------------------
// WHY: Catches import errors, missing providers, and basic render issues
describe('Rendering', () => {
it('should render without crashing', () => {
// Arrange - Setup data and mocks
// const props = createMockProps()
// Act - Render the component
// render(<ComponentName {...props} />)
// Assert - Verify expected output
// Prefer getByRole for accessibility; it's what users "see"
// expect(screen.getByRole('...')).toBeInTheDocument()
})
it('should render with default props', () => {
// WHY: Verifies component works without optional props
// render(<ComponentName />)
// expect(screen.getByText('...')).toBeInTheDocument()
})
})
// --------------------------------------------------------------------------
// Props Tests (REQUIRED - Every component MUST test prop behavior)
// --------------------------------------------------------------------------
// WHY: Props are the component's API contract. Test them thoroughly.
describe('Props', () => {
it('should apply custom className', () => {
// WHY: Common pattern in Dify - components should merge custom classes
// render(<ComponentName className="custom-class" />)
// expect(screen.getByTestId('component')).toHaveClass('custom-class')
})
it('should use default values for optional props', () => {
// WHY: Verifies TypeScript defaults work at runtime
// render(<ComponentName />)
// expect(screen.getByRole('...')).toHaveAttribute('...', 'default-value')
})
})
// --------------------------------------------------------------------------
// User Interactions (if component has event handlers - on*, handle*)
// --------------------------------------------------------------------------
// WHY: Event handlers are core functionality. Test from user's perspective.
describe('User Interactions', () => {
it('should call onClick when clicked', async () => {
// WHY userEvent over fireEvent?
// - userEvent simulates real user behavior (focus, hover, then click)
// - fireEvent is lower-level, doesn't trigger all browser events
// const user = userEvent.setup()
// const handleClick = vi.fn()
// render(<ComponentName onClick={handleClick} />)
//
// await user.click(screen.getByRole('button'))
//
// expect(handleClick).toHaveBeenCalledTimes(1)
})
it('should call onChange when value changes', async () => {
// const user = userEvent.setup()
// const handleChange = vi.fn()
// render(<ComponentName onChange={handleChange} />)
//
// await user.type(screen.getByRole('textbox'), 'new value')
//
// expect(handleChange).toHaveBeenCalled()
})
})
// --------------------------------------------------------------------------
// State Management (if component uses useState/useReducer)
// --------------------------------------------------------------------------
// WHY: Test state through observable UI changes, not internal state values
describe('State Management', () => {
it('should update state on interaction', async () => {
// WHY test via UI, not state?
// - State is implementation detail; UI is what users see
// - If UI works correctly, state must be correct
// const user = userEvent.setup()
// render(<ComponentName />)
//
// // Initial state - verify what user sees
// expect(screen.getByText('Initial')).toBeInTheDocument()
//
// // Trigger state change via user action
// await user.click(screen.getByRole('button'))
//
// // New state - verify UI updated
// expect(screen.getByText('Updated')).toBeInTheDocument()
})
})
// --------------------------------------------------------------------------
// Async Operations (if component fetches data - useQuery, fetch)
// --------------------------------------------------------------------------
// WHY: Async operations have 3 states users experience: loading, success, error
describe('Async Operations', () => {
it('should show loading state', () => {
// WHY never-resolving promise?
// - Keeps component in loading state for assertion
// - Alternative: use fake timers
// mockedApi.fetchData.mockImplementation(() => new Promise(() => {}))
// render(<ComponentName />)
//
// expect(screen.getByText(/loading/i)).toBeInTheDocument()
})
it('should show data on success', async () => {
// WHY waitFor?
// - Component updates asynchronously after fetch resolves
// - waitFor retries assertion until it passes or times out
// mockedApi.fetchData.mockResolvedValue({ items: ['Item 1'] })
// render(<ComponentName />)
//
// await waitFor(() => {
// expect(screen.getByText('Item 1')).toBeInTheDocument()
// })
})
it('should show error on failure', async () => {
// mockedApi.fetchData.mockRejectedValue(new Error('Network error'))
// render(<ComponentName />)
//
// await waitFor(() => {
// expect(screen.getByText(/error/i)).toBeInTheDocument()
// })
})
})
// --------------------------------------------------------------------------
// Edge Cases (REQUIRED - Every component MUST handle edge cases)
// --------------------------------------------------------------------------
// WHY: Real-world data is messy. Components must handle:
// - Null/undefined from API failures or optional fields
// - Empty arrays/strings from user clearing data
// - Boundary values (0, MAX_INT, special characters)
describe('Edge Cases', () => {
it('should handle null value', () => {
// WHY test null specifically?
// - API might return null for missing data
// - Prevents "Cannot read property of null" in production
// render(<ComponentName value={null} />)
// expect(screen.getByText(/no data/i)).toBeInTheDocument()
})
it('should handle undefined value', () => {
// WHY test undefined separately from null?
// - TypeScript treats them differently
// - Optional props are undefined, not null
// render(<ComponentName value={undefined} />)
// expect(screen.getByText(/no data/i)).toBeInTheDocument()
})
it('should handle empty array', () => {
// WHY: Empty state often needs special UI (e.g., "No items yet")
// render(<ComponentName items={[]} />)
// expect(screen.getByText(/empty/i)).toBeInTheDocument()
})
it('should handle empty string', () => {
// WHY: Empty strings are truthy in JS but visually empty
// render(<ComponentName text="" />)
// expect(screen.getByText(/placeholder/i)).toBeInTheDocument()
})
})
// --------------------------------------------------------------------------
// Accessibility (optional but recommended for Dify's enterprise users)
// --------------------------------------------------------------------------
// WHY: Dify has enterprise customers who may require accessibility compliance
describe('Accessibility', () => {
it('should have accessible name', () => {
// WHY getByRole with name?
// - Tests that screen readers can identify the element
// - Enforces proper labeling practices
// render(<ComponentName label="Test Label" />)
// expect(screen.getByRole('button', { name: /test label/i })).toBeInTheDocument()
})
it('should support keyboard navigation', async () => {
// WHY: Some users can't use a mouse
// const user = userEvent.setup()
// render(<ComponentName />)
//
// await user.tab()
// expect(screen.getByRole('button')).toHaveFocus()
})
})
})

View File

@@ -1,207 +0,0 @@
/**
* Test Template for Custom Hooks
*
* Instructions:
* 1. Replace `useHookName` with your hook name
* 2. Update import path
* 3. Add/remove test sections based on hook features
*/
import { renderHook, act, waitFor } from '@testing-library/react'
// import { useHookName } from './use-hook-name'
// ============================================================================
// Mocks
// ============================================================================
// API services (if hook fetches data)
// vi.mock('@/service/api')
// import * as api from '@/service/api'
// const mockedApi = vi.mocked(api)
// ============================================================================
// Test Helpers
// ============================================================================
// Wrapper for hooks that need context
// const createWrapper = (contextValue = {}) => {
// return ({ children }: { children: React.ReactNode }) => (
// <SomeContext.Provider value={contextValue}>
// {children}
// </SomeContext.Provider>
// )
// }
// ============================================================================
// Tests
// ============================================================================
describe('useHookName', () => {
beforeEach(() => {
vi.clearAllMocks()
})
// --------------------------------------------------------------------------
// Initial State
// --------------------------------------------------------------------------
describe('Initial State', () => {
it('should return initial state', () => {
// const { result } = renderHook(() => useHookName())
//
// expect(result.current.value).toBe(initialValue)
// expect(result.current.isLoading).toBe(false)
})
it('should accept initial value from props', () => {
// const { result } = renderHook(() => useHookName({ initialValue: 'custom' }))
//
// expect(result.current.value).toBe('custom')
})
})
// --------------------------------------------------------------------------
// State Updates
// --------------------------------------------------------------------------
describe('State Updates', () => {
it('should update value when setValue is called', () => {
// const { result } = renderHook(() => useHookName())
//
// act(() => {
// result.current.setValue('new value')
// })
//
// expect(result.current.value).toBe('new value')
})
it('should reset to initial value', () => {
// const { result } = renderHook(() => useHookName({ initialValue: 'initial' }))
//
// act(() => {
// result.current.setValue('changed')
// })
// expect(result.current.value).toBe('changed')
//
// act(() => {
// result.current.reset()
// })
// expect(result.current.value).toBe('initial')
})
})
// --------------------------------------------------------------------------
// Async Operations
// --------------------------------------------------------------------------
describe('Async Operations', () => {
it('should fetch data on mount', async () => {
// mockedApi.fetchData.mockResolvedValue({ data: 'test' })
//
// const { result } = renderHook(() => useHookName())
//
// // Initially loading
// expect(result.current.isLoading).toBe(true)
//
// // Wait for data
// await waitFor(() => {
// expect(result.current.isLoading).toBe(false)
// })
//
// expect(result.current.data).toEqual({ data: 'test' })
})
it('should handle fetch error', async () => {
// mockedApi.fetchData.mockRejectedValue(new Error('Network error'))
//
// const { result } = renderHook(() => useHookName())
//
// await waitFor(() => {
// expect(result.current.error).toBeTruthy()
// })
//
// expect(result.current.error?.message).toBe('Network error')
})
it('should refetch when dependency changes', async () => {
// mockedApi.fetchData.mockResolvedValue({ data: 'test' })
//
// const { result, rerender } = renderHook(
// ({ id }) => useHookName(id),
// { initialProps: { id: '1' } }
// )
//
// await waitFor(() => {
// expect(mockedApi.fetchData).toHaveBeenCalledWith('1')
// })
//
// rerender({ id: '2' })
//
// await waitFor(() => {
// expect(mockedApi.fetchData).toHaveBeenCalledWith('2')
// })
})
})
// --------------------------------------------------------------------------
// Side Effects
// --------------------------------------------------------------------------
describe('Side Effects', () => {
it('should call callback when value changes', () => {
// const callback = vi.fn()
// const { result } = renderHook(() => useHookName({ onChange: callback }))
//
// act(() => {
// result.current.setValue('new value')
// })
//
// expect(callback).toHaveBeenCalledWith('new value')
})
it('should cleanup on unmount', () => {
// const cleanup = vi.fn()
// vi.spyOn(window, 'addEventListener')
// vi.spyOn(window, 'removeEventListener')
//
// const { unmount } = renderHook(() => useHookName())
//
// expect(window.addEventListener).toHaveBeenCalled()
//
// unmount()
//
// expect(window.removeEventListener).toHaveBeenCalled()
})
})
// --------------------------------------------------------------------------
// Edge Cases
// --------------------------------------------------------------------------
describe('Edge Cases', () => {
it('should handle null input', () => {
// const { result } = renderHook(() => useHookName(null))
//
// expect(result.current.value).toBeNull()
})
it('should handle rapid updates', () => {
// const { result } = renderHook(() => useHookName())
//
// act(() => {
// result.current.setValue('1')
// result.current.setValue('2')
// result.current.setValue('3')
// })
//
// expect(result.current.value).toBe('3')
})
})
// --------------------------------------------------------------------------
// With Context (if hook uses context)
// --------------------------------------------------------------------------
describe('With Context', () => {
it('should use context value', () => {
// const wrapper = createWrapper({ someValue: 'context-value' })
// const { result } = renderHook(() => useHookName(), { wrapper })
//
// expect(result.current.contextValue).toBe('context-value')
})
})
})

View File

@@ -1,154 +0,0 @@
/**
* Test Template for Utility Functions
*
* Instructions:
* 1. Replace `utilityFunction` with your function name
* 2. Update import path
* 3. Use test.each for data-driven tests
*/
// import { utilityFunction } from './utility'
// ============================================================================
// Tests
// ============================================================================
describe('utilityFunction', () => {
// --------------------------------------------------------------------------
// Basic Functionality
// --------------------------------------------------------------------------
describe('Basic Functionality', () => {
it('should return expected result for valid input', () => {
// expect(utilityFunction('input')).toBe('expected-output')
})
it('should handle multiple arguments', () => {
// expect(utilityFunction('a', 'b', 'c')).toBe('abc')
})
})
// --------------------------------------------------------------------------
// Data-Driven Tests
// --------------------------------------------------------------------------
describe('Input/Output Mapping', () => {
test.each([
// [input, expected]
['input1', 'output1'],
['input2', 'output2'],
['input3', 'output3'],
])('should return %s for input %s', (input, expected) => {
// expect(utilityFunction(input)).toBe(expected)
})
})
// --------------------------------------------------------------------------
// Edge Cases
// --------------------------------------------------------------------------
describe('Edge Cases', () => {
it('should handle empty string', () => {
// expect(utilityFunction('')).toBe('')
})
it('should handle null', () => {
// expect(utilityFunction(null)).toBe(null)
// or
// expect(() => utilityFunction(null)).toThrow()
})
it('should handle undefined', () => {
// expect(utilityFunction(undefined)).toBe(undefined)
// or
// expect(() => utilityFunction(undefined)).toThrow()
})
it('should handle empty array', () => {
// expect(utilityFunction([])).toEqual([])
})
it('should handle empty object', () => {
// expect(utilityFunction({})).toEqual({})
})
})
// --------------------------------------------------------------------------
// Boundary Conditions
// --------------------------------------------------------------------------
describe('Boundary Conditions', () => {
it('should handle minimum value', () => {
// expect(utilityFunction(0)).toBe(0)
})
it('should handle maximum value', () => {
// expect(utilityFunction(Number.MAX_SAFE_INTEGER)).toBe(...)
})
it('should handle negative numbers', () => {
// expect(utilityFunction(-1)).toBe(...)
})
})
// --------------------------------------------------------------------------
// Type Coercion (if applicable)
// --------------------------------------------------------------------------
describe('Type Handling', () => {
it('should handle numeric string', () => {
// expect(utilityFunction('123')).toBe(123)
})
it('should handle boolean', () => {
// expect(utilityFunction(true)).toBe(...)
})
})
// --------------------------------------------------------------------------
// Error Cases
// --------------------------------------------------------------------------
describe('Error Handling', () => {
it('should throw for invalid input', () => {
// expect(() => utilityFunction('invalid')).toThrow('Error message')
})
it('should throw with specific error type', () => {
// expect(() => utilityFunction('invalid')).toThrow(ValidationError)
})
})
// --------------------------------------------------------------------------
// Complex Objects (if applicable)
// --------------------------------------------------------------------------
describe('Object Handling', () => {
it('should preserve object structure', () => {
// const input = { a: 1, b: 2 }
// expect(utilityFunction(input)).toEqual({ a: 1, b: 2 })
})
it('should handle nested objects', () => {
// const input = { nested: { deep: 'value' } }
// expect(utilityFunction(input)).toEqual({ nested: { deep: 'transformed' } })
})
it('should not mutate input', () => {
// const input = { a: 1 }
// const inputCopy = { ...input }
// utilityFunction(input)
// expect(input).toEqual(inputCopy)
})
})
// --------------------------------------------------------------------------
// Array Handling (if applicable)
// --------------------------------------------------------------------------
describe('Array Handling', () => {
it('should process all elements', () => {
// expect(utilityFunction([1, 2, 3])).toEqual([2, 4, 6])
})
it('should handle single element array', () => {
// expect(utilityFunction([1])).toEqual([2])
})
it('should preserve order', () => {
// expect(utilityFunction(['c', 'a', 'b'])).toEqual(['c', 'a', 'b'])
})
})
})

View File

@@ -1,345 +0,0 @@
# Async Testing Guide
## Core Async Patterns
### 1. waitFor - Wait for Condition
```typescript
import { render, screen, waitFor } from '@testing-library/react'
it('should load and display data', async () => {
render(<DataComponent />)
// Wait for element to appear
await waitFor(() => {
expect(screen.getByText('Loaded Data')).toBeInTheDocument()
})
})
it('should hide loading spinner after load', async () => {
render(<DataComponent />)
// Wait for element to disappear
await waitFor(() => {
expect(screen.queryByText('Loading...')).not.toBeInTheDocument()
})
})
```
### 2. findBy\* - Async Queries
```typescript
it('should show user name after fetch', async () => {
render(<UserProfile />)
// findBy returns a promise, auto-waits up to 1000ms
const userName = await screen.findByText('John Doe')
expect(userName).toBeInTheDocument()
// findByRole with options
const button = await screen.findByRole('button', { name: /submit/i })
expect(button).toBeEnabled()
})
```
### 3. userEvent for Async Interactions
```typescript
import userEvent from '@testing-library/user-event'
it('should submit form', async () => {
const user = userEvent.setup()
const onSubmit = vi.fn()
render(<Form onSubmit={onSubmit} />)
// userEvent methods are async
await user.type(screen.getByLabelText('Email'), 'test@example.com')
await user.click(screen.getByRole('button', { name: /submit/i }))
await waitFor(() => {
expect(onSubmit).toHaveBeenCalledWith({ email: 'test@example.com' })
})
})
```
## Fake Timers
### When to Use Fake Timers
- Testing components with `setTimeout`/`setInterval`
- Testing debounce/throttle behavior
- Testing animations or delayed transitions
- Testing polling or retry logic
### Basic Fake Timer Setup
```typescript
describe('Debounced Search', () => {
beforeEach(() => {
vi.useFakeTimers()
})
afterEach(() => {
vi.useRealTimers()
})
it('should debounce search input', async () => {
const onSearch = vi.fn()
render(<SearchInput onSearch={onSearch} debounceMs={300} />)
// Type in the input
fireEvent.change(screen.getByRole('textbox'), { target: { value: 'query' } })
// Search not called immediately
expect(onSearch).not.toHaveBeenCalled()
// Advance timers
vi.advanceTimersByTime(300)
// Now search is called
expect(onSearch).toHaveBeenCalledWith('query')
})
})
```
### Fake Timers with Async Code
```typescript
it('should retry on failure', async () => {
vi.useFakeTimers()
const fetchData = vi.fn()
.mockRejectedValueOnce(new Error('Network error'))
.mockResolvedValueOnce({ data: 'success' })
render(<RetryComponent fetchData={fetchData} retryDelayMs={1000} />)
// First call fails
await waitFor(() => {
expect(fetchData).toHaveBeenCalledTimes(1)
})
// Advance timer for retry
vi.advanceTimersByTime(1000)
// Second call succeeds
await waitFor(() => {
expect(fetchData).toHaveBeenCalledTimes(2)
expect(screen.getByText('success')).toBeInTheDocument()
})
vi.useRealTimers()
})
```
### Common Fake Timer Utilities
```typescript
// Run all pending timers
vi.runAllTimers()
// Run only pending timers (not new ones created during execution)
vi.runOnlyPendingTimers()
// Advance by specific time
vi.advanceTimersByTime(1000)
// Get current fake time
Date.now()
// Clear all timers
vi.clearAllTimers()
```
## API Testing Patterns
### Loading → Success → Error States
```typescript
describe('DataFetcher', () => {
beforeEach(() => {
vi.clearAllMocks()
})
it('should show loading state', () => {
mockedApi.fetchData.mockImplementation(() => new Promise(() => {})) // Never resolves
render(<DataFetcher />)
expect(screen.getByTestId('loading-spinner')).toBeInTheDocument()
})
it('should show data on success', async () => {
mockedApi.fetchData.mockResolvedValue({ items: ['Item 1', 'Item 2'] })
render(<DataFetcher />)
// Use findBy* for multiple async elements (better error messages than waitFor with multiple assertions)
const item1 = await screen.findByText('Item 1')
const item2 = await screen.findByText('Item 2')
expect(item1).toBeInTheDocument()
expect(item2).toBeInTheDocument()
expect(screen.queryByTestId('loading-spinner')).not.toBeInTheDocument()
})
it('should show error on failure', async () => {
mockedApi.fetchData.mockRejectedValue(new Error('Failed to fetch'))
render(<DataFetcher />)
await waitFor(() => {
expect(screen.getByText(/failed to fetch/i)).toBeInTheDocument()
})
})
it('should retry on error', async () => {
mockedApi.fetchData.mockRejectedValue(new Error('Network error'))
render(<DataFetcher />)
await waitFor(() => {
expect(screen.getByRole('button', { name: /retry/i })).toBeInTheDocument()
})
mockedApi.fetchData.mockResolvedValue({ items: ['Item 1'] })
fireEvent.click(screen.getByRole('button', { name: /retry/i }))
await waitFor(() => {
expect(screen.getByText('Item 1')).toBeInTheDocument()
})
})
})
```
### Testing Mutations
```typescript
it('should submit form and show success', async () => {
const user = userEvent.setup()
mockedApi.createItem.mockResolvedValue({ id: '1', name: 'New Item' })
render(<CreateItemForm />)
await user.type(screen.getByLabelText('Name'), 'New Item')
await user.click(screen.getByRole('button', { name: /create/i }))
// Button should be disabled during submission
expect(screen.getByRole('button', { name: /creating/i })).toBeDisabled()
await waitFor(() => {
expect(screen.getByText(/created successfully/i)).toBeInTheDocument()
})
expect(mockedApi.createItem).toHaveBeenCalledWith({ name: 'New Item' })
})
```
## useEffect Testing
### Testing Effect Execution
```typescript
it('should fetch data on mount', async () => {
const fetchData = vi.fn().mockResolvedValue({ data: 'test' })
render(<ComponentWithEffect fetchData={fetchData} />)
await waitFor(() => {
expect(fetchData).toHaveBeenCalledTimes(1)
})
})
```
### Testing Effect Dependencies
```typescript
it('should refetch when id changes', async () => {
const fetchData = vi.fn().mockResolvedValue({ data: 'test' })
const { rerender } = render(<ComponentWithEffect id="1" fetchData={fetchData} />)
await waitFor(() => {
expect(fetchData).toHaveBeenCalledWith('1')
})
rerender(<ComponentWithEffect id="2" fetchData={fetchData} />)
await waitFor(() => {
expect(fetchData).toHaveBeenCalledWith('2')
expect(fetchData).toHaveBeenCalledTimes(2)
})
})
```
### Testing Effect Cleanup
```typescript
it('should cleanup subscription on unmount', () => {
const subscribe = vi.fn()
const unsubscribe = vi.fn()
subscribe.mockReturnValue(unsubscribe)
const { unmount } = render(<SubscriptionComponent subscribe={subscribe} />)
expect(subscribe).toHaveBeenCalledTimes(1)
unmount()
expect(unsubscribe).toHaveBeenCalledTimes(1)
})
```
## Common Async Pitfalls
### ❌ Don't: Forget to await
```typescript
// Bad - test may pass even if assertion fails
it('should load data', () => {
render(<Component />)
waitFor(() => {
expect(screen.getByText('Data')).toBeInTheDocument()
})
})
// Good - properly awaited
it('should load data', async () => {
render(<Component />)
await waitFor(() => {
expect(screen.getByText('Data')).toBeInTheDocument()
})
})
```
### ❌ Don't: Use multiple assertions in single waitFor
```typescript
// Bad - if first assertion fails, won't know about second
await waitFor(() => {
expect(screen.getByText('Title')).toBeInTheDocument()
expect(screen.getByText('Description')).toBeInTheDocument()
})
// Good - separate waitFor or use findBy
const title = await screen.findByText('Title')
const description = await screen.findByText('Description')
expect(title).toBeInTheDocument()
expect(description).toBeInTheDocument()
```
### ❌ Don't: Mix fake timers with real async
```typescript
// Bad - fake timers don't work well with real Promises
vi.useFakeTimers()
await waitFor(() => {
expect(screen.getByText('Data')).toBeInTheDocument()
}) // May timeout!
// Good - use runAllTimers or advanceTimersByTime
vi.useFakeTimers()
render(<Component />)
vi.runAllTimers()
expect(screen.getByText('Data')).toBeInTheDocument()
```

View File

@@ -1,208 +0,0 @@
# Test Generation Checklist
Use this checklist when generating or reviewing tests for Dify frontend components.
## Pre-Generation
- [ ] Read the component source code completely
- [ ] Identify component type (component, hook, utility, page)
- [ ] Run `pnpm analyze-component <path>` if available
- [ ] Note complexity score and features detected
- [ ] Check for existing tests in the same directory
- [ ] **Identify ALL files in the directory** that need testing (not just index)
## Testing Strategy
### ⚠️ Incremental Workflow (CRITICAL for Multi-File)
- [ ] **NEVER generate all tests at once** - process one file at a time
- [ ] Order files by complexity: utilities → hooks → simple → complex → integration
- [ ] Create a todo list to track progress before starting
- [ ] For EACH file: write → run test → verify pass → then next
- [ ] **DO NOT proceed** to next file until current one passes
### Path-Level Coverage
- [ ] **Test ALL files** in the assigned directory/path
- [ ] List all components, hooks, utilities that need coverage
- [ ] Decide: single spec file (integration) or multiple spec files (unit)
### Complexity Assessment
- [ ] Run `pnpm analyze-component <path>` for complexity score
- [ ] **Complexity > 50**: Consider refactoring before testing
- [ ] **500+ lines**: Consider splitting before testing
- [ ] **30-50 complexity**: Use multiple describe blocks, organized structure
### Integration vs Mocking
- [ ] **DO NOT mock base components or dify-ui primitives** (base `Loading`, `Input`, `Badge`; dify-ui `Button`, `Tooltip`, `Dialog`, etc.)
- [ ] Import real project components instead of mocking
- [ ] Only mock: API calls, complex context providers, third-party libs with side effects
- [ ] Prefer integration testing when using single spec file
## Required Test Sections
### All Components MUST Have
- [ ] **Rendering tests** - Component renders without crashing
- [ ] **Props tests** - Required props, optional props, default values
- [ ] **Edge cases** - null, undefined, empty values, boundaries
### Conditional Sections (Add When Feature Present)
| Feature | Add Tests For |
|---------|---------------|
| `useState` | Initial state, transitions, cleanup |
| `useEffect` | Execution, dependencies, cleanup |
| Event handlers | onClick, onChange, onSubmit, keyboard |
| API calls | Loading, success, error states |
| Routing | Navigation, params, query strings |
| `useCallback`/`useMemo` | Referential equality |
| Context | Provider values, consumer behavior |
| Forms | Validation, submission, error display |
## Code Quality Checklist
### Structure
- [ ] Uses `describe` blocks to group related tests
- [ ] Test names follow `should <behavior> when <condition>` pattern
- [ ] AAA pattern (Arrange-Act-Assert) is clear
- [ ] Comments explain complex test scenarios
### Mocks
- [ ] **DO NOT mock base components or dify-ui primitives** (`@/app/components/base/*` or `@langgenius/dify-ui/*`)
- [ ] `vi.clearAllMocks()` in `beforeEach` (not `afterEach`)
- [ ] Shared mock state reset in `beforeEach`
- [ ] i18n uses global mock (auto-loaded in `web/vitest.setup.ts`); only override locally for custom translations
- [ ] Router mocks match actual Next.js API
- [ ] Mocks reflect actual component conditional behavior
- [ ] Only mock: API services, complex context providers, third-party libs
- [ ] For `nuqs` URL-state tests, wrap with `NuqsTestingAdapter` (prefer `web/test/nuqs-testing.tsx`)
- [ ] For `nuqs` URL-state tests, assert `onUrlUpdate` payload (`searchParams`, `options.history`)
- [ ] If custom `nuqs` parser exists, add round-trip tests for encoded edge cases (`%2F`, `%25`, spaces, legacy encoded values)
### Queries
- [ ] Prefer semantic queries (`getByRole`, `getByLabelText`)
- [ ] Use `queryBy*` for absence assertions
- [ ] Use `findBy*` for async elements
- [ ] `getByTestId` only as last resort
### Async
- [ ] All async tests use `async/await`
- [ ] `waitFor` wraps async assertions
- [ ] Fake timers properly setup/teardown
- [ ] No floating promises
### TypeScript
- [ ] No `any` types without justification
- [ ] Mock data uses actual types from source
- [ ] Factory functions have proper return types
## Coverage Goals (Per File)
For the current file being tested:
- [ ] 100% function coverage
- [ ] 100% statement coverage
- [ ] >95% branch coverage
- [ ] >95% line coverage
## Post-Generation (Per File)
**Run these checks after EACH test file, not just at the end:**
- [ ] Run `pnpm test path/to/file.spec.tsx` - **MUST PASS before next file**
- [ ] Fix any failures immediately
- [ ] Mark file as complete in todo list
- [ ] Only then proceed to next file
### After All Files Complete
- [ ] Run full directory test: `pnpm test path/to/directory/`
- [ ] Check coverage report: `pnpm test:coverage`
- [ ] Run `pnpm lint:fix` on all test files
- [ ] Run `pnpm type-check`
## Common Issues to Watch
### False Positives
```typescript
// ❌ Mock doesn't match actual behavior
vi.mock('./Component', () => () => <div>Mocked</div>)
// ✅ Mock matches actual conditional logic
vi.mock('./Component', () => ({ isOpen }: any) =>
isOpen ? <div>Content</div> : null
)
```
### State Leakage
```typescript
// ❌ Shared state not reset
let mockState = false
vi.mock('./useHook', () => () => mockState)
// ✅ Reset in beforeEach
beforeEach(() => {
mockState = false
})
```
### Async Race Conditions
```typescript
// ❌ Not awaited
it('loads data', () => {
render(<Component />)
expect(screen.getByText('Data')).toBeInTheDocument()
})
// ✅ Properly awaited
it('loads data', async () => {
render(<Component />)
await waitFor(() => {
expect(screen.getByText('Data')).toBeInTheDocument()
})
})
```
### Missing Edge Cases
Always test these scenarios:
- `null` / `undefined` inputs
- Empty strings / arrays / objects
- Boundary values (0, -1, MAX_INT)
- Error states
- Loading states
- Disabled states
## Quick Commands
```bash
# Run specific test
pnpm test path/to/file.spec.tsx
# Run with coverage
pnpm test:coverage path/to/file.spec.tsx
# Watch mode
pnpm test:watch path/to/file.spec.tsx
# Update snapshots (use sparingly)
pnpm test -u path/to/file.spec.tsx
# Analyze component
pnpm analyze-component path/to/component.tsx
# Review existing test
pnpm analyze-component path/to/component.tsx --review
```

View File

@@ -1,449 +0,0 @@
# Common Testing Patterns
## Query Priority
Use queries in this order (most to least preferred):
```typescript
// 1. getByRole - Most recommended (accessibility)
screen.getByRole('button', { name: /submit/i })
screen.getByRole('textbox', { name: /email/i })
screen.getByRole('heading', { level: 1 })
// 2. getByLabelText - Form fields
screen.getByLabelText('Email address')
screen.getByLabelText(/password/i)
// 3. getByPlaceholderText - When no label
screen.getByPlaceholderText('Search...')
// 4. getByText - Non-interactive elements
screen.getByText('Welcome to Dify')
screen.getByText(/loading/i)
// 5. getByDisplayValue - Current input value
screen.getByDisplayValue('current value')
// 6. getByAltText - Images
screen.getByAltText('Company logo')
// 7. getByTitle - Tooltip elements
screen.getByTitle('Close')
// 8. getByTestId - Last resort only!
screen.getByTestId('custom-element')
```
## Event Handling Patterns
### Click Events
```typescript
// Basic click
fireEvent.click(screen.getByRole('button'))
// With userEvent (preferred for realistic interaction)
const user = userEvent.setup()
await user.click(screen.getByRole('button'))
// Double click
await user.dblClick(screen.getByRole('button'))
// Right click
await user.pointer({ keys: '[MouseRight]', target: screen.getByRole('button') })
```
### Form Input
```typescript
const user = userEvent.setup()
// Type in input
await user.type(screen.getByRole('textbox'), 'Hello World')
// Clear and type
await user.clear(screen.getByRole('textbox'))
await user.type(screen.getByRole('textbox'), 'New value')
// Select option
await user.selectOptions(screen.getByRole('combobox'), 'option-value')
// Check checkbox
await user.click(screen.getByRole('checkbox'))
// Upload file
const file = new File(['content'], 'test.pdf', { type: 'application/pdf' })
await user.upload(screen.getByLabelText(/upload/i), file)
```
### Keyboard Events
```typescript
const user = userEvent.setup()
// Press Enter
await user.keyboard('{Enter}')
// Press Escape
await user.keyboard('{Escape}')
// Keyboard shortcut
await user.keyboard('{Control>}a{/Control}') // Ctrl+A
// Tab navigation
await user.tab()
// Arrow keys
await user.keyboard('{ArrowDown}')
await user.keyboard('{ArrowUp}')
```
## Component State Testing
### Testing State Transitions
```typescript
describe('Counter', () => {
it('should increment count', async () => {
const user = userEvent.setup()
render(<Counter initialCount={0} />)
// Initial state
expect(screen.getByText('Count: 0')).toBeInTheDocument()
// Trigger transition
await user.click(screen.getByRole('button', { name: /increment/i }))
// New state
expect(screen.getByText('Count: 1')).toBeInTheDocument()
})
})
```
### Testing Controlled Components
```typescript
describe('ControlledInput', () => {
it('should call onChange with new value', async () => {
const user = userEvent.setup()
const handleChange = vi.fn()
render(<ControlledInput value="" onChange={handleChange} />)
await user.type(screen.getByRole('textbox'), 'a')
expect(handleChange).toHaveBeenCalledWith('a')
})
it('should display controlled value', () => {
render(<ControlledInput value="controlled" onChange={vi.fn()} />)
expect(screen.getByRole('textbox')).toHaveValue('controlled')
})
})
```
## Conditional Rendering Testing
```typescript
describe('ConditionalComponent', () => {
it('should show loading state', () => {
render(<DataDisplay isLoading={true} data={null} />)
expect(screen.getByText(/loading/i)).toBeInTheDocument()
expect(screen.queryByTestId('data-content')).not.toBeInTheDocument()
})
it('should show error state', () => {
render(<DataDisplay isLoading={false} data={null} error="Failed to load" />)
expect(screen.getByText(/failed to load/i)).toBeInTheDocument()
})
it('should show data when loaded', () => {
render(<DataDisplay isLoading={false} data={{ name: 'Test' }} />)
expect(screen.getByText('Test')).toBeInTheDocument()
})
it('should show empty state when no data', () => {
render(<DataDisplay isLoading={false} data={[]} />)
expect(screen.getByText(/no data/i)).toBeInTheDocument()
})
})
```
## List Rendering Testing
```typescript
describe('ItemList', () => {
const items = [
{ id: '1', name: 'Item 1' },
{ id: '2', name: 'Item 2' },
{ id: '3', name: 'Item 3' },
]
it('should render all items', () => {
render(<ItemList items={items} />)
expect(screen.getAllByRole('listitem')).toHaveLength(3)
items.forEach(item => {
expect(screen.getByText(item.name)).toBeInTheDocument()
})
})
it('should handle item selection', async () => {
const user = userEvent.setup()
const onSelect = vi.fn()
render(<ItemList items={items} onSelect={onSelect} />)
await user.click(screen.getByText('Item 2'))
expect(onSelect).toHaveBeenCalledWith(items[1])
})
it('should handle empty list', () => {
render(<ItemList items={[]} />)
expect(screen.getByText(/no items/i)).toBeInTheDocument()
})
})
```
## Modal/Dialog Testing
```typescript
describe('Modal', () => {
it('should not render when closed', () => {
render(<Modal isOpen={false} onClose={vi.fn()} />)
expect(screen.queryByRole('dialog')).not.toBeInTheDocument()
})
it('should render when open', () => {
render(<Modal isOpen={true} onClose={vi.fn()} />)
expect(screen.getByRole('dialog')).toBeInTheDocument()
})
it('should call onClose when clicking overlay', async () => {
const user = userEvent.setup()
const handleClose = vi.fn()
render(<Modal isOpen={true} onClose={handleClose} />)
await user.click(screen.getByTestId('modal-overlay'))
expect(handleClose).toHaveBeenCalled()
})
it('should call onClose when pressing Escape', async () => {
const user = userEvent.setup()
const handleClose = vi.fn()
render(<Modal isOpen={true} onClose={handleClose} />)
await user.keyboard('{Escape}')
expect(handleClose).toHaveBeenCalled()
})
it('should trap focus inside modal', async () => {
const user = userEvent.setup()
render(
<Modal isOpen={true} onClose={vi.fn()}>
<button>First</button>
<button>Second</button>
</Modal>
)
// Focus should cycle within modal
await user.tab()
expect(screen.getByText('First')).toHaveFocus()
await user.tab()
expect(screen.getByText('Second')).toHaveFocus()
await user.tab()
expect(screen.getByText('First')).toHaveFocus() // Cycles back
})
})
```
## Form Testing
```typescript
describe('LoginForm', () => {
it('should submit valid form', async () => {
const user = userEvent.setup()
const onSubmit = vi.fn()
render(<LoginForm onSubmit={onSubmit} />)
await user.type(screen.getByLabelText(/email/i), 'test@example.com')
await user.type(screen.getByLabelText(/password/i), 'password123')
await user.click(screen.getByRole('button', { name: /sign in/i }))
expect(onSubmit).toHaveBeenCalledWith({
email: 'test@example.com',
password: 'password123',
})
})
it('should show validation errors', async () => {
const user = userEvent.setup()
render(<LoginForm onSubmit={vi.fn()} />)
// Submit empty form
await user.click(screen.getByRole('button', { name: /sign in/i }))
expect(screen.getByText(/email is required/i)).toBeInTheDocument()
expect(screen.getByText(/password is required/i)).toBeInTheDocument()
})
it('should validate email format', async () => {
const user = userEvent.setup()
render(<LoginForm onSubmit={vi.fn()} />)
await user.type(screen.getByLabelText(/email/i), 'invalid-email')
await user.click(screen.getByRole('button', { name: /sign in/i }))
expect(screen.getByText(/invalid email/i)).toBeInTheDocument()
})
it('should disable submit button while submitting', async () => {
const user = userEvent.setup()
const onSubmit = vi.fn(() => new Promise(resolve => setTimeout(resolve, 100)))
render(<LoginForm onSubmit={onSubmit} />)
await user.type(screen.getByLabelText(/email/i), 'test@example.com')
await user.type(screen.getByLabelText(/password/i), 'password123')
await user.click(screen.getByRole('button', { name: /sign in/i }))
expect(screen.getByRole('button', { name: /signing in/i })).toBeDisabled()
await waitFor(() => {
expect(screen.getByRole('button', { name: /sign in/i })).toBeEnabled()
})
})
})
```
## Data-Driven Tests with test.each
```typescript
describe('StatusBadge', () => {
test.each([
['success', 'bg-green-500'],
['warning', 'bg-yellow-500'],
['error', 'bg-red-500'],
['info', 'bg-blue-500'],
])('should apply correct class for %s status', (status, expectedClass) => {
render(<StatusBadge status={status} />)
expect(screen.getByTestId('status-badge')).toHaveClass(expectedClass)
})
test.each([
{ input: null, expected: 'Unknown' },
{ input: undefined, expected: 'Unknown' },
{ input: '', expected: 'Unknown' },
{ input: 'invalid', expected: 'Unknown' },
])('should show "Unknown" for invalid input: $input', ({ input, expected }) => {
render(<StatusBadge status={input} />)
expect(screen.getByText(expected)).toBeInTheDocument()
})
})
```
## Debugging Tips
```typescript
// Print entire DOM
screen.debug()
// Print specific element
screen.debug(screen.getByRole('button'))
// Log testing playground URL
screen.logTestingPlaygroundURL()
// Pretty print DOM
import { prettyDOM } from '@testing-library/react'
console.log(prettyDOM(screen.getByRole('dialog')))
// Check available roles
import { getRoles } from '@testing-library/react'
console.log(getRoles(container))
```
## Common Mistakes to Avoid
### ❌ Don't Use Implementation Details
```typescript
// Bad - testing implementation
expect(component.state.isOpen).toBe(true)
expect(wrapper.find('.internal-class').length).toBe(1)
// Good - testing behavior
expect(screen.getByRole('dialog')).toBeInTheDocument()
```
### ❌ Don't Forget Cleanup
```typescript
// Bad - may leak state between tests
it('test 1', () => {
render(<Component />)
})
// Good - cleanup is automatic with RTL, but reset mocks
beforeEach(() => {
vi.clearAllMocks()
})
```
### ❌ Don't Use Exact String Matching (Prefer Black-Box Assertions)
```typescript
// ❌ Bad - hardcoded strings are brittle
expect(screen.getByText('Submit Form')).toBeInTheDocument()
expect(screen.getByText('Loading...')).toBeInTheDocument()
// ✅ Good - role-based queries (most semantic)
expect(screen.getByRole('button', { name: /submit/i })).toBeInTheDocument()
expect(screen.getByRole('status')).toBeInTheDocument()
// ✅ Good - pattern matching (flexible)
expect(screen.getByText(/submit/i)).toBeInTheDocument()
expect(screen.getByText(/loading/i)).toBeInTheDocument()
// ✅ Good - test behavior, not exact UI text
expect(screen.getByRole('button')).toBeDisabled()
expect(screen.getByRole('alert')).toBeInTheDocument()
```
**Why prefer black-box assertions?**
- Text content may change (i18n, copy updates)
- Role-based queries test accessibility
- Pattern matching is resilient to minor changes
- Tests focus on behavior, not implementation details
### ❌ Don't Assert on Absence Without Query
```typescript
// Bad - throws if not found
expect(screen.getByText('Error')).not.toBeInTheDocument() // Error!
// Good - use queryBy for absence assertions
expect(screen.queryByText('Error')).not.toBeInTheDocument()
```

View File

@@ -1,523 +0,0 @@
# Domain-Specific Component Testing
This guide covers testing patterns for Dify's domain-specific components.
## Workflow Components (`workflow/`)
Workflow components handle node configuration, data flow, and graph operations.
### Key Test Areas
1. **Node Configuration**
1. **Data Validation**
1. **Variable Passing**
1. **Edge Connections**
1. **Error Handling**
### Example: Node Configuration Panel
```typescript
import { render, screen, fireEvent, waitFor } from '@testing-library/react'
import userEvent from '@testing-library/user-event'
import NodeConfigPanel from './node-config-panel'
import { createMockNode, createMockWorkflowContext } from '@/__mocks__/workflow'
// Mock workflow context
vi.mock('@/app/components/workflow/hooks', () => ({
useWorkflowStore: () => mockWorkflowStore,
useNodesInteractions: () => mockNodesInteractions,
}))
let mockWorkflowStore = {
nodes: [],
edges: [],
updateNode: vi.fn(),
}
let mockNodesInteractions = {
handleNodeSelect: vi.fn(),
handleNodeDelete: vi.fn(),
}
describe('NodeConfigPanel', () => {
beforeEach(() => {
vi.clearAllMocks()
mockWorkflowStore = {
nodes: [],
edges: [],
updateNode: vi.fn(),
}
})
describe('Node Configuration', () => {
it('should render node type selector', () => {
const node = createMockNode({ type: 'llm' })
render(<NodeConfigPanel node={node} />)
expect(screen.getByLabelText(/model/i)).toBeInTheDocument()
})
it('should update node config on change', async () => {
const user = userEvent.setup()
const node = createMockNode({ type: 'llm' })
render(<NodeConfigPanel node={node} />)
await user.selectOptions(screen.getByLabelText(/model/i), 'gpt-4')
expect(mockWorkflowStore.updateNode).toHaveBeenCalledWith(
node.id,
expect.objectContaining({ model: 'gpt-4' })
)
})
})
describe('Data Validation', () => {
it('should show error for invalid input', async () => {
const user = userEvent.setup()
const node = createMockNode({ type: 'code' })
render(<NodeConfigPanel node={node} />)
// Enter invalid code
const codeInput = screen.getByLabelText(/code/i)
await user.clear(codeInput)
await user.type(codeInput, 'invalid syntax {{{')
await waitFor(() => {
expect(screen.getByText(/syntax error/i)).toBeInTheDocument()
})
})
it('should validate required fields', async () => {
const node = createMockNode({ type: 'http', data: { url: '' } })
render(<NodeConfigPanel node={node} />)
fireEvent.click(screen.getByRole('button', { name: /save/i }))
await waitFor(() => {
expect(screen.getByText(/url is required/i)).toBeInTheDocument()
})
})
})
describe('Variable Passing', () => {
it('should display available variables from upstream nodes', () => {
const upstreamNode = createMockNode({
id: 'node-1',
type: 'start',
data: { outputs: [{ name: 'user_input', type: 'string' }] },
})
const currentNode = createMockNode({
id: 'node-2',
type: 'llm',
})
mockWorkflowStore.nodes = [upstreamNode, currentNode]
mockWorkflowStore.edges = [{ source: 'node-1', target: 'node-2' }]
render(<NodeConfigPanel node={currentNode} />)
// Variable selector should show upstream variables
fireEvent.click(screen.getByRole('button', { name: /add variable/i }))
expect(screen.getByText('user_input')).toBeInTheDocument()
})
it('should insert variable into prompt template', async () => {
const user = userEvent.setup()
const node = createMockNode({ type: 'llm' })
render(<NodeConfigPanel node={node} />)
// Click variable button
await user.click(screen.getByRole('button', { name: /insert variable/i }))
await user.click(screen.getByText('user_input'))
const promptInput = screen.getByLabelText(/prompt/i)
expect(promptInput).toHaveValue(expect.stringContaining('{{user_input}}'))
})
})
})
```
## Dataset Components (`dataset/`)
Dataset components handle file uploads, data display, and search/filter operations.
### Key Test Areas
1. **File Upload**
1. **File Type Validation**
1. **Pagination**
1. **Search & Filtering**
1. **Data Format Handling**
### Example: Document Uploader
```typescript
import { render, screen, fireEvent, waitFor } from '@testing-library/react'
import userEvent from '@testing-library/user-event'
import DocumentUploader from './document-uploader'
vi.mock('@/service/datasets', () => ({
uploadDocument: vi.fn(),
parseDocument: vi.fn(),
}))
import * as datasetService from '@/service/datasets'
const mockedService = vi.mocked(datasetService)
describe('DocumentUploader', () => {
beforeEach(() => {
vi.clearAllMocks()
})
describe('File Upload', () => {
it('should accept valid file types', async () => {
const user = userEvent.setup()
const onUpload = vi.fn()
mockedService.uploadDocument.mockResolvedValue({ id: 'doc-1' })
render(<DocumentUploader onUpload={onUpload} />)
const file = new File(['content'], 'test.pdf', { type: 'application/pdf' })
const input = screen.getByLabelText(/upload/i)
await user.upload(input, file)
await waitFor(() => {
expect(mockedService.uploadDocument).toHaveBeenCalledWith(
expect.any(FormData)
)
})
})
it('should reject invalid file types', async () => {
const user = userEvent.setup()
render(<DocumentUploader />)
const file = new File(['content'], 'test.exe', { type: 'application/x-msdownload' })
const input = screen.getByLabelText(/upload/i)
await user.upload(input, file)
expect(screen.getByText(/unsupported file type/i)).toBeInTheDocument()
expect(mockedService.uploadDocument).not.toHaveBeenCalled()
})
it('should show upload progress', async () => {
const user = userEvent.setup()
// Mock upload with progress
mockedService.uploadDocument.mockImplementation(() => {
return new Promise((resolve) => {
setTimeout(() => resolve({ id: 'doc-1' }), 100)
})
})
render(<DocumentUploader />)
const file = new File(['content'], 'test.pdf', { type: 'application/pdf' })
await user.upload(screen.getByLabelText(/upload/i), file)
expect(screen.getByRole('progressbar')).toBeInTheDocument()
await waitFor(() => {
expect(screen.queryByRole('progressbar')).not.toBeInTheDocument()
})
})
})
describe('Error Handling', () => {
it('should handle upload failure', async () => {
const user = userEvent.setup()
mockedService.uploadDocument.mockRejectedValue(new Error('Upload failed'))
render(<DocumentUploader />)
const file = new File(['content'], 'test.pdf', { type: 'application/pdf' })
await user.upload(screen.getByLabelText(/upload/i), file)
await waitFor(() => {
expect(screen.getByText(/upload failed/i)).toBeInTheDocument()
})
})
it('should allow retry after failure', async () => {
const user = userEvent.setup()
mockedService.uploadDocument
.mockRejectedValueOnce(new Error('Network error'))
.mockResolvedValueOnce({ id: 'doc-1' })
render(<DocumentUploader />)
const file = new File(['content'], 'test.pdf', { type: 'application/pdf' })
await user.upload(screen.getByLabelText(/upload/i), file)
await waitFor(() => {
expect(screen.getByRole('button', { name: /retry/i })).toBeInTheDocument()
})
await user.click(screen.getByRole('button', { name: /retry/i }))
await waitFor(() => {
expect(screen.getByText(/uploaded successfully/i)).toBeInTheDocument()
})
})
})
})
```
### Example: Document List with Pagination
```typescript
describe('DocumentList', () => {
describe('Pagination', () => {
it('should load first page on mount', async () => {
mockedService.getDocuments.mockResolvedValue({
data: [{ id: '1', name: 'Doc 1' }],
total: 50,
page: 1,
pageSize: 10,
})
render(<DocumentList datasetId="ds-1" />)
await waitFor(() => {
expect(screen.getByText('Doc 1')).toBeInTheDocument()
})
expect(mockedService.getDocuments).toHaveBeenCalledWith('ds-1', { page: 1 })
})
it('should navigate to next page', async () => {
const user = userEvent.setup()
mockedService.getDocuments.mockResolvedValue({
data: [{ id: '1', name: 'Doc 1' }],
total: 50,
page: 1,
pageSize: 10,
})
render(<DocumentList datasetId="ds-1" />)
await waitFor(() => {
expect(screen.getByText('Doc 1')).toBeInTheDocument()
})
mockedService.getDocuments.mockResolvedValue({
data: [{ id: '11', name: 'Doc 11' }],
total: 50,
page: 2,
pageSize: 10,
})
await user.click(screen.getByRole('button', { name: /next/i }))
await waitFor(() => {
expect(screen.getByText('Doc 11')).toBeInTheDocument()
})
})
})
describe('Search & Filtering', () => {
it('should filter by search query', async () => {
const user = userEvent.setup()
vi.useFakeTimers()
render(<DocumentList datasetId="ds-1" />)
await user.type(screen.getByPlaceholderText(/search/i), 'test query')
// Debounce
vi.advanceTimersByTime(300)
await waitFor(() => {
expect(mockedService.getDocuments).toHaveBeenCalledWith(
'ds-1',
expect.objectContaining({ search: 'test query' })
)
})
vi.useRealTimers()
})
})
})
```
## Configuration Components (`app/configuration/`, `config/`)
Configuration components handle forms, validation, and data persistence.
### Key Test Areas
1. **Form Validation**
1. **Save/Reset**
1. **Required vs Optional Fields**
1. **Configuration Persistence**
1. **Error Feedback**
### Example: App Configuration Form
```typescript
import { render, screen, fireEvent, waitFor } from '@testing-library/react'
import userEvent from '@testing-library/user-event'
import AppConfigForm from './app-config-form'
vi.mock('@/service/apps', () => ({
updateAppConfig: vi.fn(),
getAppConfig: vi.fn(),
}))
import * as appService from '@/service/apps'
const mockedService = vi.mocked(appService)
describe('AppConfigForm', () => {
const defaultConfig = {
name: 'My App',
description: '',
icon: 'default',
openingStatement: '',
}
beforeEach(() => {
vi.clearAllMocks()
mockedService.getAppConfig.mockResolvedValue(defaultConfig)
})
describe('Form Validation', () => {
it('should require app name', async () => {
const user = userEvent.setup()
render(<AppConfigForm appId="app-1" />)
await waitFor(() => {
expect(screen.getByLabelText(/name/i)).toHaveValue('My App')
})
// Clear name field
await user.clear(screen.getByLabelText(/name/i))
await user.click(screen.getByRole('button', { name: /save/i }))
expect(screen.getByText(/name is required/i)).toBeInTheDocument()
expect(mockedService.updateAppConfig).not.toHaveBeenCalled()
})
it('should validate name length', async () => {
const user = userEvent.setup()
render(<AppConfigForm appId="app-1" />)
await waitFor(() => {
expect(screen.getByLabelText(/name/i)).toBeInTheDocument()
})
// Enter very long name
await user.clear(screen.getByLabelText(/name/i))
await user.type(screen.getByLabelText(/name/i), 'a'.repeat(101))
expect(screen.getByText(/name must be less than 100 characters/i)).toBeInTheDocument()
})
it('should allow empty optional fields', async () => {
const user = userEvent.setup()
mockedService.updateAppConfig.mockResolvedValue({ success: true })
render(<AppConfigForm appId="app-1" />)
await waitFor(() => {
expect(screen.getByLabelText(/name/i)).toHaveValue('My App')
})
// Leave description empty (optional)
await user.click(screen.getByRole('button', { name: /save/i }))
await waitFor(() => {
expect(mockedService.updateAppConfig).toHaveBeenCalled()
})
})
})
describe('Save/Reset Functionality', () => {
it('should save configuration', async () => {
const user = userEvent.setup()
mockedService.updateAppConfig.mockResolvedValue({ success: true })
render(<AppConfigForm appId="app-1" />)
await waitFor(() => {
expect(screen.getByLabelText(/name/i)).toHaveValue('My App')
})
await user.clear(screen.getByLabelText(/name/i))
await user.type(screen.getByLabelText(/name/i), 'Updated App')
await user.click(screen.getByRole('button', { name: /save/i }))
await waitFor(() => {
expect(mockedService.updateAppConfig).toHaveBeenCalledWith(
'app-1',
expect.objectContaining({ name: 'Updated App' })
)
})
expect(screen.getByText(/saved successfully/i)).toBeInTheDocument()
})
it('should reset to default values', async () => {
const user = userEvent.setup()
render(<AppConfigForm appId="app-1" />)
await waitFor(() => {
expect(screen.getByLabelText(/name/i)).toHaveValue('My App')
})
// Make changes
await user.clear(screen.getByLabelText(/name/i))
await user.type(screen.getByLabelText(/name/i), 'Changed Name')
// Reset
await user.click(screen.getByRole('button', { name: /reset/i }))
expect(screen.getByLabelText(/name/i)).toHaveValue('My App')
})
it('should show unsaved changes warning', async () => {
const user = userEvent.setup()
render(<AppConfigForm appId="app-1" />)
await waitFor(() => {
expect(screen.getByLabelText(/name/i)).toHaveValue('My App')
})
// Make changes
await user.type(screen.getByLabelText(/name/i), ' Updated')
expect(screen.getByText(/unsaved changes/i)).toBeInTheDocument()
})
})
describe('Error Handling', () => {
it('should show error on save failure', async () => {
const user = userEvent.setup()
mockedService.updateAppConfig.mockRejectedValue(new Error('Server error'))
render(<AppConfigForm appId="app-1" />)
await waitFor(() => {
expect(screen.getByLabelText(/name/i)).toHaveValue('My App')
})
await user.click(screen.getByRole('button', { name: /save/i }))
await waitFor(() => {
expect(screen.getByText(/failed to save/i)).toBeInTheDocument()
})
})
})
})
```

View File

@@ -1,535 +0,0 @@
# Mocking Guide for Dify Frontend Tests
## ⚠️ Important: What NOT to Mock
### DO NOT Mock Base Components or dify-ui Primitives
**Never mock components from `@/app/components/base/` or from `@langgenius/dify-ui/*`** such as:
- Legacy base (`@/app/components/base/*`): `Loading`, `Spinner`, `Input`, `Badge`, `Tag`
- dify-ui primitives (`@langgenius/dify-ui/*`): `Button`, `Tooltip`, `Dialog`, `Popover`, `DropdownMenu`, `ContextMenu`, `Select`, `AlertDialog`, `Toast`
**Why?**
- These components have their own dedicated tests
- Mocking them creates false positives (tests pass but real integration fails)
- Using real components tests actual integration behavior
```typescript
// ❌ WRONG: Don't mock base components or dify-ui primitives
vi.mock('@/app/components/base/loading', () => () => <div>Loading</div>)
vi.mock('@langgenius/dify-ui/button', () => ({ Button: ({ children }: any) => <button>{children}</button> }))
// ✅ CORRECT: Import and use the real components
import Loading from '@/app/components/base/loading'
import { Button } from '@langgenius/dify-ui/button'
// They will render normally in tests
```
### What TO Mock
Only mock these categories:
1. **API services** (`@/service/*`) - Network calls
1. **Complex context providers** - When setup is too difficult
1. **Third-party libraries with side effects** - `next/navigation`, external SDKs
1. **i18n** - Always mock to return keys
### Zustand Stores - DO NOT Mock Manually
**Zustand is globally mocked** in `web/vitest.setup.ts`. Use real stores with `setState()`:
```typescript
// ✅ CORRECT: Use real store, set test state
import { useAppStore } from '@/app/components/app/store'
useAppStore.setState({ appDetail: { id: 'test', name: 'Test' } })
render(<MyComponent />)
// ❌ WRONG: Don't mock the store module
vi.mock('@/app/components/app/store', () => ({ ... }))
```
See [Zustand Store Testing](#zustand-store-testing) section for full details.
## Mock Placement
| Location | Purpose |
|----------|---------|
| `web/vitest.setup.ts` | Global mocks shared by all tests (`react-i18next`, `zustand`, clipboard, FloatingPortal, Monaco, localStorage`) |
| `web/__mocks__/zustand.ts` | Zustand mock implementation (auto-resets stores after each test) |
| `web/__mocks__/` | Reusable mock factories shared across multiple test files |
| Test file | Test-specific mocks, inline with `vi.mock()` |
Modules are not mocked automatically. Use `vi.mock` in test files, or add global mocks in `web/vitest.setup.ts`.
**Note**: Zustand is special - it's globally mocked but you should NOT mock store modules manually. See [Zustand Store Testing](#zustand-store-testing).
## Essential Mocks
### 1. i18n (Auto-loaded via Global Mock)
A global mock is defined in `web/vitest.setup.ts` and is auto-loaded by Vitest setup.
The global mock provides:
- `useTranslation` - returns translation keys with namespace prefix
- `Trans` component - renders i18nKey and components
- `useMixedTranslation` (from `@/app/components/plugins/marketplace/hooks`)
- `useGetLanguage` (from `@/context/i18n`) - returns `'en-US'`
**Default behavior**: Most tests should use the global mock (no local override needed).
**For custom translations**: Use the helper function from `@/test/i18n-mock`:
```typescript
import { createReactI18nextMock } from '@/test/i18n-mock'
vi.mock('react-i18next', () => createReactI18nextMock({
'my.custom.key': 'Custom translation',
'button.save': 'Save',
}))
```
**Avoid**: Manually defining `useTranslation` mocks that just return the key - the global mock already does this.
### 2. Next.js Router
```typescript
const mockPush = vi.fn()
const mockReplace = vi.fn()
vi.mock('next/navigation', () => ({
useRouter: () => ({
push: mockPush,
replace: mockReplace,
back: vi.fn(),
prefetch: vi.fn(),
}),
usePathname: () => '/current-path',
useSearchParams: () => new URLSearchParams('?key=value'),
}))
describe('Component', () => {
beforeEach(() => {
vi.clearAllMocks()
})
it('should navigate on click', () => {
render(<Component />)
fireEvent.click(screen.getByRole('button'))
expect(mockPush).toHaveBeenCalledWith('/expected-path')
})
})
```
### 2.1 `nuqs` Query State (Preferred: Testing Adapter)
For tests that validate URL query behavior, use `NuqsTestingAdapter` instead of mocking `nuqs` directly.
```typescript
import { renderHookWithNuqs } from '@/test/nuqs-testing'
it('should sync query to URL with push history', async () => {
const { result, onUrlUpdate } = renderHookWithNuqs(() => useMyQueryState(), {
searchParams: '?page=1',
})
act(() => {
result.current.setQuery({ page: 2 })
})
await waitFor(() => expect(onUrlUpdate).toHaveBeenCalled())
const update = onUrlUpdate.mock.calls[onUrlUpdate.mock.calls.length - 1][0]
expect(update.options.history).toBe('push')
expect(update.searchParams.get('page')).toBe('2')
})
```
Use direct `vi.mock('nuqs')` only when URL synchronization is intentionally out of scope.
### 3. Portal Components (with Shared State)
```typescript
// ⚠️ Important: Use shared state for components that depend on each other
let mockPortalOpenState = false
vi.mock('@/app/components/base/portal-to-follow-elem', () => ({
PortalToFollowElem: ({ children, open, ...props }: any) => {
mockPortalOpenState = open || false // Update shared state
return <div data-testid="portal" data-open={open}>{children}</div>
},
PortalToFollowElemContent: ({ children }: any) => {
// ✅ Matches actual: returns null when portal is closed
if (!mockPortalOpenState) return null
return <div data-testid="portal-content">{children}</div>
},
PortalToFollowElemTrigger: ({ children }: any) => (
<div data-testid="portal-trigger">{children}</div>
),
}))
describe('Component', () => {
beforeEach(() => {
vi.clearAllMocks()
mockPortalOpenState = false // ✅ Reset shared state
})
})
```
### 4. API Service Mocks
```typescript
import * as api from '@/service/api'
vi.mock('@/service/api')
const mockedApi = vi.mocked(api)
describe('Component', () => {
beforeEach(() => {
vi.clearAllMocks()
// Setup default mock implementation
mockedApi.fetchData.mockResolvedValue({ data: [] })
})
it('should show data on success', async () => {
mockedApi.fetchData.mockResolvedValue({ data: [{ id: 1 }] })
render(<Component />)
await waitFor(() => {
expect(screen.getByText('1')).toBeInTheDocument()
})
})
it('should show error on failure', async () => {
mockedApi.fetchData.mockRejectedValue(new Error('Network error'))
render(<Component />)
await waitFor(() => {
expect(screen.getByText(/error/i)).toBeInTheDocument()
})
})
})
```
### 5. HTTP and `fetch` Mocking
```typescript
describe('GithubComponent', () => {
beforeEach(() => {
vi.clearAllMocks()
})
it('should display repo info', async () => {
vi.mocked(globalThis.fetch).mockResolvedValueOnce(
new Response(JSON.stringify({ name: 'dify', stars: 1000 }), {
status: 200,
headers: { 'Content-Type': 'application/json' },
}),
)
render(<GithubComponent />)
await waitFor(() => {
expect(screen.getByText('dify')).toBeInTheDocument()
})
})
it('should handle API error', async () => {
vi.mocked(globalThis.fetch).mockResolvedValueOnce(
new Response(JSON.stringify({ message: 'Server error' }), {
status: 500,
headers: { 'Content-Type': 'application/json' },
}),
)
render(<GithubComponent />)
await waitFor(() => {
expect(screen.getByText(/error/i)).toBeInTheDocument()
})
})
})
```
Prefer mocking `@/service/*` modules or spying on `global.fetch` / `ky` clients with deterministic responses. Do not introduce an HTTP interception dependency such as `nock` or MSW unless it is already declared in the workspace or adding it is part of the task.
### 6. Context Providers
```typescript
import { ProviderContext } from '@/context/provider-context'
import { createMockProviderContextValue, createMockPlan } from '@/__mocks__/provider-context'
describe('Component with Context', () => {
it('should render for free plan', () => {
const mockContext = createMockPlan('sandbox')
render(
<ProviderContext.Provider value={mockContext}>
<Component />
</ProviderContext.Provider>
)
expect(screen.getByText('Upgrade')).toBeInTheDocument()
})
it('should render for pro plan', () => {
const mockContext = createMockPlan('professional')
render(
<ProviderContext.Provider value={mockContext}>
<Component />
</ProviderContext.Provider>
)
expect(screen.queryByText('Upgrade')).not.toBeInTheDocument()
})
})
```
### 7. React Query
```typescript
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
const createTestQueryClient = () => new QueryClient({
defaultOptions: {
queries: { retry: false },
mutations: { retry: false },
},
})
const renderWithQueryClient = (ui: React.ReactElement) => {
const queryClient = createTestQueryClient()
return render(
<QueryClientProvider client={queryClient}>
{ui}
</QueryClientProvider>
)
}
```
## Mock Best Practices
### ✅ DO
1. **Use real base components and dify-ui primitives** - Import from `@/app/components/base/` or `@langgenius/dify-ui/*` directly
1. **Use real project components** - Prefer importing over mocking
1. **Use real Zustand stores** - Set test state via `store.setState()`
1. **Reset mocks in `beforeEach`**, not `afterEach`
1. **Match actual component behavior** in mocks (when mocking is necessary)
1. **Use factory functions** for complex mock data
1. **Import actual types** for type safety
1. **Reset shared mock state** in `beforeEach`
### ❌ DON'T
1. **Don't mock base components or dify-ui primitives** (`Loading`, `Input`, `Button`, `Tooltip`, `Dialog`, etc.)
1. **Don't mock Zustand store modules** - Use real stores with `setState()`
1. Don't mock components you can import directly
1. Don't create overly simplified mocks that miss conditional logic
1. Don't leave HTTP mocks or service mock state leaking between tests
1. Don't use `any` types in mocks without necessity
### Mock Decision Tree
```
Need to use a component in test?
│
├─ Is it from @/app/components/base/* or @langgenius/dify-ui/*?
│ └─ YES → Import real component, DO NOT mock
│
├─ Is it a project component?
│ └─ YES → Prefer importing real component
│ Only mock if setup is extremely complex
│
├─ Is it an API service (@/service/*)?
│ └─ YES → Mock it
│
├─ Is it a third-party lib with side effects?
│ └─ YES → Mock it (next/navigation, external SDKs)
│
├─ Is it a Zustand store?
│ └─ YES → DO NOT mock the module!
│ Use real store + setState() to set test state
│ (Global mock handles auto-reset)
│
└─ Is it i18n?
└─ YES → Uses shared mock (auto-loaded). Override only for custom translations
```
## Zustand Store Testing
### Global Zustand Mock (Auto-loaded)
Zustand is globally mocked in `web/vitest.setup.ts` following the [official Zustand testing guide](https://zustand.docs.pmnd.rs/guides/testing). The mock in `web/__mocks__/zustand.ts` provides:
- Real store behavior with `getState()`, `setState()`, `subscribe()` methods
- Automatic store reset after each test via `afterEach`
- Proper test isolation between tests
### ✅ Recommended: Use Real Stores (Official Best Practice)
**DO NOT mock store modules manually.** Import and use the real store, then use `setState()` to set test state:
```typescript
// ✅ CORRECT: Use real store with setState
import { useAppStore } from '@/app/components/app/store'
describe('MyComponent', () => {
it('should render app details', () => {
// Arrange: Set test state via setState
useAppStore.setState({
appDetail: {
id: 'test-app',
name: 'Test App',
mode: 'chat',
},
})
// Act
render(<MyComponent />)
// Assert
expect(screen.getByText('Test App')).toBeInTheDocument()
// Can also verify store state directly
expect(useAppStore.getState().appDetail?.name).toBe('Test App')
})
// No cleanup needed - global mock auto-resets after each test
})
```
### ❌ Avoid: Manual Store Module Mocking
Manual mocking conflicts with the global Zustand mock and loses store functionality:
```typescript
// ❌ WRONG: Don't mock the store module
vi.mock('@/app/components/app/store', () => ({
useStore: (selector) => mockSelector(selector), // Missing getState, setState!
}))
// ❌ WRONG: This conflicts with global zustand mock
vi.mock('@/app/components/workflow/store', () => ({
useWorkflowStore: vi.fn(() => mockState),
}))
```
**Problems with manual mocking:**
1. Loses `getState()`, `setState()`, `subscribe()` methods
1. Conflicts with global Zustand mock behavior
1. Requires manual maintenance of store API
1. Tests don't reflect actual store behavior
### When Manual Store Mocking is Necessary
In rare cases where the store has complex initialization or side effects, you can mock it, but ensure you provide the full store API:
```typescript
// If you MUST mock (rare), include full store API
const mockStore = {
appDetail: { id: 'test', name: 'Test' },
setAppDetail: vi.fn(),
}
vi.mock('@/app/components/app/store', () => ({
useStore: Object.assign(
(selector: (state: typeof mockStore) => unknown) => selector(mockStore),
{
getState: () => mockStore,
setState: vi.fn(),
subscribe: vi.fn(),
},
),
}))
```
### Store Testing Decision Tree
```
Need to test a component using Zustand store?
│
├─ Can you use the real store?
│ └─ YES → Use real store + setState (RECOMMENDED)
│ useAppStore.setState({ ... })
│
├─ Does the store have complex initialization/side effects?
│ └─ YES → Consider mocking, but include full API
│ (getState, setState, subscribe)
│
└─ Are you testing the store itself (not a component)?
└─ YES → Test store directly with getState/setState
const store = useMyStore
store.setState({ count: 0 })
store.getState().increment()
expect(store.getState().count).toBe(1)
```
### Example: Testing Store Actions
```typescript
import { useCounterStore } from '@/stores/counter'
describe('Counter Store', () => {
it('should increment count', () => {
// Initial state (auto-reset by global mock)
expect(useCounterStore.getState().count).toBe(0)
// Call action
useCounterStore.getState().increment()
// Verify state change
expect(useCounterStore.getState().count).toBe(1)
})
it('should reset to initial state', () => {
// Set some state
useCounterStore.setState({ count: 100 })
expect(useCounterStore.getState().count).toBe(100)
// After this test, global mock will reset to initial state
})
})
```
## Factory Function Pattern
```typescript
// __mocks__/data-factories.ts
import type { User, Project } from '@/types'
export const createMockUser = (overrides: Partial<User> = {}): User => ({
id: 'user-1',
name: 'Test User',
email: 'test@example.com',
role: 'member',
createdAt: new Date().toISOString(),
...overrides,
})
export const createMockProject = (overrides: Partial<Project> = {}): Project => ({
id: 'project-1',
name: 'Test Project',
description: 'A test project',
owner: createMockUser(),
members: [],
createdAt: new Date().toISOString(),
...overrides,
})
// Usage in tests
it('should display project owner', () => {
const project = createMockProject({
owner: createMockUser({ name: 'John Doe' }),
})
render(<ProjectCard project={project} />)
expect(screen.getByText('John Doe')).toBeInTheDocument()
})
```

View File

@@ -1,269 +0,0 @@
# Testing Workflow Guide
This guide defines the workflow for generating tests, especially for complex components or directories with multiple files.
## Scope Clarification
This guide addresses **multi-file workflow** (how to process multiple test files). For coverage requirements within a single test file, see `web/docs/test.md` § Coverage Goals.
| Scope | Rule |
|-------|------|
| **Single file** | Complete coverage in one generation (100% function, >95% branch) |
| **Multi-file directory** | Process one file at a time, verify each before proceeding |
## ⚠️ Critical Rule: Incremental Approach for Multi-File Testing
When testing a **directory with multiple files**, **NEVER generate all test files at once.** Use an incremental, verify-as-you-go approach.
### Why Incremental?
| Batch Approach (❌) | Incremental Approach (✅) |
|---------------------|---------------------------|
| Generate 5+ tests at once | Generate 1 test at a time |
| Run tests only at the end | Run test immediately after each file |
| Multiple failures compound | Single point of failure, easy to debug |
| Hard to identify root cause | Clear cause-effect relationship |
| Mock issues affect many files | Mock issues caught early |
| Messy git history | Clean, atomic commits possible |
## Single File Workflow
When testing a **single component, hook, or utility**:
```
1. Read source code completely
2. Run `pnpm analyze-component <path>` (if available)
3. Check complexity score and features detected
4. Write the test file
5. Run test: `pnpm test <file>.spec.tsx`
6. Fix any failures
7. Verify coverage meets goals (100% function, >95% branch)
```
## Directory/Multi-File Workflow (MUST FOLLOW)
When testing a **directory or multiple files**, follow this strict workflow:
### Step 1: Analyze and Plan
1. **List all files** that need tests in the directory
1. **Categorize by complexity**:
- 🟢 **Simple**: Utility functions, simple hooks, presentational components
- 🟡 **Medium**: Components with state, effects, or event handlers
- 🔴 **Complex**: Components with API calls, routing, or many dependencies
1. **Order by dependency**: Test dependencies before dependents
1. **Create a todo list** to track progress
### Step 2: Determine Processing Order
Process files in this recommended order:
```
1. Utility functions (simplest, no React)
2. Custom hooks (isolated logic)
3. Simple presentational components (few/no props)
4. Medium complexity components (state, effects)
5. Complex components (API, routing, many deps)
6. Container/index components (integration tests - last)
```
**Rationale**:
- Simpler files help establish mock patterns
- Hooks used by components should be tested first
- Integration tests (index files) depend on child components working
### Step 3: Process Each File Incrementally
**For EACH file in the ordered list:**
```
┌─────────────────────────────────────────────┐
│ 1. Write test file │
│ 2. Run: pnpm test <file>.spec.tsx │
│ 3. If FAIL → Fix immediately, re-run │
│ 4. If PASS → Mark complete in todo list │
│ 5. ONLY THEN proceed to next file │
└─────────────────────────────────────────────┘
```
**DO NOT proceed to the next file until the current one passes.**
### Step 4: Final Verification
After all individual tests pass:
```bash
# Run all tests in the directory together
pnpm test path/to/directory/
# Check coverage
pnpm test:coverage path/to/directory/
```
## Component Complexity Guidelines
Use `pnpm analyze-component <path>` to assess complexity before testing.
### 🔴 Very Complex Components (Complexity > 50)
**Consider refactoring BEFORE testing:**
- Break component into smaller, testable pieces
- Extract complex logic into custom hooks
- Separate container and presentational layers
**If testing as-is:**
- Use integration tests for complex workflows
- Use `test.each()` for data-driven testing
- Multiple `describe` blocks for organization
- Consider testing major sections separately
### 🟡 Medium Complexity (Complexity 30-50)
- Group related tests in `describe` blocks
- Test integration scenarios between internal parts
- Focus on state transitions and side effects
- Use helper functions to reduce test complexity
### 🟢 Simple Components (Complexity < 30)
- Standard test structure
- Focus on props, rendering, and edge cases
- Usually straightforward to test
### 📏 Large Files (500+ lines)
Regardless of complexity score:
- **Strongly consider refactoring** before testing
- If testing as-is, test major sections separately
- Create helper functions for test setup
- May need multiple test files
## Todo List Format
When testing multiple files, use a todo list like this:
```
Testing: path/to/directory/
Ordered by complexity (simple → complex):
☐ utils/helper.ts [utility, simple]
☐ hooks/use-custom-hook.ts [hook, simple]
☐ empty-state.tsx [component, simple]
☐ item-card.tsx [component, medium]
☐ list.tsx [component, complex]
☐ index.tsx [integration]
Progress: 0/6 complete
```
Update status as you complete each:
- ☐ → ⏳ (in progress)
- ⏳ → ✅ (complete and verified)
- ⏳ → ❌ (blocked, needs attention)
## When to Stop and Verify
**Always run tests after:**
- Completing a test file
- Making changes to fix a failure
- Modifying shared mocks
- Updating test utilities or helpers
**Signs you should pause:**
- More than 2 consecutive test failures
- Mock-related errors appearing
- Unclear why a test is failing
- Test passing but coverage unexpectedly low
## Common Pitfalls to Avoid
### ❌ Don't: Generate Everything First
```
# BAD: Writing all files then testing
Write component-a.spec.tsx
Write component-b.spec.tsx
Write component-c.spec.tsx
Write component-d.spec.tsx
Run pnpm test ← Multiple failures, hard to debug
```
### ✅ Do: Verify Each Step
```
# GOOD: Incremental with verification
Write component-a.spec.tsx
Run pnpm test component-a.spec.tsx ✅
Write component-b.spec.tsx
Run pnpm test component-b.spec.tsx ✅
...continue...
```
### ❌ Don't: Skip Verification for "Simple" Components
Even simple components can have:
- Import errors
- Missing mock setup
- Incorrect assumptions about props
**Always verify, regardless of perceived simplicity.**
### ❌ Don't: Continue When Tests Fail
Failing tests compound:
- A mock issue in file A affects files B, C, D
- Fixing A later requires revisiting all dependent tests
- Time wasted on debugging cascading failures
**Fix failures immediately before proceeding.**
## Integration with Codex's Todo Feature
When using Codex for multi-file testing:
1. **Create a todo list** before starting
1. **Process one file at a time**
1. **Verify each test passes** before asking for the next
1. **Mark todos complete** as you progress
Example prompt:
```
Test all components in `path/to/directory/`.
First, analyze the directory and create a todo list ordered by complexity.
Then, process ONE file at a time, waiting for my confirmation that tests pass
before proceeding to the next.
```
## Summary Checklist
Before starting multi-file testing:
- [ ] Listed all files needing tests
- [ ] Ordered by complexity (simple → complex)
- [ ] Created todo list for tracking
- [ ] Understand dependencies between files
During testing:
- [ ] Processing ONE file at a time
- [ ] Running tests after EACH file
- [ ] Fixing failures BEFORE proceeding
- [ ] Updating todo list progress
After completion:
- [ ] All individual tests pass
- [ ] Full directory test run passes
- [ ] Coverage goals met
- [ ] Todo list shows all complete

View File

@@ -1,117 +1,34 @@
---
name: how-to-write-component
description: Use when writing, refactoring, or reviewing React/TypeScript components in Dify web, especially decisions about component ownership, props/types, URL/query state, Jotai state, async state, generated API contracts, queries/mutations, overlays, effects, navigation, performance, and empty states.
description: Use when implementing or refactoring React/TypeScript components and the task requires decisions about component ownership, feature boundaries, state, data flow, effects, or interaction ownership. Do not use for review-only requests, test-only work, copy-only edits, or styling-only changes.
---
# How To Write A Component
Use this as the component decision guide for Dify web. Existing code is reference material, not automatic precedent; if touched code violates these rules, adapt it and fix equivalent patterns in the same feature branch.
Use this skill to route component architecture decisions to its bundled references. Read only the references required by the current change.
## First Decisions
## Topic Routing
| Question | Default | Promote or extract only when |
| --- | --- | --- |
| Where should code live? | Keep it local to the feature workflow, route, or owner. | Multiple verticals need the same stable primitive. |
| Who owns state, data, and handlers? | The lowest component that uses them. | A parent coordinates shared loading, errors, empty UI, selection, submission, navigation, or one consistent snapshot. |
| Should this become Jotai state? | Keep synchronous UI/form state in component or DOM state. | Siblings need one source of truth, the value drives atoms, or scoped workflow state must survive hidden/unmounted steps. |
| Should URL state enter Jotai? | Let Next.js route params and `nuqs` own URL state and updates. | Query atoms or shared derived atoms need a read-only bridge hydrated at the route/surface boundary. |
| Should this query/mutation become an atom? | Use TanStack Query hooks at the lowest owner. | It reads atom state, feeds derived atoms, or participates in shared Jotai workflow orchestration. |
| Should this be a helper/wrapper? | Prefer direct readable code at the use site. | The name captures a stable domain rule or the wrapper owns real behavior, validation, state, error handling, or semantics. |
| Is an Effect needed? | No. Derive during render or handle the user action in the event handler. | It synchronizes with an external system such as browser APIs, subscriptions, timers, analytics, or imperative DOM/non-React widgets. |
- Component moves, module boundaries, props, types, or owner placement: read [`references/ownership.md`][ownership].
- Dify UI wrappers or primitive state styling: read the package's [Public API authoring] and [Styling] contracts.
- Jotai, form drafts, route identity, URL state, or persistence: read [`references/state.md`][state].
- Generated contracts, nullable API data, Query, mutations, SSR, auth, or workspace state: read [`references/data.md`][data].
- Hotkeys, focus, dialogs, menus, popovers, or other secondary surfaces: read [`references/interactions.md`][interactions] and the overlay guide it references when applicable. Also read [`references/state.md`][state] when the surface owns a draft or other local session state.
- Effects, navigation, memoization, preloading, or render cost: read [`references/runtime.md`][runtime].
## Core Defaults
## Scope And Verification
- Search before adding UI, hooks, helpers, query utilities, or styling patterns. Reuse existing base components, feature components, hooks, utilities, and design styles when they fit.
- Follow Dify's CSS-first Tailwind v4 contract from `packages/dify-ui/README.md` and `packages/dify-ui/AGENTS.md`. Prefer design-system tokens, utilities, and radius mappings over generic Tailwind choices.
- Group feature code by workflow, route, or ownership area: components, hooks, local types, query helpers, atoms, constants, and small utilities should live near the code that changes with them.
- Keep source/default selection, validation, dirty checks, and payload shaping close to the workflow that owns submit behavior. Do not hide flow-specific priority order, fallback behavior, or submit semantics in generic utilities.
- Prefer direct conditionals for small branch-specific decisions, especially form source selection and request payload assembly.
- Loading states for page sections, cards, lists, tables, forms, and drawers should be skeletons scoped to the content being loaded. Use spinners only for small inline busy indicators.
Identify the behavior owner, state lifetime, and public contract from the nearby implementation and relevant references. Keep the change within that vertical slice unless the contract requires changes elsewhere. Verify the changed behavior and complete the owning package's required checks. For Web, read `web/docs/test.md` for test work and `web/docs/lint.md` for static checks. Dify UI verification is owned by `packages/dify-ui/docs/testing.md`.
## Layout And Ownership
## Tailwind CSS
- State-heavy wizards, drawers, modals, and secondary workflows can be a small feature surface: an entry file, one feature-local state file when Jotai is actually needed, and shallow `ui/` owners that match real visual regions.
- The entry file handles route integration, provider wiring, close behavior, and surface mounting. The composition owner handles high-level workflow branching. The closest visual owner handles section branching.
- Repeated TanStack query calls in sibling components are acceptable when each component independently consumes the data; TanStack Query deduplicates and shares cache.
- Pass stable domain identity across boundaries. Do not forward derived presentation state when the receiver can derive it from its own data source.
- A component that owns a visual surface should also own data access, loading, empty, and error states for content rendered inside it unless a parent truly coordinates that state.
- Avoid prop drilling. One pass-through layer is acceptable; repeated forwarding means ownership should move down or into feature-scoped Jotai UI state. Keep server/cache state in Query and API flow.
- Do not replace prop drilling with one large view-model hook threaded through section props. Move each hook, query, derived value, and handler to the concrete section that consumes it.
- Keep callbacks in a parent only for workflow coordination such as form submission, shared selection, batch behavior, or navigation. Otherwise let the child, menu, or row own the action.
- Write canonical Tailwind v4 classes; prefer canonical utilities over equivalent arbitrary values.
- Common forms include `w-105` instead of `w-[420px]`, `px-2.25` instead of `px-[9px]`, `bg-linear-to-b` instead of `bg-gradient-to-b`, `wrap-break-word` instead of `break-words`, and `field-sizing-content` instead of `[field-sizing:content]`.
## Feature-Scoped Jotai
- A Jotai-backed feature has one feature-local state file for shared primitive atoms, query atoms, derived atoms, write-only actions, mutation atoms, submission orchestration, provider exports, and optional scope configuration.
- Keep component-owned synchronous UI state local even inside Jotai features: dialog open flags, menus/popovers, confirmations, field drafts, and selected local options usually belong in component state.
- Use uncontrolled `@langgenius/dify-ui/form` and `@langgenius/dify-ui/field` controls for edit/create forms whose fields are read only at submit time. Initialize query-backed defaults with `defaultValue` and keyed remounts.
- Promote form state to atoms only when another component must react to in-progress values, a draft must survive unmount/remount in the scoped workflow, or multiple steps share the same editable draft before submit.
- Treat `useParams`, route args, and `nuqs` query state as framework-owned state. When atom logic needs those values, hydrate primitive atoms at the route or surface boundary, such as with `useHydrateAtoms(..., { dangerouslyForceHydrate: true })`; keep URL updates in the route/query-state APIs instead of write atoms.
- For async work tied to atom state, use `atomWithQuery` or `atomWithMutation`; write atoms should update only the inputs that drive those atoms. This applies to pure frontend async work as well as network requests, so do not hand-roll loading/error/in-flight state with `useState` or `useRef` for atom-orchestrated async behavior. For component-owned remote work, use `useQuery` or `useMutation` directly.
- Row-local async state belongs to the row owner unless it participates in a shared Jotai workflow or needs atom-scoped reset semantics.
- Leave query and mutation atoms unscoped so they keep shared QueryClient cache and invalidation behavior. Scope resettable primitives and explicit hydration tuples; scope a derived atom only when every dependency should be private to that surface.
- For scoped primitives that are always hydrated by `ScopeProvider`, prefer `atomWithLazy<T>(() => { throw new Error(...) })` when consumers should see a non-null type.
- Order state files by dependency graph: types/constants, primitives, query atoms, query-data derived atoms, business/readiness derived atoms, write actions, mutation atoms, submission orchestration, provider exports.
- Name derived atoms as business facts and write atoms as user or workflow commands. Components should read or write the exact atom they need with `useAtomValue` or `useSetAtom`.
- Menu/dialog `open` state usually stays local, but a scoped atom is acceptable when a composed menu plus secondary surface would otherwise pass confusing `open`/`onClose` props through unrelated layers. Scope that primitive with the surface instance so reset behavior stays local.
- Keep independent dialog lifecycles separate. Avoid one discriminated "current action dialog" atom when dialogs have separate open state, loading guards, or reset behavior.
## Components, Props, And Types
- Type component signatures directly; do not use `FC` or `React.FC`.
- Prefer `function` for top-level components and module helpers. Use arrow functions for local callbacks, handlers, and lambda-style APIs.
- Prefer named exports. Use default exports only where the framework requires them, such as Next.js route files.
- Type simple one-off props inline. Use a named `Props` type only when reused, exported, complex, or clearer.
- Use API-generated or API-returned types at component boundaries. Keep small UI conversion helpers and one-off UI extensions beside the component that needs them.
- Do not create type aliases that only rename another type. Use aliases only for real UI concepts, refinements, or reusable local contracts.
- Name values by their domain role and backend API contract, especially persistent IDs and route params. Normalize framework or route params at the boundary.
- Put fallback and invariant checks in the lowest component that already handles that state. Do not extract helpers whose only behavior is hiding missing display data.
## Generated API And Nullable Data
- Treat generated contracts as authoritative at API, query, mutation, cache, and service boundaries. For enterprise APIs, use `packages/contracts/generated/enterprise/*`.
- Do not hand-write DTO mirrors, widen generated fields/enums, or add parallel frontend enum/status layers unless they model product state not represented by the API.
- Use generated enum objects and union types directly in props, comparisons, status logic, and i18n keys. Presentation-only tone maps should be keyed by generated enums.
- Normalize or coerce only at real boundaries: user-entered forms, search, URL/query params, file names, DOM IDs, or legacy adapters.
- Do not coerce nullable or optional API strings to `''` in query, derived model, or payload-building code. Keep `null` or `undefined` until the final boundary requiring a string.
- Do not use `value || undefined` for mutation fields where `''` means "clear this value". Trim or normalize at the form boundary, then preserve intentional empty strings.
- Prefer nullable-tolerant render props for API-returned rows. Narrow only where a real value is required, such as mutation params, route hrefs, select values, query input, or required React keys.
- Build required values in the same branch that proves them, using `flatMap`, a local loop, or an early return. Avoid truthiness guards, `filter(Boolean)`, `filter(item => item.id)`, and `!` after filters.
- Use conditional spreads or explicit pushes for conditional array items instead of `undefined` placeholders followed by narrowing filters.
- Empty collection fallbacks are for not-yet-loaded query data or genuinely nullable collections at the owning render boundary, not for hiding required API fields.
## Queries And Mutations
- Keep `web/contract/*` as the API shape source of truth and follow the `{ params, query?, body? }` input shape.
- Consume generated queries with `useQuery(consoleQuery.xxx.queryOptions(...))` or `useQuery(marketplaceQuery.xxx.queryOptions(...))`.
- Consume owner-local mutations with `useMutation(consoleQuery.xxx.mutationOptions(...))` or `useMutation(marketplaceQuery.xxx.mutationOptions(...))` when pending/error state is not consumed by feature atoms.
- In `atomWithQuery`, `atomWithInfiniteQuery`, and `atomWithMutation`, return generated `queryOptions()`, `infiniteOptions()`, or `mutationOptions()` directly. Pass `enabled`, `retry`, `placeholderData`, `select`, and pagination options into the generated call instead of spreading options into a hand-built object.
- For generated oRPC options with missing required input, branch the whole input with `input: condition ? validInput : skipToken` and `enabled: Boolean(condition)`. Never place `skipToken` inside a nested placeholder payload or coerce required IDs to `''`.
- When prefetch and render use the same request, extract local query options or a query-options atom so `prefetchQuery` and `useQuery`/`atomWithQuery` share the exact options.
- For custom query or mutation functions, wrap options with TanStack `queryOptions(...)` or `mutationOptions(...)`.
- Avoid pass-through hooks and thin `web/service/use-*` wrappers that only rename generated options. Keep feature hooks for real orchestration, workflow state, or shared domain behavior.
- Put shared cache behavior in `createTanstackQueryUtils(...experimental_defaults...)`. Component or atom callbacks may handle local toasts, closing dialogs, and navigation, but should not replace shared invalidation or patch shared server state locally.
- For overlays that may open heavier secondary content, prefetch from the trigger/menu open event with `queryClient.prefetchQuery(queryOptions)` when `onOpenChange` is available. Do not mount hidden subscribers just to warm cache.
- Do not use deprecated `useInvalid` or `useReset`.
- Prefer `mutate(...)`; use `mutateAsync(...)` only when Promise semantics are required, and wrap awaited calls in `try/catch`.
## Boundaries And Overlays
- Use the first level below a page or tab to organize independent page sections when it adds structure. This layer is layout/semantic first, not automatically the data owner.
- Treat component names, semantic roles, and user- or design-marked visual regions as boundary constraints. Keep adjacent UI as a sibling owner or introduce a correctly named broader owner.
- Keep cohesive forms, menu bodies, and one-off helpers local unless they need their own state, reuse, or semantic boundary.
- Separate hidden secondary surfaces from the trigger's main flow. For dialogs, dropdowns, popovers, and similar branches, extract a small local component when hidden content would obscure the parent.
- Preserve composability by separating behavior ownership from placement ownership: an action can own trigger/open/menu content while the caller owns slots, offsets, and alignment.
- When a dialog, dropdown, or popover accepts controlled `open`, mount it unconditionally unless unmounting is required for performance or reset semantics. Use keyed scope or local state reset instead of `{open && <Surface />}` wrappers.
- When opening a dialog from a menu item, keep the menu and dialog as sibling surfaces. Let the menu command open the dialog, and mount the dialog outside menu popup content.
- For dialogs and alert dialogs, keep the root responsible for `open` wiring and put query/mutation hooks inside the content component when work should mount only after the overlay opens.
- Prefer uncontrolled overlay roots when the library can own open state. Use `onOpenChange` for side effects and CSS/data selectors for open-state styling.
- Avoid wrapper DOM unless it provides layout, semantics, accessibility, state ownership, or library integration. Avoid shallow wrappers, hook-to-props adapters, layout-only render props, children pass-through wrappers, and prop renaming unless they add real behavior or a real boundary.
## Effects, Navigation, And Performance
- Use Effects only to synchronize with external systems. Do not use Effects to transform props/state for rendering, handle user actions, copy state, reset state from props, or fetch data.
- For forms initialized from query data, prefer keyed remounts or surface-entry atom hydration over Effects that copy query data into form state.
- Prefer framework data APIs or TanStack Query for data fetching.
- Prefer `Link` for normal navigation. Use router APIs only for command-flow side effects such as mutation success, guarded redirects, or form submission.
- Before using `memo`, move changing state down to the smallest component that uses it. If state must wrap stable content, lift the stable content up and pass it as `children`.
- Avoid `memo`, `useMemo`, and `useCallback` unless there is a clear performance reason.
[Public API authoring]: ../../../packages/dify-ui/docs/authoring.md
[Styling]: ../../../packages/dify-ui/docs/styling.md
[data]: references/data.md
[interactions]: references/interactions.md
[ownership]: references/ownership.md
[runtime]: references/runtime.md
[state]: references/state.md

View File

@@ -0,0 +1,58 @@
# Component Data And Queries
Read this document when a component consumes generated contracts, nullable API values, TanStack Query, mutations, prefetching, authentication, or workspace state.
## Generated Contracts
- Treat generated contracts as authoritative at API, query, mutation, cache, and service boundaries. Enterprise APIs use `packages/contracts/generated/enterprise/*`.
- Backend Pydantic and OpenAPI schemas own API shape. Follow the generated `{ params, query?, body? }` input shape; when it is wrong, fix the backend schema and regenerate `packages/contracts/generated/*`.
- Do not hand-write DTO mirrors, widen generated fields or enums, edit generated output, or add a parallel frontend status layer unless it models product state absent from the API.
- Check deprecated markers, schema shape, and the actual consumer before assuming that a generated operation is ready to use.
- When a ready generated operation exists for the changed call, migrate deprecated operations and remove the replaced layer instead of adding compatibility wrappers.
- Normalize only at real boundaries such as user input, search, URL params, filenames, DOM IDs, or a required legacy adapter.
- Preserve `null`, `undefined`, and intentional empty strings until the final boundary. Do not use `value || undefined` when an empty string means clearing a field.
- Build required values in the branch that proves them. Do not use truthiness filters, non-null assertions, or placeholders to conceal missing required input or discard valid `0`, `false`, or empty-string values.
## Queries
- Use generated options directly with `useQuery(consoleQuery.xxx.queryOptions(...))`, `marketplaceQuery`, or the equivalent generated client.
- If query input comes from atom state, keep it in `atomWithQuery`; do not unwrap the atom in a component solely to call `useQuery`.
- For missing required input, branch the whole generated input with `skipToken`. Add `enabled` only for an independent execution condition; do not put `skipToken` inside a placeholder payload or coerce IDs to empty strings.
- Return generated `queryOptions()`, `infiniteOptions()`, or `mutationOptions()` directly from TanStack Query atoms. Pass supported options into the generated call instead of spreading into a parallel object.
- For the same logical request, preserve key, input, operation, and result contracts. Reuse exact options only when
transport, context, and cache policy are shared; imperative and observer freshness may differ. Do not extract a helper
merely to reuse input construction.
- Avoid pass-through service hooks that only rename generated options. Keep feature hooks for actual orchestration or shared domain behavior.
## Mutations And Cache
- Use generated `mutationOptions()` directly for owner-local mutations.
- Do not introduce deprecated `useInvalid` or `useReset` APIs.
- Put shared invalidation, retries, and cache behavior in `createTanstackQueryUtils(...experimental_defaults...)`. In oRPC v1, caller options override defaults, including callbacks. Local callbacks may own toast, close, and navigation effects but must preserve shared cache behavior.
- Prefer `mutate(...)`. Use `mutateAsync(...)` only when Promise composition is required, and catch awaited failures.
- Preserve intentional empty values and current list/detail ownership when updating data. Do not add optimistic updates without a verified owner contract.
## Prefetch And Hidden Surfaces
- Prefetch expensive secondary content from the trigger or menu-open event when it benefits the visible path. Do not mount hidden subscribers solely to warm the cache.
- Use `query` or `infiniteQuery` for imperative access. `staleTime` defines cache acceptance; `select` projects the return
value without replacing cached query-function data. Imperative queries default to no retries when `retry` is not
configured, and observer-only `enabled` does not prevent an imperative call.
- Migrate deprecated `fetchQuery`, `prefetchQuery`, `ensureQueryData`, and their infinite variants when the current `query` or `infiniteQuery` contract applies. A `staleTime` of `0` treats data as stale; a finite value accepts that freshness window; `Infinity` accepts data until invalidation; `'static'` accepts available data even after invalidation.
- `await` blocks, `return` transfers the Promise, and `void` discards its value without handling rejection. Handle
rejection before discarding a potentially rejecting Promise; use `.catch(noop)` only for intentional silence or
feedback owned elsewhere. Hard server gates await the query and preserve rejection.
## SSR, Authentication, And Workspace
- Static configuration owns path-invariant routing. Request-dependent authentication, setup, role, and tenant decisions belong to SSR or runtime decision boundaries.
- Distinguish soft SSR cache warming from authoritative decisions. Prefetched or placeholder data must not grant access or represent successful availability.
- Treat Server Components as query prefetch-and-dehydrate owners by default. Do not render or pass an imperative query
result when a browser observer can revalidate the same data unless ownership and freshness explicitly prevent drift.
- Non-blocking RSC streaming requires pending-query dehydration without redacting Next.js server errors, a
`HydrationBoundary` around the same-key client consumer, and Suspense when that content must be server-rendered.
- Never reuse tenant-scoped state after switching workspaces. Discard it at the switch boundary or isolate it by workspace identity.
- Trace the current switch flow before choosing cache handling: server switch plus full reload is a tenant boundary, not ordinary CRUD invalidation. Include workspace identity in varying query keys when no full-reload boundary applies, and trace the backend contract before interchanging `workspace_id` and `tenant_id`.
- Do not make product or authorization decisions from bootstrap defaults. Wait for authoritative data, or render an explicit loading or error state.
- Preserve an existing client fallback until server API-unavailable behavior has an explicit owner.
- Keep loading and Suspense behavior inside the feature that owns the request. Do not add fake global data merely to bypass that boundary.

View File

@@ -0,0 +1,27 @@
# Component Interactions And Overlays
Read this document when a change involves application hotkeys, focus, dialogs, menus, popovers, or other secondary surfaces. Overlay primitive selection and layering are owned by the [overlay contract].
## Focus And Semantics
- Preserve a visible focus indicator on the final focusable element. Styled Dify UI controls usually provide it; headless anatomy parts and direct trigger exports may not.
- Native buttons, links, custom trigger renderers, clickable rows, icon controls, and menu-like items must retain their correct native semantics and accessible name.
- Do not hide an outline without an equivalent visible `focus-visible` treatment. Follow an existing Dify UI pattern rather than inventing a call-site style.
## Keyboard Commands
- Keep widget navigation, dialog dismissal, and editor commands in their local primitive or owner.
- For Web application commands, follow [Keyboard commands] for TanStack registration, typed bindings, targets, event consumption, display, and verification. Do not recreate that policy in a wrapper or a second command framework.
## Secondary Surfaces
- Follow the [overlay contract] for primitive choice and shared mechanics. The nearest consumer `AGENTS.md` owns application-specific composite reuse policy.
- Separate behavior ownership from placement ownership: the action may own trigger, open state, and menu content while the caller owns slots, offsets, and alignment.
- Keep menu and dialog surfaces as siblings when a menu command opens a dialog. Mount the dialog outside popup content.
- Use the [overlay contract] to determine content lifetime and preserve the Root's closing lifecycle. Follow [state ownership] for draft placement and semantic identity; portal placement alone does not locate the state owner.
- Place query subscriptions and mutation observers at the owner whose lifetime matches when they should run. Mounted-session work may belong inside content; work that must start or stop exactly with `open` needs an explicit open-state condition.
- Prefer primitive-owned open state unless another owner must observe or coordinate it. Analytics callbacks and local cleanup alone do not require a controlled root.
[overlay contract]: ../../../../packages/dify-ui/docs/overlays.md
[Keyboard commands]: ../../../../web/docs/hotkeys.md
[state ownership]: state.md

View File

@@ -0,0 +1,45 @@
# Component Ownership And Modules
Read this document when adding, moving, splitting, or refactoring React components or feature modules.
## Vertical Modules
- Organize code by product workflow, route, or behavior owner. Keep components, hooks, local types, atoms, query helpers, tests, and small utilities beside the code that changes with them.
- Name page and tab folders after the current route, tab, or user-visible surface. Do not preserve stale parent groupings that no longer own multiple surfaces.
- Split a growing page or tab by product or visual owners. Keep the feature root for its public entrypoint and genuinely cross-owner coordination.
- Import other features only through explicit public entrypoints. Avoid barrels that merely re-export secondary owners.
- Promote code outside a feature only when multiple verticals use the same stable contract. Possible future reuse is not sufficient.
## Component Ownership
- Put state, data access, loading, empty, error, and handlers in the lowest owner that uses them and whose mounted lifetime matches the required persistence.
- Keep coordination in a parent only when it needs one consistent snapshot, the value must intentionally survive the local owner's unmount, or the parent coordinates submission, shared selection, batch behavior, navigation, or cross-section loading and errors.
- Repeated TanStack Query hooks for the same key and input in Client Component siblings under one QueryClient are
acceptable; shared cache is not a reason to hoist. Separate Server Component QueryClients do not share it, so
request-level deduplication needs an identified request-local cache or verified framework or transport owner.
- Pass stable domain identity across boundaries. Do not pass raw server data together with separately derived flags for the same concept.
- Revisit prop forwarding when intermediate components obscure the behavior owner; keep clear data flow rather than introducing shared state merely to avoid passing props.
- Do not replace prop drilling with one large view-model hook. Move each query, derived value, and handler to the concrete owner that consumes it.
- Keep source selection, defaults, validation, dirty checks, and payload shaping beside the workflow that owns submission.
## Boundaries
- Prefer reusing or extending the component that already owns an interaction over rebuilding that behavior in a parallel component.
- State-heavy wizards, drawers, modals, and secondary workflows can form a small vertical surface with an entrypoint, optional feature-local state, and shallow owners matching real visual regions.
- The entrypoint owns route integration, provider wiring, placement, and open-state coordination. A content or session owner keeps state scoped to that mounted surface.
- Judge hook lifetime by the component that declares the hook and the primitive's mount contract, not only by where its rendered controls appear in JSX.
- Separate hidden dialogs, dropdowns, and popovers into small local owners when their content obscures the parent flow.
- Keep cohesive forms, menu bodies, and one-off helpers local unless they have their own state, reuse, or semantic boundary.
- Extract components or hooks when they clarify ownership or hide a cohesive implementation; keep logic local when extraction only shortens the file or relocates the same coordination.
- Avoid wrapper components and wrapper DOM that only rename props, pass children through, or hide the real primitive. A wrapper must own behavior, validation, state, accessibility, layout, or library integration.
- Keep feature workflows out of shared components: do not encode one feature through many boolean props or import its copy, routes, and API contracts into a generic component. Do not pass pre-rendered fragments merely to avoid assigning the behavior to its owner.
- Loading states for page sections, cards, lists, tables, forms, and drawers should use skeletons scoped to the loaded content. Reserve spinners for small inline busy indicators.
## Components And Types
- Choose component declaration and export forms from the actual component contract, framework requirements, and enforced package rules. Existing style is context, not authority; do not rewrite unaffected code solely to normalize `FC`, `function`, arrow-function, named-export, or default-export forms.
- Use API-generated or API-returned types at component boundaries. Keep one-off UI refinements and conversions beside their owner.
- Name props and converted data after their domain/API role, preserving traceability to the original contract.
- Preserve domain value types for selections. Do not widen enums, unions, booleans, numbers, objects, or nullable values to `string` before a real boundary requires it.
- Avoid generic `common.tsx` buckets and aliases that only rename another type. Name files, values, and public types after their domain role.
- Put fallback and invariant checks in the lowest component that already renders that state. Do not extract helpers whose only purpose is hiding missing display data.

View File

@@ -0,0 +1,24 @@
# Component Effects, Navigation, And Runtime Cost
Read this document when a change introduces Effects, navigation side effects, memoization, preloading, or render-cost optimizations.
## Effects
- Keep render pure: do not read or write `ref.current` during render except for predictable null-guarded lazy initialization. Update interaction-owned refs in event handlers, synchronize external-system refs after commit, and use state or derivation for rendered values.
- Use Effects only to synchronize with a named external system such as a browser API, subscription, timer, analytics integration, non-React widget, or imperative DOM API.
- Do not use Effects to transform render state, handle user actions, copy query data, reset state from props, or fetch data owned by framework APIs or TanStack Query.
- Initialize query-backed form sessions after their defaults are available instead of copying data through Effects. Use a stable semantic identity key when the represented identity changes; use the intended surface lifecycle for per-session reset.
## Navigation
- Use `Link` for ordinary navigation.
- Use router APIs for command-flow side effects such as mutation success, guarded redirects, or form submission.
- Keep shareable navigation state in the URL rather than hidden component state.
## Runtime Cost
- Move changing state to the smallest consumer before considering memoization. Stable parent content can be lifted and passed as children.
- Avoid `memo`, `useMemo`, and `useCallback` unless identity or computation has a demonstrated consumer or measurable cost.
- Start independent remote work together and await it near the branch that consumes it. Avoid introducing request waterfalls.
- Load heavy optional surfaces on demand when they sit behind a dialog, tab, command, or feature activation.
- Use narrow selectors or field-level atoms for broad stores and subscriptions. Do not optimize simple primitive expressions merely for stylistic consistency.

View File

@@ -0,0 +1,44 @@
# Component State And URL Ownership
Read this document when a change involves Jotai, form drafts, route identity, shared client state, or local persistence.
## Choose The Owner
- Keep synchronous state local when one component owns it: dialog and menu state, confirmations, field drafts, and local selections usually belong to the component or DOM.
- Use feature-scoped Jotai when siblings need one source of truth, values drive other atoms, or a scoped workflow must preserve state across hidden or unmounted steps.
- Keep server and cache state in TanStack Query. Use existing feature stores for complex, high-frequency interaction state such as workflow canvas drag, resize, and runtime panels.
- Use feature-owned storage only for low-frequency client preferences, dismissed notices, and UI defaults. Live application state does not belong in local storage.
## Forms And Sessions
- Follow the [form contract] for field controlledness and the [overlay contract] for Root/content mounting and state lifetime. These primitive contracts also apply when reviewing a consumer.
- Choose the Web draft owner from the required lifetime. Keep mounted-session drafts in the content owner; start with the lowest shared React owner when another component needs the draft or it must survive unmounting. Use feature-scoped atoms only when their coordination or persistence contract is needed.
- For query-backed defaults, establish the form session after the required defaults are available. `defaultValue` initializes the current mount; a stable semantic identity key may create a fresh snapshot when the represented identity changes. Do not use a generated key as a routine reset command.
- Keep validation, source priority, fallback behavior, dirty checks, and payload assembly in the workflow that owns submission.
- Derive booleans, disabled flags, default tabs, and loading labels from current state. Do not mirror one value into competing prop, default, and local sources; controlled state alone is not a competing-source defect.
- Do not use local state to fake server data or generated contract fields, or connect a feature mock shell to an unrelated API before its actual contract is confirmed.
## Route And URL State
- Treat `useParams`, route arguments, and `nuqs` as the owners of URL identity and updates.
- Hydrate a primitive atom at the route or surface boundary only when query atoms or shared derived atoms require route identity. Keep URL writes in route and query-state APIs.
- Within one route-owned feature, choose one route-identity source. Do not hydrate route identity into atoms while also threading the same ID through multiple component layers.
- Put shareable filters, tabs, selected panels, pagination, and search state in the URL. Keep one-shot navigation signals and transient UI state out of persistent subscriptions.
## Jotai And Query
- A Jotai-backed feature may keep one feature-local state module ordered by dependency: types and constants, primitives, query atoms, query-data derivations, business facts, commands, mutations, submission orchestration, and provider exports.
- Use `atomWithQuery` or `atomWithMutation` for async work driven by atom state. Do not hand-roll loading, error, or in-flight state for atom-orchestrated work.
- Use field-specific derived atoms for query results. `jotai-tanstack-query` does not provide TanStack Query tracked properties, so reading a whole query atom subscribes to the entire observer result.
- Leave query and mutation atoms unscoped so they retain the shared QueryClient cache. Scope resettable primitives and hydration tuples; scope a derived atom only when all dependencies should be private to the surface.
- Use non-null lazy primitives for values always hydrated by a scope provider. Name derived atoms as business facts and write atoms as user or workflow commands.
- Keep independent dialog lifecycles separate. A scoped open-state atom is acceptable only when composed sibling surfaces would otherwise pass confusing lifecycle props through unrelated owners.
## Persistence
- Use feature-owned storage modules built on `createLocalStorageState`; callers should not scatter direct storage access or raw keys.
- Persist high-frequency interaction state only on commit or after updates settle.
- Do not add ad hoc global event listeners for shared state. Centralize subscriptions through the owning atom, store, or subscription hook.
[form contract]: ../../../../packages/dify-ui/docs/forms.md
[overlay contract]: ../../../../packages/dify-ui/docs/overlays.md

View File

@@ -1,33 +0,0 @@
---
name: karpathy-guidelines
description: Lightweight coding guardrails for making focused, simple, and verifiable changes in this repo. Use for all coding work.
---
# Karpathy Guidelines
Use this skill whenever you touch code in this repository.
## Principles
- Keep the change small and directly tied to the user request.
- Prefer the simplest implementation that fits the existing codebase.
- Read the nearby code first, then match its patterns.
- Avoid unrelated refactors, broad rewrites, or style churn.
- Preserve existing behavior unless the user explicitly asked to change it.
- Treat regressions as a signal to narrow the change, not to add workaround layers.
## Workflow
1. Inspect the current implementation and tests around the change.
2. Make the smallest coherent edit.
3. Add or update focused tests when the behavior changes or the risk is non-trivial.
4. Run the narrowest relevant verification first.
5. Report exactly what was verified and anything left unverified.
## Review Checklist
- Does this change solve the stated problem without expanding scope?
- Did it preserve existing route/component/data-flow semantics?
- Are new abstractions justified by real complexity?
- Are tests focused on the behavior that could regress?
- Are unrelated files and generated artifacts left alone?

View File

@@ -1 +0,0 @@
../../.agents/skills/component-refactoring

View File

@@ -1 +0,0 @@
../../.agents/skills/karpathy-guidelines

View File

@@ -1,7 +1,7 @@
# Development with devcontainer
This project includes a devcontainer configuration that allows you to open the project in a container with a fully configured development environment.
Both frontend and backend environments are initialized when the container is started.
The create hook installs workspace JavaScript dependencies and `uv`; the start hook synchronizes backend dependencies. Follow the [backend setup](../api/README.md) and [frontend guide](../web/README.md) to configure environment files and start services.
## GitHub Codespaces
@@ -19,20 +19,6 @@ if you have VS Code installed, you can click the button above to open this proje
You can learn more in the [Dev Containers documentation](https://code.visualstudio.com/docs/devcontainers/containers).
## Pros of Devcontainer
Unified Development Environment: By using devcontainers, you can ensure that all developers are developing in the same environment, reducing the occurrence of "it works on my machine" type of issues.
Quick Start: New developers can set up their development environment in a few simple steps, without spending a lot of time on environment configuration.
Isolation: Devcontainers isolate your project from your host operating system, reducing the chance of OS updates or other application installations impacting the development environment.
## Cons of Devcontainer
Learning Curve: For developers unfamiliar with Docker and VS Code, using devcontainers may be somewhat complex.
Performance Impact: While usually minimal, programs running inside a devcontainer may be slightly slower than those running directly on the host.
## Troubleshooting
if you see such error message when you open this project in codespaces:

View File

@@ -12,7 +12,7 @@
"features": {
"ghcr.io/devcontainers/features/node:1": {
"nodeGypDependencies": true,
"version": "lts"
"version": "24.20.0"
},
"ghcr.io/devcontainers-extra/features/npm-package:1": {
"package": "typescript",
@@ -46,4 +46,4 @@
// Configure tool-specific properties.
// "customizations": {},
// Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
}
}

View File

@@ -37,3 +37,7 @@ indent_size = 2
[package.json]
indent_style = space
indent_size = 2
# Oxlint writes its generated suppression baseline without a final newline.
[oxlint-suppressions.json]
insert_final_newline = false

View File

@@ -1,13 +0,0 @@
have_fun: false
memory_config:
disabled: false
code_review:
disable: true
comment_severity_threshold: MEDIUM
max_review_comments: -1
pull_request_opened:
help: false
summary: false
code_review: false
include_drafts: false
ignore_patterns: []

3
.gitattributes vendored
View File

@@ -9,3 +9,6 @@
# Codegen output must stay byte-identical across platforms so
# `pnpm tree:check` in CI does not trip on CRLF rewrites.
*.generated.ts text eol=lf
# Skill scripts run on every platform, so keep LF line endings.
/skills/** text=auto eol=lf

127
.github/CODEOWNERS vendored
View File

@@ -6,8 +6,8 @@
* @crazywoola @laipz8200
# ESLint suppression file is maintained by autofix.ci pruning.
/eslint-suppressions.json
# Lint bulk suppression baselines.
/oxlint-suppressions.json
# CODEOWNERS file
/.github/CODEOWNERS @laipz8200 @crazywoola
@@ -26,43 +26,41 @@
/cli/ @GareArc
/.github/workflows/cli-tests.yml @GareArc
# Dify Agent
/dify-agent/ @BeautyyuYanli
# E2E
/e2e/ @lyzno1
/.github/workflows/web-e2e.yml @lyzno1
# Backend (default owner, more specific rules below will override)
/api/ @QuantumGhost
# Backend - MCP
/api/core/mcp/ @Nov1c444
/api/core/entities/mcp_provider.py @Nov1c444
/api/services/tools/mcp_tools_manage_service.py @Nov1c444
/api/controllers/mcp/ @Nov1c444
/api/controllers/console/app/mcp_server.py @Nov1c444
# Backend - Tests
# Backend - Tests (default owners, domain-specific rules below will override)
/api/tests/ @laipz8200 @QuantumGhost
/api/tests/**/*mcp* @Nov1c444
# Backend - Workflow - Engine (Core graph execution engine)
/api/core/workflow/graph_engine/ @laipz8200 @QuantumGhost
/api/core/workflow/runtime/ @laipz8200 @QuantumGhost
/api/core/workflow/graph/ @laipz8200 @QuantumGhost
/api/core/workflow/graph_events/ @laipz8200 @QuantumGhost
/api/core/workflow/node_events/ @laipz8200 @QuantumGhost
# Backend - Workflow - Nodes (Agent, Iteration, Loop, LLM)
/api/core/workflow/nodes/agent/ @Nov1c444
/api/core/workflow/nodes/iteration/ @Nov1c444
/api/core/workflow/nodes/loop/ @Nov1c444
/api/core/workflow/nodes/llm/ @Nov1c444
/api/tests/*/core/rag/ @JohnJyong
/api/tests/*/services/rag_pipeline/ @JohnJyong
/api/tests/*/services/dataset_service/ @JohnJyong
/api/tests/*/controllers/console/datasets/ @JohnJyong
/api/tests/*/controllers/service_api/dataset/ @JohnJyong
/api/tests/*/vdb/ @JohnJyong
/api/tests/*/core/plugin/ @WH-2099
/api/tests/*/services/plugin/ @WH-2099
/api/tests/*/controllers/inner_api/plugin/ @WH-2099
/api/tests/*/plugin/ @WH-2099
/api/tests/*/controllers/trigger/ @CourTeous33
/api/tests/*/core/trigger/ @CourTeous33
/api/tests/*/trigger/ @CourTeous33
/api/tests/*/controllers/console/billing/ @zyssyz123
/api/tests/*/services/enterprise/ @GareArc
/api/tests/*/migrations/ @snakevash @laipz8200 @MRZHUH
# Backend - RAG (Retrieval Augmented Generation)
/api/core/rag/ @JohnJyong
/api/services/knowledge/ @JohnJyong
/api/services/rag_pipeline/ @JohnJyong
/api/services/dataset_service.py @JohnJyong
/api/services/knowledge_service.py @JohnJyong
/api/services/external_knowledge_service.py @JohnJyong
/api/services/hit_testing_service.py @JohnJyong
/api/services/metadata_service.py @JohnJyong
/api/services/vector_service.py @JohnJyong
/api/services/entities/knowledge_entities/ @JohnJyong
/api/services/entities/external_knowledge_entities/ @JohnJyong
/api/controllers/console/datasets/ @JohnJyong
@@ -107,7 +105,6 @@
/api/core/app/layers/trigger_post_layer.py @CourTeous33
/api/services/trigger/ @CourTeous33
/api/models/trigger.py @CourTeous33
/api/fields/workflow_trigger_fields.py @CourTeous33
/api/repositories/workflow_trigger_log_repository.py @CourTeous33
/api/repositories/sqlalchemy_workflow_trigger_log_repository.py @CourTeous33
/api/libs/schedule_utils.py @CourTeous33
@@ -128,15 +125,15 @@
/api/tasks/async_workflow_tasks.py @Mairuis
# Backend - Billing
/api/services/billing_service.py @hj24 @zyssyz123
/api/controllers/console/billing/ @hj24 @zyssyz123
/api/services/billing_service.py @zyssyz123
/api/controllers/console/billing/ @zyssyz123
# Backend - Enterprise
/api/configs/enterprise/ @GarfieldDai @GareArc
/api/services/enterprise/ @GarfieldDai @GareArc
/api/services/feature_service.py @GarfieldDai @GareArc
/api/controllers/console/feature.py @GarfieldDai @GareArc
/api/controllers/web/feature.py @GarfieldDai @GareArc
/api/configs/enterprise/ @GareArc
/api/services/enterprise/ @GareArc
/api/services/feature_service.py @GareArc
/api/controllers/console/feature.py @GareArc
/api/controllers/web/feature.py @GareArc
# Backend - Database Migrations
/api/migrations/ @snakevash @laipz8200 @MRZHUH
@@ -147,9 +144,14 @@
# Frontend
/web/ @iamjoel
# Frontend - Tooling
/lint.config.ts @hyoban @lyzno1
/eslint.config.mjs @hyoban @lyzno1
/knip.config.ts @hyoban @lyzno1
/vite.config.ts @hyoban @lyzno1
# Frontend - Platform and Features
/web/config/ @lyzno1
/web/contract/ @lyzno1
/web/env.ts @lyzno1
/web/features/ @lyzno1
/web/hooks/ @lyzno1
@@ -208,7 +210,6 @@
/web/app/components/rag-pipeline/store/ @iamjoel @zxhlyh
# Frontend - RAG - Documents List
/web/app/components/datasets/documents/list.tsx @iamjoel @WTW0313
/web/app/components/datasets/documents/create-from-pipeline/ @iamjoel @WTW0313
# Frontend - RAG - Segments List
@@ -227,22 +228,22 @@
/web/app/components/plugins/marketplace/ @iamjoel @Yessenia-d
# Frontend - Login and Registration
/web/app/signin/ @douxc @iamjoel
/web/app/signup/ @douxc @iamjoel
/web/app/reset-password/ @douxc @iamjoel
/web/app/install/ @douxc @iamjoel
/web/app/init/ @douxc @iamjoel
/web/app/forgot-password/ @douxc @iamjoel
/web/app/account/ @douxc @iamjoel
/web/app/signin/ @iamjoel
/web/app/signup/ @iamjoel
/web/app/reset-password/ @iamjoel
/web/app/install/ @iamjoel
/web/app/init/ @iamjoel
/web/app/forgot-password/ @iamjoel
/web/app/account/ @iamjoel
# Frontend - Service Authentication
/web/service/base.ts @douxc @iamjoel
/web/service/base.ts @iamjoel
# Frontend - WebApp Authentication and Access Control
/web/app/(shareLayout)/components/ @douxc @iamjoel
/web/app/(shareLayout)/webapp-signin/ @douxc @iamjoel
/web/app/(shareLayout)/webapp-reset-password/ @douxc @iamjoel
/web/app/components/app/app-access-control/ @douxc @iamjoel
/web/app/(shareLayout)/components/ @iamjoel
/web/app/(shareLayout)/webapp-signin/ @iamjoel
/web/app/(shareLayout)/webapp-reset-password/ @iamjoel
/web/app/components/app/app-access-control/ @iamjoel
# Frontend - Explore Page
/web/app/components/explore/ @CodingOnStar @iamjoel
@@ -261,17 +262,37 @@
/web/app/components/base/**/*.spec.tsx @hyoban @CodingOnStar
# Frontend - Utils and Hooks
/web/utils/classnames.ts @iamjoel @zxhlyh
/web/utils/time.ts @iamjoel @zxhlyh
/web/utils/format.ts @iamjoel @zxhlyh
/web/utils/clipboard.ts @iamjoel @zxhlyh
# Frontend - Billing and Education
/web/app/components/billing/ @iamjoel @zxhlyh
/web/app/education-apply/ @iamjoel @zxhlyh
/web/app/education/ @iamjoel @zxhlyh
# Frontend - Workspace
/web/app/components/header/account-dropdown/workplace-selector/ @iamjoel @zxhlyh
# Frontend - App Shell and Console Bootstrap
/web/app/layout.tsx @iamjoel @lyzno1
/web/app/error.tsx @iamjoel @lyzno1
/web/app/(commonLayout)/layout.tsx @iamjoel @lyzno1
/web/app/(commonLayout)/providers.tsx @iamjoel @lyzno1
/web/app/(commonLayout)/hydration-boundary.tsx @iamjoel @lyzno1
/web/app/(commonLayout)/profile-bootstrap-gate.tsx @iamjoel @lyzno1
/web/app/(commonLayout)/error.tsx @iamjoel @lyzno1
/web/app/account/(commonLayout)/layout.tsx @iamjoel @lyzno1
/web/app/components/main-nav/* @iamjoel @lyzno1
/web/app/components/main-nav/components/* @iamjoel @lyzno1
/web/context/query-client.tsx @iamjoel @lyzno1
/web/context/query-client-server.ts @iamjoel @lyzno1
/web/proxy.ts @iamjoel @lyzno1
/web/app/auth/refresh/route.ts @iamjoel @lyzno1
/web/service/server.ts @iamjoel @lyzno1
# Frontend - Browser Mode Tests
/web/app/**/*.browser.spec.ts @lyzno1
/web/app/**/*.browser.spec.tsx @lyzno1
# Docker
/docker/* @laipz8200

View File

@@ -1,17 +1,17 @@
title: "General Discussion"
title: 'General Discussion'
body:
- type: checkboxes
attributes:
label: Self Checks
description: "To make sure we get to you in time, please check the following :)"
description: 'To make sure we get to you in time, please check the following :)'
options:
- label: I have searched for existing issues [search for existing issues](https://github.com/langgenius/dify/issues), including closed ones.
required: true
- label: I confirm that I am using English to submit this report (我已阅读并同意 [Language Policy](https://github.com/langgenius/dify/issues/1542)).
required: true
- label: "[FOR CHINESE USERS] 请务必使用英文提交 Issue,否则会被关闭。谢谢!:)"
- label: '[FOR CHINESE USERS] 请务必使用英文提交 Issue,否则会被关闭。谢谢!:)'
required: true
- label: "Please do not modify this template :) and fill in all the required fields."
- label: 'Please do not modify this template :) and fill in all the required fields.'
required: true
- type: textarea
attributes:

View File

@@ -1,17 +1,17 @@
title: "Help"
title: 'Help'
body:
- type: checkboxes
attributes:
label: Self Checks
description: "To make sure we get to you in time, please check the following :)"
description: 'To make sure we get to you in time, please check the following :)'
options:
- label: I have searched for existing issues [search for existing issues](https://github.com/langgenius/dify/issues), including closed ones.
required: true
- label: I confirm that I am using English to submit this report (我已阅读并同意 [Language Policy](https://github.com/langgenius/dify/issues/1542)).
required: true
- label: "[FOR CHINESE USERS] 请务必使用英文提交 Issue,否则会被关闭。谢谢!:)"
- label: '[FOR CHINESE USERS] 请务必使用英文提交 Issue,否则会被关闭。谢谢!:)'
required: true
- label: "Please do not modify this template :) and fill in all the required fields."
- label: 'Please do not modify this template :) and fill in all the required fields.'
required: true
- type: textarea
attributes:

View File

@@ -3,15 +3,15 @@ body:
- type: checkboxes
attributes:
label: Self Checks
description: "To make sure we get to you in time, please check the following :)"
description: 'To make sure we get to you in time, please check the following :)'
options:
- label: I have searched for existing issues [search for existing issues](https://github.com/langgenius/dify/issues), including closed ones.
required: true
- label: I confirm that I am using English to submit this report (我已阅读并同意 [Language Policy](https://github.com/langgenius/dify/issues/1542)).
required: true
- label: "[FOR CHINESE USERS] 请务必使用英文提交 Issue,否则会被关闭。谢谢!:)"
- label: '[FOR CHINESE USERS] 请务必使用英文提交 Issue,否则会被关闭。谢谢!:)'
required: true
- label: "Please do not modify this template :) and fill in all the required fields."
- label: 'Please do not modify this template :) and fill in all the required fields.'
required: true
- type: textarea
attributes:

View File

@@ -1,12 +1,12 @@
name: "🕷️ Bug report"
name: '🕷️ Bug report'
description: Report errors or unexpected behavior
labels:
- bug
- 🐞 bug
body:
- type: checkboxes
attributes:
label: Self Checks
description: "To make sure we get to you in time, please check the following :)"
description: 'To make sure we get to you in time, please check the following :)'
options:
- label: I have read the [Contributing Guide](https://github.com/langgenius/dify/blob/main/CONTRIBUTING.md) and [Language Policy](https://github.com/langgenius/dify/issues/1542).
required: true
@@ -18,7 +18,7 @@ body:
required: true
- label: 【中文用户 & Non English User】请使用英语提交,否则会被关闭 :)
required: true
- label: "Please do not modify this template :) and fill in all the required fields."
- label: 'Please do not modify this template :) and fill in all the required fields.'
required: true
- type: input

View File

@@ -1,13 +1,13 @@
blank_issues_enabled: false
contact_links:
- name: "\U0001F510 Security Vulnerabilities"
url: "https://github.com/langgenius/dify/security/advisories/new"
url: 'https://github.com/langgenius/dify/security/advisories/new'
about: Report security vulnerabilities through GitHub Security Advisories to ensure responsible disclosure. 💡 Please do not report security vulnerabilities in public issues.
- name: "\U0001F4A1 Model Providers & Plugins"
url: "https://github.com/langgenius/dify-official-plugins/issues/new/choose"
url: 'https://github.com/langgenius/dify-official-plugins/issues/new/choose'
about: Report issues with official plugins or model providers, you will need to provide the plugin version and other relevant details.
- name: "\U0001F4AC Documentation Issues"
url: "https://github.com/langgenius/dify-docs/issues/new"
url: 'https://github.com/langgenius/dify-docs/issues/new'
about: Report issues with the documentation, such as typos, outdated information, or missing content. Please provide the specific section and details of the issue.
- name: "\U0001F4E7 Discussions"
url: https://github.com/langgenius/dify/discussions/categories/general

View File

@@ -1,12 +1,12 @@
name: "⭐ Feature or enhancement request"
name: '⭐ Feature or enhancement request'
description: Propose something new.
labels:
- enhancement
- 💪 enhancement
body:
- type: checkboxes
attributes:
label: Self Checks
description: "To make sure we get to you in time, please check the following :)"
description: 'To make sure we get to you in time, please check the following :)'
options:
- label: I have read the [Contributing Guide](https://github.com/langgenius/dify/blob/main/CONTRIBUTING.md) and [Language Policy](https://github.com/langgenius/dify/issues/1542).
required: true
@@ -14,7 +14,7 @@ body:
required: true
- label: I confirm that I am using English to submit this report, otherwise it will be closed.
required: true
- label: "Please do not modify this template :) and fill in all the required fields."
- label: 'Please do not modify this template :) and fill in all the required fields.'
required: true
- type: textarea
attributes:

View File

@@ -1,11 +1,11 @@
name: "✨ Refactor or Chore"
name: '✨ Refactor or Chore'
description: Refactor existing code or perform maintenance chores to improve readability and reliability.
title: "[Refactor/Chore] "
title: '[Refactor/Chore] '
body:
- type: checkboxes
attributes:
label: Self Checks
description: "To make sure we get to you in time, please check the following :)"
description: 'To make sure we get to you in time, please check the following :)'
options:
- label: I have read the [Contributing Guide](https://github.com/langgenius/dify/blob/main/CONTRIBUTING.md) and [Language Policy](https://github.com/langgenius/dify/issues/1542).
required: true
@@ -17,26 +17,26 @@ body:
required: true
- label: 【中文用户 & Non English User】请使用英语提交,否则会被关闭 :)
required: true
- label: "Please do not modify this template :) and fill in all the required fields."
- label: 'Please do not modify this template :) and fill in all the required fields.'
required: true
- type: textarea
id: description
attributes:
label: Description
placeholder: "Describe the refactor or chore you are proposing."
placeholder: 'Describe the refactor or chore you are proposing.'
validations:
required: true
- type: textarea
id: motivation
attributes:
label: Motivation
placeholder: "Explain why this refactor or chore is necessary."
placeholder: 'Explain why this refactor or chore is necessary.'
validations:
required: false
- type: textarea
id: additional-context
attributes:
label: Additional Context
placeholder: "Add any other context or screenshots about the request here."
placeholder: 'Add any other context or screenshots about the request here.'
validations:
required: false

View File

@@ -0,0 +1,29 @@
name: Setup Core E2E Dependencies
description: Install API dependencies alongside web dependencies and the selected browser
inputs:
browser:
description: Browser to install (chromium or webkit)
required: true
runs:
using: composite
steps:
- name: Setup web toolchain
uses: ./.github/actions/setup-web
with:
run-install: 'false'
- name: Setup UV and Python
uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0
with:
enable-cache: true
python-version: '3.12'
cache-dependency-glob: api/uv.lock
- name: Install dependencies in parallel
shell: bash
env:
E2E_INSTALL_BROWSER: ${{ inputs.browser }}
E2E_SETUP_ACTION_PATH: ${{ github.action_path }}
run: bash "$E2E_SETUP_ACTION_PATH/install.sh"

56
.github/actions/setup-core-e2e/install.sh vendored Executable file
View File

@@ -0,0 +1,56 @@
#!/usr/bin/env bash
set -euo pipefail
case "${E2E_INSTALL_BROWSER:-}" in
chromium|webkit) ;;
*) echo "Expected chromium or webkit" >&2; exit 1 ;;
esac
# Keep both branches in this step so failures are collected before tests start.
started=$SECONDS
timing_dir=$(mktemp -d)
trap 'rm -rf "$timing_dir"' EXIT
(
api_started=$SECONDS
uv sync --project api --dev
echo "$((SECONDS - api_started))" > "$timing_dir/api"
) &
api_pid=$!
(
web_started=$SECONDS
vp install --frozen-lockfile
echo "$((SECONDS - web_started))" > "$timing_dir/web"
browser_started=$SECONDS
cd e2e
vp run "e2e:install:ci:$E2E_INSTALL_BROWSER"
echo "$((SECONDS - browser_started))" > "$timing_dir/browser"
) &
web_pid=$!
api_status=0
web_status=0
wait "$api_pid" || api_status=$?
wait "$web_pid" || web_status=$?
{
echo "### E2E dependency preparation ($E2E_INSTALL_BROWSER)"
echo ""
echo "Parallel install wall time: $((SECONDS - started))s"
echo ""
echo "| Phase | Seconds |"
echo "| --- | ---: |"
for phase in api web browser; do
if [[ -f "$timing_dir/$phase" ]]; then
echo "| $phase | $(cat "$timing_dir/$phase") |"
fi
done
echo ""
echo "API exit status: $api_status; Web/browser exit status: $web_status"
} >> "${GITHUB_STEP_SUMMARY:-/dev/null}"
if (( api_status != 0 || web_status != 0 )); then
echo "E2E dependency installation failed (API: $api_status, Web/browser: $web_status)" >&2
exit 1
fi

View File

@@ -1,16 +1,29 @@
name: Setup Web Environment
description: Set up Node.js, Vite+, pnpm, and web dependencies
inputs:
run-install:
description: Install web dependencies after setting up the toolchain
default: 'true'
cache-save:
description: Save the dependency cache after the job completes
default: 'true'
runs:
using: composite
steps:
- name: Setup pnpm
uses: pnpm/action-setup@0e279bb959325dab635dd2c09392533439d90093 # v6.0.8
- name: Setup pnpm and Node.js
uses: pnpm/setup@fbda4c85fc2e1e08721cd8763afea8f48d60f024 # v3.0.0
with:
run_install: false
install: false
- name: Setup Vite+
uses: voidzero-dev/setup-vp@ca1c46663915d6c1042ae23bd39ab85718bfb0fa # v1.10.0
uses: voidzero-dev/setup-vp@3754dd7dbdb32bd8f6d28b6043de13ad3a75f21f # v1.21.1
with:
node-version-file: .nvmrc
node-manager: false
package-manager: |
pnpm: false
npm: false
cache: true
run-install: true
# Nested composite post actions can evaluate inputs in the outer scope.
cache-save: ${{ inputs.cache-save || 'true' }}
run-install: ${{ inputs.run-install }}

View File

@@ -0,0 +1,21 @@
name: Wait for Core E2E Web Build
description: Wait for the current workflow run's Web build artifact while the producer finishes independently
outputs:
artifact-id:
description: ID of the ready Web build artifact
value: ${{ steps.wait.outputs.result }}
runs:
using: composite
steps:
- name: Wait for build artifact
id: wait
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
env:
E2E_WAIT_ACTION_PATH: ${{ github.action_path }}
with:
result-encoding: string
script: |
const waitForBuild = require(`${process.env.E2E_WAIT_ACTION_PATH}/wait.cjs`)
return await waitForBuild({ github, context, core, runAttempt: Number(process.env.GITHUB_RUN_ATTEMPT) })

View File

@@ -0,0 +1,104 @@
const { execFile } = require('node:child_process')
const { appendFile, mkdtemp, rm } = require('node:fs/promises')
const os = require('node:os')
const path = require('node:path')
const { promisify } = require('node:util')
const waitForBuild = require('./wait.cjs')
const execFileAsync = promisify(execFile)
async function downloadWebBuild({
env = process.env,
execute = execFileAsync,
webDir = path.resolve(__dirname, '../../../web'),
} = {}) {
const repository = env.GITHUB_REPOSITORY
const runId = env.GITHUB_RUN_ID
const runAttempt = Number(env.GITHUB_RUN_ATTEMPT)
if (
!repository ||
!/^\d+$/.test(runId || '') ||
!Number.isInteger(runAttempt) ||
runAttempt < 1 ||
!env.GH_TOKEN
) {
throw new Error(
'Downloading the Web build requires GITHUB_REPOSITORY, GITHUB_RUN_ID, GITHUB_RUN_ATTEMPT, and GH_TOKEN.',
)
}
const run = (command, args, timeout = 60_000) =>
execute(command, args, {
env,
timeout,
maxBuffer: 32 * 1024 * 1024,
})
const api = async (endpoint, paginate = false) => {
const { stdout } = await run('gh', [
'api',
endpoint,
...(paginate ? ['--paginate', '--slurp'] : []),
])
return JSON.parse(stdout)
}
const prefix = `repos/${repository}/actions`
let summary = ''
const artifactId = await waitForBuild({
github: {
rest: {
actions: { listJobsForWorkflowRunAttempt: 'jobs', listWorkflowRunArtifacts: 'artifacts' },
},
paginate: async (kind) => {
const endpoint =
kind === 'jobs'
? `${prefix}/runs/${runId}/attempts/${runAttempt}/jobs?per_page=100`
: `${prefix}/runs/${runId}/artifacts?per_page=100`
const pages = await api(endpoint, true)
return pages.flatMap((page) => page[kind])
},
},
context: { repo: {}, runId },
core: {
info: console.log,
summary: {
addHeading(text) {
summary += `### ${text}\n\n`
return this
},
addRaw(text) {
summary += `${text}\n`
return this
},
async write() {
if (env.GITHUB_STEP_SUMMARY) await appendFile(env.GITHUB_STEP_SUMMARY, summary)
},
},
},
runAttempt,
})
const artifact = await api(`${prefix}/artifacts/${artifactId}`)
const directory = await mkdtemp(path.join(os.tmpdir(), 'dify-e2e-web-build-'))
try {
// Artifact names are immutable within a run. Use the name selected by wait.cjs,
// including its matching upload timestamp when only consumer jobs are rerun.
await run(
'gh',
['run', 'download', runId, '--repo', repository, '--name', artifact.name, '--dir', directory],
300_000,
)
await run('tar', ['-xf', path.join(directory, 'e2e-web-build.tar'), '-C', webDir])
console.log(`Web build artifact ${artifactId} extracted and ready.`)
} finally {
await rm(directory, { force: true, recursive: true })
}
}
module.exports = downloadWebBuild
if (require.main === module) {
downloadWebBuild().catch((error) => {
console.error(error)
process.exitCode = 1
})
}

View File

@@ -0,0 +1,112 @@
const assert = require('node:assert/strict')
const { access } = require('node:fs/promises')
const { test } = require('node:test')
const downloadWebBuild = require('./download.cjs')
function fixture({ downloadFails = false, producerFails = false } = {}) {
const calls = []
const env = {
GITHUB_REPOSITORY: 'owner/repo',
GITHUB_RUN_ID: '123',
GITHUB_RUN_ATTEMPT: '4',
GH_TOKEN: 'test-token',
}
const execute = async (command, args) => {
calls.push({ command, args })
if (command === 'tar') return { stdout: '' }
if (args[0] === 'run') {
if (downloadFails) throw new Error('artifact download failed')
return { stdout: '' }
}
if (args[1].includes('/jobs?')) {
return {
stdout: JSON.stringify([
{
jobs: [
{
name: 'Run Web Full-Stack E2E / Prepare Core E2E Web Build',
status: 'completed',
conclusion: producerFails ? 'failure' : 'success',
steps: [
{
name: 'Upload Web build',
conclusion: 'success',
started_at: '2026-09-22T04:08:08Z',
completed_at: '2026-09-22T04:08:12Z',
},
],
},
],
},
]),
}
}
if (args[1].includes('/artifacts?')) {
return {
stdout: JSON.stringify([
{ artifacts: [] },
{
artifacts: [
{
id: 42,
name: 'core-e2e-web-build-2',
created_at: '2026-09-22T04:08:11Z',
expired: false,
},
],
},
]),
}
}
assert.equal(args[1], 'repos/owner/repo/actions/artifacts/42')
return { stdout: JSON.stringify({ name: 'core-e2e-web-build-2' }) }
}
return { calls, options: { env, execute, webDir: '/test/web' } }
}
test('downloads the producer-selected artifact on consumer-only reruns, including paginated results', async () => {
const { calls, options } = fixture()
await downloadWebBuild(options)
assert.match(calls[0].args[1], /runs\/123\/attempts\/4\/jobs/)
const download = calls.find(({ args }) => args[0] === 'run')
assert.deepEqual(download.args.slice(0, 7), [
'run',
'download',
'123',
'--repo',
'owner/repo',
'--name',
'core-e2e-web-build-2',
])
const extract = calls.at(-1)
assert.equal(extract.command, 'tar')
assert.deepEqual(extract.args.slice(-2), ['-C', '/test/web'])
await assert.rejects(access(download.args.at(-1)), { code: 'ENOENT' })
})
test('does not extract a failed download and removes its temporary directory', async () => {
const { calls, options } = fixture({ downloadFails: true })
await assert.rejects(downloadWebBuild(options), /artifact download failed/)
assert.equal(
calls.some(({ command }) => command === 'tar'),
false,
)
await assert.rejects(access(calls.at(-1).args.at(-1)), { code: 'ENOENT' })
})
test('does not download or extract when the producer fails', async () => {
const { calls, options } = fixture({ producerFails: true })
await assert.rejects(downloadWebBuild(options), /Web build finished with failure/)
assert.equal(calls.length, 1)
})
test('requires CI metadata and credentials before starting preparation', async () => {
const { calls, options } = fixture()
for (const key of Object.keys(options.env)) {
await assert.rejects(
downloadWebBuild({ ...options, env: { ...options.env, [key]: '' } }),
/requires GITHUB/,
)
}
assert.equal(calls.length, 0)
})

View File

@@ -0,0 +1,65 @@
const { setTimeout: delay } = require('node:timers/promises')
module.exports = async function waitForBuild({
github,
context,
core,
runAttempt,
now = Date.now,
sleep = delay,
timeoutMs = 30 * 60 * 1000,
}) {
const started = now()
const run = { ...context.repo, run_id: context.runId, per_page: 100 }
core.info('Waiting for core-e2e-web-build in this workflow run')
while (now() - started < timeoutMs) {
const jobs = await github.paginate(github.rest.actions.listJobsForWorkflowRunAttempt, {
...run,
attempt_number: runAttempt,
})
const producer = jobs.find(
(job) =>
job.name === 'Prepare Core E2E Web Build' ||
job.name.endsWith(' / Prepare Core E2E Web Build'),
)
if (producer?.status === 'completed' && producer.conclusion !== 'success') {
throw new Error(
`Web build finished with ${producer.conclusion} before publishing an artifact`,
)
}
if (producer && ['in_progress', 'completed'].includes(producer.status)) {
const artifacts = await github.paginate(github.rest.actions.listWorkflowRunArtifacts, run)
const upload = producer.steps?.find((step) => step.name === 'Upload Web build')
const artifact = artifacts.find((item) => {
if (item.expired || !/^core-e2e-web-build-[1-9]\d*$/.test(item.name)) return false
if (producer.status === 'in_progress') {
// A rebuilding producer must publish this attempt's immutable artifact.
return item.name === `core-e2e-web-build-${runAttempt}`
}
// GitHub relabels reused successful jobs with the current run_attempt.
// Their upload step keeps its original timestamps, identifying the artifact
// to reuse when only consumers are rerun (including across several attempts).
return (
upload?.conclusion === 'success' &&
item.created_at >= upload.started_at &&
item.created_at <= upload.completed_at
)
})
if (artifact) {
const seconds = Math.round((now() - started) / 1000)
core.info(`Web build artifact ${artifact.name} ready after ${seconds}s`)
await core.summary
.addHeading('E2E Web build wait')
.addRaw(`Artifact wait: ${seconds}s`)
.write()
return String(artifact.id)
}
}
await sleep(Math.min(10000, timeoutMs - (now() - started)))
}
throw new Error('Timed out waiting for core-e2e-web-build in this workflow run')
}

View File

@@ -0,0 +1,164 @@
const assert = require('node:assert/strict')
const { test } = require('node:test')
const waitForBuild = require('./wait.cjs')
function fixture({ artifacts = [], jobs = [producer], error, runAttempt = 2 } = {}) {
let elapsed = 0
const calls = []
const summary = {
addHeading() {
return this
},
addRaw() {
return this
},
async write() {},
}
return {
calls,
options: {
context: { repo: { owner: 'owner', repo: 'repo' }, runId: 123 },
core: { info() {}, summary },
runAttempt,
github: {
rest: {
actions: { listWorkflowRunArtifacts: 'artifacts', listJobsForWorkflowRunAttempt: 'jobs' },
},
async paginate(endpoint, params) {
calls.push({ endpoint, params })
if (error) throw error
const values = endpoint === 'artifacts' ? artifacts : jobs
return typeof values === 'function' ? values(elapsed) : values
},
},
now: () => elapsed,
sleep: async (ms) => {
elapsed += ms
},
timeoutMs: 20000,
},
}
}
const producer = {
name: 'Run Web Full-Stack E2E / Prepare Core E2E Web Build',
status: 'in_progress',
run_attempt: 2,
}
const artifact = {
id: 42,
name: 'core-e2e-web-build-2',
expired: false,
created_at: '2026-09-22T04:08:11Z',
}
const oldArtifact = {
...artifact,
id: 41,
name: 'core-e2e-web-build-1',
created_at: '2026-09-22T03:08:11Z',
}
const successfulProducer = {
...producer,
status: 'completed',
conclusion: 'success',
steps: [
{
name: 'Upload Web build',
conclusion: 'success',
started_at: '2026-09-22T04:08:08Z',
completed_at: '2026-09-22T04:08:12Z',
},
],
}
test('starts consuming the current artifact without waiting for producer cache saves', async () => {
const { options, calls } = fixture({ artifacts: (elapsed) => (elapsed ? [artifact] : []) })
assert.equal(await waitForBuild(options), '42')
assert.equal(options.now(), 10000)
assert.deepEqual(
calls.map((call) => call.endpoint),
['jobs', 'artifacts', 'jobs', 'artifacts'],
)
for (const { endpoint, params } of calls) {
assert.equal(params.run_id, 123)
assert.equal(params.owner, 'owner')
assert.equal(params.repo, 'repo')
if (endpoint === 'jobs') assert.equal(params.attempt_number, 2)
}
})
test('full reruns ignore the old artifact until the rebuilding producer publishes this attempt', async () => {
const { options } = fixture({
artifacts: (elapsed) => (elapsed ? [oldArtifact, artifact] : [oldArtifact]),
})
assert.equal(await waitForBuild(options), '42')
assert.equal(options.now(), 10000)
})
test('does not use an old artifact before the current producer appears or while it is queued', async () => {
const { options } = fixture({
artifacts: [oldArtifact],
jobs: (elapsed) => (elapsed ? [{ ...producer, status: 'queued' }] : []),
})
await assert.rejects(waitForBuild(options), /Timed out/)
})
test('consumer-only reruns reuse the actual successful upload despite a relabeled run_attempt', async () => {
const { options } = fixture({
runAttempt: 4,
artifacts: [oldArtifact, artifact],
jobs: [{ ...successfulProducer, run_attempt: 4 }],
})
assert.equal(await waitForBuild(options), '42')
assert.equal(options.now(), 0)
})
for (const conclusion of ['failure', 'cancelled', 'skipped']) {
test(`does not fall back to an old artifact when the producer finishes with ${conclusion}`, async () => {
const { options } = fixture({
artifacts: [oldArtifact, artifact],
jobs: [{ ...producer, status: 'completed', conclusion }],
})
await assert.rejects(waitForBuild(options), new RegExp(`Web build finished with ${conclusion}`))
assert.equal(options.now(), 0)
})
}
test('ignores unrelated and expired artifacts and stops at the deadline', async () => {
const { options } = fixture({
artifacts: [
{ ...artifact, expired: true },
{ ...artifact, name: 'other' },
],
})
await assert.rejects(waitForBuild(options), /Timed out/)
assert.equal(options.now(), 20000)
})
test('completed rebuilt producers select their upload instead of the old artifact', async () => {
const { options } = fixture({ artifacts: [oldArtifact, artifact], jobs: [successfulProducer] })
assert.equal(await waitForBuild(options), '42')
})
test('allows artifact visibility to catch up after a successful producer finishes', async () => {
const { options } = fixture({
artifacts: (elapsed) => (elapsed ? [oldArtifact, artifact] : [oldArtifact]),
jobs: [successfulProducer],
})
assert.equal(await waitForBuild(options), '42')
assert.equal(options.now(), 10000)
})
test('does not reuse artifacts without a successful matching upload step', async () => {
const { options } = fixture({
artifacts: [artifact],
jobs: [{ ...successfulProducer, steps: [] }],
})
await assert.rejects(waitForBuild(options), /Timed out/)
})
test('reports API errors rather than silently waiting until timeout', async () => {
const { options } = fixture({ error: new Error('Resource not accessible by integration') })
await assert.rejects(waitForBuild(options), /Resource not accessible/)
assert.equal(options.now(), 0)
})

328
.github/dependabot.yml vendored
View File

@@ -1,223 +1,223 @@
version: 2
updates:
- package-ecosystem: "uv"
directory: "/api"
- package-ecosystem: 'uv'
directory: '/api'
open-pull-requests-limit: 10
schedule:
interval: "weekly"
interval: 'weekly'
groups:
flask:
patterns:
- "flask"
- "flask-*"
- "werkzeug"
- "gunicorn"
- 'flask'
- 'flask-*'
- 'werkzeug'
- 'gunicorn'
google:
patterns:
- "google-*"
- "googleapis-*"
- 'google-*'
- 'googleapis-*'
opentelemetry:
patterns:
- "opentelemetry-*"
- 'opentelemetry-*'
pydantic:
patterns:
- "pydantic"
- "pydantic-*"
- 'pydantic'
- 'pydantic-*'
llm:
patterns:
- "langfuse"
- "langsmith"
- "litellm"
- "mlflow*"
- "opik"
- "weave*"
- "arize*"
- "tiktoken"
- "transformers"
- 'langfuse'
- 'langsmith'
- 'litellm'
- 'mlflow*'
- 'opik'
- 'weave*'
- 'arize*'
- 'tiktoken'
- 'transformers'
database:
patterns:
- "sqlalchemy"
- "psycopg2*"
- "psycogreen"
- "redis*"
- "alembic*"
- 'sqlalchemy'
- 'psycopg2*'
- 'psycogreen'
- 'redis*'
- 'alembic*'
storage:
patterns:
- "boto3*"
- "botocore*"
- "azure-*"
- "bce-*"
- "cos-python-*"
- "esdk-obs-*"
- "google-cloud-storage"
- "opendal"
- "oss2"
- "supabase*"
- "tos*"
- 'boto3*'
- 'botocore*'
- 'azure-*'
- 'bce-*'
- 'cos-python-*'
- 'esdk-obs-*'
- 'google-cloud-storage'
- 'opendal'
- 'oss2'
- 'supabase*'
- 'tos*'
vdb:
patterns:
- "alibabacloud*"
- "chromadb"
- "clickhouse-*"
- "clickzetta-*"
- "couchbase"
- "elasticsearch"
- "opensearch-py"
- "oracledb"
- "pgvect*"
- "pymilvus"
- "pymochow"
- "pyobvector"
- "qdrant-client"
- "intersystems-*"
- "tablestore"
- "tcvectordb"
- "tidb-vector"
- "upstash-*"
- "volcengine-*"
- "weaviate-*"
- "xinference-*"
- "mo-vector"
- "mysql-connector-*"
- 'alibabacloud*'
- 'chromadb'
- 'clickhouse-*'
- 'clickzetta-*'
- 'couchbase'
- 'elasticsearch'
- 'opensearch-py'
- 'oracledb'
- 'pgvect*'
- 'pymilvus'
- 'pymochow'
- 'pyobvector'
- 'qdrant-client'
- 'intersystems-*'
- 'tablestore'
- 'tcvectordb'
- 'tidb-vector'
- 'upstash-*'
- 'volcengine-*'
- 'weaviate-*'
- 'xinference-*'
- 'mo-vector'
- 'mysql-connector-*'
dev:
patterns:
- "coverage"
- "dotenv-linter"
- "faker"
- "lxml-stubs"
- "basedpyright"
- "ruff"
- "pytest*"
- "types-*"
- "boto3-stubs"
- "hypothesis"
- "pandas-stubs"
- "scipy-stubs"
- "import-linter"
- "celery-types"
- "mypy*"
- "pyrefly"
- 'coverage'
- 'dotenv-linter'
- 'faker'
- 'lxml-stubs'
- 'basedpyright'
- 'ruff'
- 'pytest*'
- 'types-*'
- 'boto3-stubs'
- 'hypothesis'
- 'pandas-stubs'
- 'scipy-stubs'
- 'import-linter'
- 'celery-types'
- 'mypy*'
- 'pyrefly'
python-packages:
patterns:
- "*"
- package-ecosystem: "github-actions"
directory: "/"
- '*'
- package-ecosystem: 'github-actions'
directory: '/'
open-pull-requests-limit: 5
schedule:
interval: "weekly"
interval: 'weekly'
groups:
github-actions-dependencies:
patterns:
- "*"
- package-ecosystem: "uv"
directory: "/api"
target-branch: "lts/1.13.x"
- '*'
- package-ecosystem: 'uv'
directory: '/api'
target-branch: 'lts/1.13.x'
open-pull-requests-limit: 10
schedule:
interval: "weekly"
interval: 'weekly'
groups:
flask:
patterns:
- "flask"
- "flask-*"
- "werkzeug"
- "gunicorn"
- 'flask'
- 'flask-*'
- 'werkzeug'
- 'gunicorn'
google:
patterns:
- "google-*"
- "googleapis-*"
- 'google-*'
- 'googleapis-*'
opentelemetry:
patterns:
- "opentelemetry-*"
- 'opentelemetry-*'
pydantic:
patterns:
- "pydantic"
- "pydantic-*"
- 'pydantic'
- 'pydantic-*'
llm:
patterns:
- "langfuse"
- "langsmith"
- "litellm"
- "mlflow*"
- "opik"
- "weave*"
- "arize*"
- "tiktoken"
- "transformers"
- 'langfuse'
- 'langsmith'
- 'litellm'
- 'mlflow*'
- 'opik'
- 'weave*'
- 'arize*'
- 'tiktoken'
- 'transformers'
database:
patterns:
- "sqlalchemy"
- "psycopg2*"
- "psycogreen"
- "redis*"
- "alembic*"
- 'sqlalchemy'
- 'psycopg2*'
- 'psycogreen'
- 'redis*'
- 'alembic*'
storage:
patterns:
- "boto3*"
- "botocore*"
- "azure-*"
- "bce-*"
- "cos-python-*"
- "esdk-obs-*"
- "google-cloud-storage"
- "opendal"
- "oss2"
- "supabase*"
- "tos*"
- 'boto3*'
- 'botocore*'
- 'azure-*'
- 'bce-*'
- 'cos-python-*'
- 'esdk-obs-*'
- 'google-cloud-storage'
- 'opendal'
- 'oss2'
- 'supabase*'
- 'tos*'
vdb:
patterns:
- "alibabacloud*"
- "chromadb"
- "clickhouse-*"
- "clickzetta-*"
- "couchbase"
- "elasticsearch"
- "opensearch-py"
- "oracledb"
- "pgvect*"
- "pymilvus"
- "pymochow"
- "pyobvector"
- "qdrant-client"
- "intersystems-*"
- "tablestore"
- "tcvectordb"
- "tidb-vector"
- "upstash-*"
- "volcengine-*"
- "weaviate-*"
- "xinference-*"
- "mo-vector"
- "mysql-connector-*"
- 'alibabacloud*'
- 'chromadb'
- 'clickhouse-*'
- 'clickzetta-*'
- 'couchbase'
- 'elasticsearch'
- 'opensearch-py'
- 'oracledb'
- 'pgvect*'
- 'pymilvus'
- 'pymochow'
- 'pyobvector'
- 'qdrant-client'
- 'intersystems-*'
- 'tablestore'
- 'tcvectordb'
- 'tidb-vector'
- 'upstash-*'
- 'volcengine-*'
- 'weaviate-*'
- 'xinference-*'
- 'mo-vector'
- 'mysql-connector-*'
dev:
patterns:
- "coverage"
- "dotenv-linter"
- "faker"
- "lxml-stubs"
- "basedpyright"
- "ruff"
- "pytest*"
- "types-*"
- "boto3-stubs"
- "hypothesis"
- "pandas-stubs"
- "scipy-stubs"
- "import-linter"
- "celery-types"
- "mypy*"
- "pyrefly"
- 'coverage'
- 'dotenv-linter'
- 'faker'
- 'lxml-stubs'
- 'basedpyright'
- 'ruff'
- 'pytest*'
- 'types-*'
- 'boto3-stubs'
- 'hypothesis'
- 'pandas-stubs'
- 'scipy-stubs'
- 'import-linter'
- 'celery-types'
- 'mypy*'
- 'pyrefly'
python-packages:
patterns:
- "*"
- package-ecosystem: "github-actions"
directory: "/"
target-branch: "lts/1.13.x"
- '*'
- package-ecosystem: 'github-actions'
directory: '/'
target-branch: 'lts/1.13.x'
open-pull-requests-limit: 5
schedule:
interval: "weekly"
interval: 'weekly'
groups:
github-actions-dependencies:
patterns:
- "*"
- '*'

7
.github/labeler.yml vendored
View File

@@ -6,4 +6,9 @@ web:
- 'package.json'
- 'pnpm-lock.yaml'
- 'pnpm-workspace.yaml'
- '.nvmrc'
e2e:
- changed-files:
- any-glob-to-any-file:
- 'e2e/**'
- '.github/workflows/web-e2e.yml'

View File

@@ -1 +1 @@
failure-threshold: "error"
failure-threshold: 'error'

View File

@@ -1,10 +1,11 @@
---
extends: default
rules:
brackets:
max-spaces-inside: 1
comments:
min-spaces-from-content: 1
comments-indentation: disable
document-start: disable
line-length: disable

View File

@@ -1,22 +1,22 @@
{
"Verbose": false,
"Debug": false,
"IgnoreDefaults": false,
"SpacesAfterTabs": false,
"NoColor": false,
"Exclude": [
"^web/public/vs/",
"^web/public/pdf.worker.min.mjs$",
"web/app/components/base/icons/src/vender/"
],
"AllowedContentTypes": [],
"PassedFiles": [],
"Disable": {
"EndOfLine": false,
"Indentation": false,
"IndentSize": true,
"InsertFinalNewline": false,
"TrimTrailingWhitespace": false,
"MaxLineLength": false
}
"Verbose": false,
"Debug": false,
"IgnoreDefaults": false,
"SpacesAfterTabs": false,
"NoColor": false,
"Exclude": [
"^web/public/vs/",
"^web/public/pdf.worker.min.mjs$",
"web/app/components/base/icons/src/vender/"
],
"AllowedContentTypes": [],
"PassedFiles": [],
"Disable": {
"EndOfLine": false,
"Indentation": false,
"IndentSize": true,
"InsertFinalNewline": false,
"TrimTrailingWhitespace": false,
"MaxLineLength": false
}
}

View File

@@ -1,7 +1,7 @@
> [!IMPORTANT]
>
> 1. Make sure you have read our [contribution guidelines](https://github.com/langgenius/dify/blob/main/CONTRIBUTING.md)
> 1. Ensure there is an associated issue and you have been assigned to it
> 1. Ensure there is an associated issue
> 1. Use the correct syntax to link this PR: `Fixes #<issue number>`.
## Summary
@@ -12,13 +12,13 @@
## Screenshots
| Before | After |
|--------|-------|
| ... | ... |
| ------ | ----- |
| ... | ... |
## Checklist
- [ ] This change requires a documentation update, included: [Dify Document](https://github.com/langgenius/dify-docs)
- [ ] I understand that this PR may be closed in case there was no previous discussion or issues. (This doesn't apply to typos!)
- [ ] I've added a test for each change that was introduced, and I tried as much as possible to make a single atomic change.
- [ ] I've verified the change and added or updated tests where meaningful regression risk justifies coverage.
- [ ] I've updated the documentation accordingly.
- [ ] I ran `make lint && make type-check` (backend) and `cd web && pnpm exec vp staged` (frontend) to appease the lint gods
- [ ] I ran `make lint && make type-check` (backend) and `vp staged` (frontend) to appease the lint gods

View File

@@ -45,7 +45,7 @@ while IFS= read -r commit_sha; do
)
if [[ -z "$source_sha" ]]; then
error "Commit $commit_sha ($subject) is missing cherry-pick provenance. $REMEDIATION_HINT"
error "Commit $commit_sha ($subject) is missing cherry-pick provenance. $REMEDIATION_HINT If version differences prevent using git cherry-pick -x, manually add '(cherry picked from commit <sha>)' to the commit message."
failed=1
continue
fi

View File

@@ -8,31 +8,32 @@ const headSha = process.env.HEAD_SHA || ''
const files = (process.env.CHANGED_FILES || '').split(/\s+/).filter(Boolean)
const outputPath = process.env.I18N_CHANGES_OUTPUT_PATH || '/tmp/i18n-changes.json'
const englishPath = fileStem => path.join(repoRoot, 'web', 'i18n', 'en-US', `${fileStem}.json`)
const englishPath = (fileStem) =>
path.join(repoRoot, 'web', 'i18n', 'locales', 'en-US', `${fileStem}.json`)
const readCurrentJson = (fileStem) => {
const filePath = englishPath(fileStem)
if (!fs.existsSync(filePath))
return null
if (!fs.existsSync(filePath)) return null
return JSON.parse(fs.readFileSync(filePath, 'utf8'))
}
const readBaseJson = (fileStem) => {
if (!baseSha)
return null
if (!baseSha) return null
try {
const relativePath = `web/i18n/en-US/${fileStem}.json`
const content = execFileSync('git', ['show', `${baseSha}:${relativePath}`], { encoding: 'utf8' })
const relativePath = `web/i18n/locales/en-US/${fileStem}.json`
const content = execFileSync('git', ['show', `${baseSha}:${relativePath}`], {
encoding: 'utf8',
})
return JSON.parse(content)
}
catch {
} catch {
return null
}
}
const compareJson = (beforeValue, afterValue) => JSON.stringify(beforeValue) === JSON.stringify(afterValue)
const compareJson = (beforeValue, afterValue) =>
JSON.stringify(beforeValue) === JSON.stringify(afterValue)
const changes = {}
@@ -59,8 +60,7 @@ for (const fileStem of files) {
}
for (const key of Object.keys(beforeJson)) {
if (!(key in afterJson))
deleted.push(key)
if (!(key in afterJson)) deleted.push(key)
}
changes[fileStem] = {
@@ -78,5 +78,5 @@ fs.writeFileSync(
headSha,
files,
changes,
})
}),
)

94
.github/scripts/size-labeler.test.cjs vendored Normal file
View File

@@ -0,0 +1,94 @@
const fs = require('node:fs')
const assert = require('node:assert/strict')
const test = require('node:test')
const source = fs.readFileSync(
require('node:path').join(__dirname, '../workflows/size-labeler.yml'),
'utf8',
)
const script = source
.replace(/\r\n/g, '\n')
.split(' script: |\n')[1]
.split('\n')
.map((l) => l.replace(/^ /, ''))
.join('\n')
const run = new (Object.getPrototypeOf(async function () {}).constructor)(
'github',
'context',
'core',
script,
)
async function scenario(files, existing = [], changed = files.length) {
const calls = []
const warnings = []
const api = {
pulls: {
get: async () => ({ data: { changed_files: changed } }),
listFiles: 'files',
},
issues: {
listLabelsOnIssue: 'labels',
addLabels: async (p) => calls.push(['add', p.labels[0]]),
removeLabel: async (p) => calls.push(['remove', p.name]),
},
}
await run(
{
rest: api,
paginate: async (endpoint) =>
endpoint === 'files' ? files : existing.map((name) => ({ name })),
},
{
repo: { owner: 'test', repo: 'repo' },
payload: { pull_request: { number: 1 } },
},
{ warning: (s) => warnings.push(s) },
)
return { calls, warnings }
}
for (const [n, label] of [
[0, 'XS'],
[9, 'XS'],
[10, 'S'],
[29, 'S'],
[30, 'M'],
[99, 'M'],
[100, 'L'],
[499, 'L'],
[500, 'XL'],
[999, 'XL'],
[1000, 'XXL'],
]) {
test(`threshold ${n}`, async () =>
assert.deepEqual((await scenario([{ filename: 'a.py', additions: n, deletions: 0 }])).calls, [
['add', `size:${label}`],
]))
}
test('count deletions', async () =>
assert.deepEqual((await scenario([{ filename: 'a.py', additions: 0, deletions: 30 }])).calls, [
['add', 'size:M'],
]))
test('ignore nested lockfiles', async () =>
assert.deepEqual(
(
await scenario([
{ filename: 'api/uv.lock', additions: 9000, deletions: 5 },
{ filename: 'web/pnpm-lock.yaml', additions: 5000, deletions: 0 },
])
).calls,
[['add', 'size:XS']],
))
test('replace stale size only', async () =>
assert.deepEqual(
(await scenario([{ filename: 'a.py', additions: 10, deletions: 0 }], ['size:L', 'bug', 'web']))
.calls,
[
['add', 'size:S'],
['remove', 'size:L'],
],
))
test('idempotent', async () => assert.deepEqual((await scenario([], ['size:XS', 'bug'])).calls, []))
test('incomplete file list', async () => {
const r = await scenario([], ['size:L'], 3001)
assert.deepEqual(r.calls, [])
assert.equal(r.warnings.length, 1)
})

101
.github/workflows/accessibility-e2e.yml vendored Normal file
View File

@@ -0,0 +1,101 @@
name: Manual WCAG Accessibility Audit
run-name: WCAG ${{ inputs.level }} · ${{ inputs.page }}
on:
workflow_dispatch:
inputs:
page:
description: Page to scan
required: true
default: home
type: choice
options:
- home
- sign-in
- studio
- agents
- knowledge
- integrations
- all
level:
description: WCAG level to scan
required: true
default: aa
type: choice
options:
- aa
- a
permissions:
contents: read
concurrency:
group: accessibility-e2e-${{ github.ref }}-${{ inputs.page }}-${{ inputs.level }}
cancel-in-progress: true
jobs:
accessibility:
name: WCAG Level ${{ inputs.level == 'a' && 'A' || 'AA' }} · ${{ inputs.page }}
runs-on: ubuntu-24.04
timeout-minutes: 120
defaults:
run:
shell: bash
steps:
- name: Checkout code
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- name: Setup web dependencies
uses: ./.github/actions/setup-web
- name: Setup UV and Python
uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0
with:
enable-cache: true
python-version: '3.12'
cache-dependency-glob: |
api/uv.lock
- name: Install API dependencies
run: uv sync --project api --dev
- name: Install Chromium for accessibility E2E
timeout-minutes: 15
working-directory: ./e2e
run: vp run e2e:install:ci:chromium
- name: Run automated WCAG Level ${{ inputs.level == 'a' && 'A' || 'AA' }} checks
working-directory: ./e2e
env:
E2E_ADMIN_EMAIL: e2e-admin@example.com
E2E_ADMIN_NAME: E2E Admin
E2E_ADMIN_PASSWORD: E2eAdmin12345
E2E_FORCE_WEB_BUILD: '1'
E2E_INIT_PASSWORD: E2eInit12345
WCAG_PAGE: ${{ inputs.page }}
run: |
if [[ "$WCAG_PAGE" == "all" ]]; then
vp run e2e:accessibility:${{ inputs.level }}
else
pnpm exec node ./scripts/run-cucumber.ts --full -- --tags "@axe and @wcag-${{ inputs.level }} and @wcag-page-$WCAG_PAGE"
fi
- name: Upload accessibility Cucumber report
if: ${{ !cancelled() }}
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: cucumber-report-accessibility-${{ inputs.level }}-${{ inputs.page }}
path: e2e/cucumber-report
retention-days: 7
- name: Upload accessibility E2E logs
if: ${{ !cancelled() }}
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: e2e-logs-accessibility-${{ inputs.level }}-${{ inputs.page }}
path: e2e/.logs/*.log
include-hidden-files: true
retention-days: 7

View File

@@ -14,28 +14,79 @@ concurrency:
cancel-in-progress: true
jobs:
api-unit-plan:
name: Plan API unit shards
runs-on: depot-ubuntu-24.04
steps:
- name: Checkout code
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- name: Setup UV and Python
uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0
with:
python-version: '3.12'
enable-cache: false
- name: Download shared timing baseline
# Public statistics are independent of PR refs and require no credentials.
run: |
if ! curl --fail --silent --show-error --location \
--connect-timeout 5 --max-time 15 --retry 2 --retry-max-time 30 \
https://raw.githubusercontent.com/langgenius/dify-test-infra/generated-stats/stats/test-times.json \
--output unit-test-durations.json; then
rm -f unit-test-durations.json
echo '::warning::Timing baseline unavailable; using round-robin file allocation.'
fi
- name: Freeze file assignments for every shard
run: |
uv run --project api --no-sync python api/dev/pytest_sharding.py \
--shard-index 1 --shard-total 2 \
--durations unit-test-durations.json \
--write-plan unit-test-plan.json \
--split-threshold 60 \
--ignore api/tests/unit_tests/controllers \
api/tests/unit_tests \
api/providers/vdb/*/tests/unit_tests \
api/providers/trace/*/tests/unit_tests
- name: Upload shared plan
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: api-unit-plan
path: |
unit-test-plan.json
unit-test-durations.json
retention-days: 7
if-no-files-found: error
api-unit:
name: API Unit Tests
needs: api-unit-plan
name: API Unit Tests (${{ matrix.python-version }}, shard ${{ matrix.shardIndex }}/${{ matrix.shardTotal }})
runs-on: depot-ubuntu-24.04
env:
COVERAGE_FILE: coverage-unit
PYTHONUNBUFFERED: '1'
COVERAGE_FILE: coverage-unit-${{ matrix.python-version }}-${{ matrix.shardIndex }}
defaults:
run:
shell: bash
strategy:
fail-fast: false
matrix:
python-version:
- "3.12"
- '3.12'
shardIndex:
- 1
- 2
shardTotal:
- 2
steps:
- name: Checkout code
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0
persist-credentials: false
- name: Setup UV and Python
uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0
with:
enable-cache: true
python-version: ${{ matrix.python-version }}
@@ -47,37 +98,116 @@ jobs:
- name: Install dependencies
run: uv sync --project api --dev
- name: Run dify config tests
run: uv run --project api pytest api/tests/unit_tests/configs/test_env_consistency.py
- name: Download shared plan
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: api-unit-plan
- name: Run Unit Tests
run: |
uv run --project api python api/dev/pytest_sharding.py \
--plan unit-test-plan.json \
--shard-index "${{ matrix.shardIndex }}" \
--shard-total "${{ matrix.shardTotal }}" \
--ignore api/tests/unit_tests/controllers \
api/tests/unit_tests \
api/providers/vdb/*/tests/unit_tests \
api/providers/trace/*/tests/unit_tests > "$RUNNER_TEMP/unit-test-files.txt"
uv run --project api pytest \
-p no:benchmark \
--timeout "${PYTEST_TIMEOUT:-20}" \
-n auto \
api/tests/unit_tests \
api/providers/vdb/*/tests/unit_tests \
api/providers/trace/*/tests/unit_tests \
--ignore=api/tests/unit_tests/controllers
# Controller tests register Flask routes at import time, so keep them out of xdist.
uv run --project api pytest \
--timeout "${PYTEST_TIMEOUT:-20}" \
--cov-append \
api/tests/unit_tests/controllers
-o 'addopts=-p no:opik -p no:langsmith_plugin --cov=./api --cov-branch --import-mode=importlib' \
--cov-report= \
--file-shard-plan unit-test-plan.json \
--shard-index "${{ matrix.shardIndex }}" \
--shard-total "${{ matrix.shardTotal }}" \
--write-test-durations "test-results/durations-${{ matrix.shardIndex }}.json" \
--junitxml=test-results/unit.xml \
"@$RUNNER_TEMP/unit-test-files.txt"
- name: Upload unit test reports
if: ${{ !cancelled() }}
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: api-test-results-unit-${{ matrix.python-version }}-${{ matrix.shardIndex }}
path: test-results/*.xml
if-no-files-found: warn
retention-days: 7
- name: Upload successful timing observations
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: api-unit-durations-${{ matrix.shardIndex }}
path: test-results/durations-*.json
retention-days: 7
if-no-files-found: error
- name: Upload unit coverage data
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: api-coverage-unit
path: coverage-unit
name: api-coverage-unit-${{ matrix.python-version }}-${{ matrix.shardIndex }}
path: ${{ env.COVERAGE_FILE }}
if-no-files-found: error
retention-days: 1
api-controllers:
name: API Controller Tests (3.12)
runs-on: depot-ubuntu-24.04
env:
PYTHONUNBUFFERED: '1'
COVERAGE_FILE: coverage-controllers-3.12
steps:
- name: Checkout code
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- name: Setup UV and Python
uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0
with:
enable-cache: true
python-version: '3.12'
cache-dependency-glob: api/uv.lock
- name: Check UV lockfile
run: uv lock --project api --check
- name: Install dependencies
run: uv sync --project api --dev
- name: Run Controller Tests
# Controller tests register Flask routes at import time, so keep them out of xdist.
run: |
uv run --project api pytest \
--timeout "${PYTEST_TIMEOUT:-20}" \
-o 'addopts=-p no:opik -p no:langsmith_plugin --cov=./api --cov-branch --import-mode=importlib' \
--cov-report= \
--junitxml=test-results/controllers.xml \
api/tests/unit_tests/controllers
- name: Upload controller test reports
if: ${{ !cancelled() }}
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: api-test-results-controllers-3.12
path: test-results/*.xml
if-no-files-found: warn
retention-days: 7
- name: Upload controller coverage data
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: api-coverage-controllers-3.12
path: ${{ env.COVERAGE_FILE }}
if-no-files-found: error
retention-days: 1
api-integration:
name: API Integration Tests
runs-on: depot-ubuntu-24.04
name: API Integration Tests (${{ matrix.python-version }})
runs-on: depot-ubuntu-24.04-4
env:
COVERAGE_FILE: coverage-integration
COVERAGE_FILE: coverage-integration-${{ matrix.python-version }}
STORAGE_TYPE: opendal
OPENDAL_SCHEME: fs
OPENDAL_FS_ROOT: /tmp/dify-storage
@@ -85,19 +215,19 @@ jobs:
run:
shell: bash
strategy:
fail-fast: false
matrix:
python-version:
- "3.12"
- '3.12'
steps:
- name: Checkout code
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0
persist-credentials: false
- name: Setup UV and Python
uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0
with:
enable-cache: true
python-version: ${{ matrix.python-version }}
@@ -114,7 +244,10 @@ jobs:
uv run --project api pytest \
-p no:benchmark \
--start-middleware \
--middleware-stop-timeout 2 \
-n auto \
-o 'addopts=-p no:opik -p no:langsmith_plugin --cov=./api --cov-branch --import-mode=importlib' \
--cov-report= \
--timeout "${PYTEST_TIMEOUT:-180}" \
api/tests/integration_tests/workflow \
api/tests/integration_tests/tools \
@@ -123,8 +256,9 @@ jobs:
- name: Upload integration coverage data
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: api-coverage-integration
path: coverage-integration
name: api-coverage-integration-${{ matrix.python-version }}
path: ${{ env.COVERAGE_FILE }}
if-no-files-found: error
retention-days: 1
api-coverage:
@@ -132,6 +266,7 @@ jobs:
runs-on: depot-ubuntu-24.04
needs:
- api-unit
- api-controllers
- api-integration
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
@@ -142,20 +277,14 @@ jobs:
steps:
- name: Checkout code
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0
persist-credentials: false
- name: Setup UV and Python
uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0
with:
enable-cache: true
python-version: "3.12"
cache-dependency-glob: api/uv.lock
- name: Install dependencies
run: uv sync --project api --dev
python-version: '3.12'
- name: Download coverage data
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
@@ -167,35 +296,48 @@ jobs:
- name: Combine coverage
run: |
set -euo pipefail
coverage_version=$(python3 -c 'import tomllib; print(next(p["version"] for p in tomllib.load(open("api/uv.lock", "rb"))["package"] if p["name"] == "coverage"))')
echo "### API Coverage" >> "$GITHUB_STEP_SUMMARY"
echo "" >> "$GITHUB_STEP_SUMMARY"
echo "Merged backend coverage report generated for Codecov project status." >> "$GITHUB_STEP_SUMMARY"
echo "" >> "$GITHUB_STEP_SUMMARY"
mapfile -t unit_coverage < <(find coverage-data -type f -name 'coverage-unit-*' -print | sort)
mapfile -t controller_coverage < <(find coverage-data -type f -name 'coverage-controllers-*' -print | sort)
mapfile -t integration_coverage < <(find coverage-data -type f -name 'coverage-integration-*' -print | sort)
if [[ "${#unit_coverage[@]}" -ne 2 ]]; then
echo "expected 2 unit coverage artifacts, found ${#unit_coverage[@]}" >&2
exit 1
fi
if [[ "${#controller_coverage[@]}" -ne 1 ]]; then
echo "expected 1 controller coverage artifact, found ${#controller_coverage[@]}" >&2
exit 1
fi
if [[ "${#integration_coverage[@]}" -ne 1 ]]; then
echo "expected 1 integration coverage artifact, found ${#integration_coverage[@]}" >&2
exit 1
fi
unit_coverage="$(find coverage-data -type f -name coverage-unit -print -quit)"
integration_coverage="$(find coverage-data -type f -name coverage-integration -print -quit)"
: "${unit_coverage:?coverage-unit artifact not found}"
: "${integration_coverage:?coverage-integration artifact not found}"
uvx --from "coverage==$coverage_version" coverage combine "${unit_coverage[@]}" "${controller_coverage[@]}" "${integration_coverage[@]}"
uvx --from "coverage==$coverage_version" coverage xml -o coverage.xml
report_file="$(mktemp)"
uv run --project api coverage combine "$unit_coverage" "$integration_coverage"
uv run --project api coverage report --show-missing | tee "$report_file"
echo "Summary: \`$(tail -n 1 "$report_file")\`" >> "$GITHUB_STEP_SUMMARY"
{
echo ""
echo "<details><summary>Coverage report</summary>"
echo ""
echo '```'
cat "$report_file"
echo '```'
echo "</details>"
} >> "$GITHUB_STEP_SUMMARY"
uv run --project api coverage xml -o coverage.xml
# Reuse the XML totals instead of analyzing every source file again for a text report.
python3 - <<'PY'
import os
import xml.etree.ElementTree as ET
coverage = ET.parse("coverage.xml").getroot()
with open(os.environ["GITHUB_STEP_SUMMARY"], "a") as summary:
summary.write("### API Coverage\n\n")
summary.write("Merged backend coverage report generated for Codecov project status.\n\n")
summary.write("| Metric | Covered | Total | Coverage |\n")
summary.write("| --- | ---: | ---: | ---: |\n")
for label, metric in (("Lines", "lines"), ("Branches", "branches")):
covered = int(coverage.attrib[f"{metric}-covered"])
total = int(coverage.attrib[f"{metric}-valid"])
percentage = f"{covered / total:.2%}" if total else "N/A"
summary.write(f"| {label} | {covered} | {total} | {percentage} |\n")
summary.write("\nSee Codecov for per-file coverage details.\n")
PY
- name: Report coverage
if: ${{ env.CODECOV_TOKEN != '' }}
uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0
uses: codecov/codecov-action@303a32d7a59b442fa8d48b6a1cc6825c09c847a5 # v7.1.1
with:
files: ./coverage.xml
disable_search: true

View File

@@ -1,26 +1,24 @@
name: autofix.ci
on:
pull_request:
branches: ["main"]
branches: ['main']
merge_group:
branches: ["main"]
branches: ['main']
types: [checks_requested]
push:
branches: ["main"]
permissions:
contents: read
jobs:
autofix:
if: github.repository == 'langgenius/dify'
runs-on: depot-ubuntu-24.04
runs-on: depot-ubuntu-24.04-4
steps:
- name: Complete merge group check
if: github.event_name == 'merge_group'
run: echo "autofix.ci updates pull request branches, not merge group refs."
- if: github.event_name != 'merge_group'
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Check Docker Compose inputs
if: github.event_name != 'merge_group'
@@ -32,18 +30,6 @@ jobs:
docker/.env.example
docker/docker-compose-template.yaml
docker/docker-compose.yaml
- name: Check web inputs
if: github.event_name != 'merge_group'
id: web-changes
uses: tj-actions/changed-files@9426d40962ed5378910ee2e21d5f8c6fcbf2dd96 # v47.0.6
with:
files: |
web/**
packages/**
package.json
pnpm-lock.yaml
pnpm-workspace.yaml
.nvmrc
- name: Check api inputs
if: github.event_name != 'merge_group'
id: api-changes
@@ -51,6 +37,18 @@ jobs:
with:
files: |
api/**
- name: Check frontend contract inputs
if: github.event_name != 'merge_group'
id: frontend-contract-changes
uses: tj-actions/changed-files@9426d40962ed5378910ee2e21d5f8c6fcbf2dd96 # v47.0.6
with:
files: |
api/**
packages/contracts/openapi-ts.api.config.ts
packages/contracts/package.json
packages/contracts/openapi/**
pnpm-lock.yaml
pnpm-workspace.yaml
- name: Check dify-agent inputs
if: github.event_name != 'merge_group'
id: dify-agent-changes
@@ -60,13 +58,13 @@ jobs:
dify-agent/**/*.py
dify-agent/pyproject.toml
dify-agent/uv.lock
- if: github.event_name != 'merge_group'
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
- if: github.event_name != 'merge_group' && (steps.docker-compose-changes.outputs.any_changed == 'true' || steps.api-changes.outputs.any_changed == 'true' || steps.frontend-contract-changes.outputs.any_changed == 'true' || steps.dify-agent-changes.outputs.any_changed == 'true')
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with:
python-version: "3.11"
python-version: '3.11'
- if: github.event_name != 'merge_group'
uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
- if: github.event_name != 'merge_group' && (steps.api-changes.outputs.any_changed == 'true' || steps.frontend-contract-changes.outputs.any_changed == 'true' || steps.dify-agent-changes.outputs.any_changed == 'true')
uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0
- name: Generate Docker Compose
if: github.event_name != 'merge_group' && steps.docker-compose-changes.outputs.any_changed == 'true'
@@ -96,12 +94,6 @@ jobs:
# Format code
uv run ruff format .
- name: count migration progress
if: github.event_name != 'merge_group' && steps.api-changes.outputs.any_changed == 'true'
run: |
cd api
./cnt_base.sh
- name: ast-grep
if: github.event_name != 'merge_group' && steps.api-changes.outputs.any_changed == 'true'
run: |
@@ -133,7 +125,7 @@ jobs:
find . -name "*.py.bak" -type f -delete
- name: Setup web environment
if: github.event_name != 'merge_group'
if: github.event_name != 'merge_group' && steps.frontend-contract-changes.outputs.any_changed == 'true'
uses: ./.github/actions/setup-web
- name: Generate API docs
@@ -143,13 +135,8 @@ jobs:
uv run dev/generate_swagger_markdown_docs.py --swagger-dir ../packages/contracts/openapi --markdown-dir openapi/markdown --keep-swagger-json
- name: Generate frontend contracts
if: github.event_name != 'merge_group' && steps.api-changes.outputs.any_changed == 'true'
run: pnpm --dir packages/contracts gen-api-contract-from-openapi
- name: ESLint autofix
if: github.event_name != 'merge_group' && steps.web-changes.outputs.any_changed == 'true'
run: |
vp exec eslint --concurrency=2 --prune-suppressions --quiet || true
if: github.event_name != 'merge_group' && steps.frontend-contract-changes.outputs.any_changed == 'true'
run: pnpm --dir packages/contracts gen-api-contract
- if: github.event_name != 'merge_group'
uses: autofix-ci/action@c5b2d67aa2274e7b5a18224e8171550871fc7e4a # v1.3.4

View File

@@ -3,13 +3,13 @@ name: Build and Push API & Web
on:
push:
branches:
- "main"
- "deploy/**"
- "build/**"
- "release/e-*"
- "hotfix/**"
- 'main'
- 'deploy/**'
- 'build/**'
- 'release/e-*'
- 'hotfix/**'
tags:
- "*"
- '*'
concurrency:
group: build-push-${{ github.head_ref || github.run_id }}
@@ -33,60 +33,60 @@ jobs:
strategy:
matrix:
include:
- service_name: "build-api-amd64"
image_name_env: "DIFY_API_IMAGE_NAME"
artifact_context: "api"
build_context: "{{defaultContext}}"
file: "api/Dockerfile"
- service_name: 'build-api-amd64'
image_name_env: 'DIFY_API_IMAGE_NAME'
artifact_context: 'api'
build_context: '{{defaultContext}}'
file: 'api/Dockerfile'
platform: linux/amd64
runs_on: depot-ubuntu-24.04-4
- service_name: "build-api-arm64"
image_name_env: "DIFY_API_IMAGE_NAME"
artifact_context: "api"
build_context: "{{defaultContext}}"
file: "api/Dockerfile"
- service_name: 'build-api-arm64'
image_name_env: 'DIFY_API_IMAGE_NAME'
artifact_context: 'api'
build_context: '{{defaultContext}}'
file: 'api/Dockerfile'
platform: linux/arm64
runs_on: depot-ubuntu-24.04-4
- service_name: "build-web-amd64"
image_name_env: "DIFY_WEB_IMAGE_NAME"
artifact_context: "web"
build_context: "{{defaultContext}}"
file: "web/Dockerfile"
- service_name: 'build-web-amd64'
image_name_env: 'DIFY_WEB_IMAGE_NAME'
artifact_context: 'web'
build_context: '{{defaultContext}}'
file: 'web/Dockerfile'
platform: linux/amd64
runs_on: depot-ubuntu-24.04-4
- service_name: "build-web-arm64"
image_name_env: "DIFY_WEB_IMAGE_NAME"
artifact_context: "web"
build_context: "{{defaultContext}}"
file: "web/Dockerfile"
- service_name: 'build-web-arm64'
image_name_env: 'DIFY_WEB_IMAGE_NAME'
artifact_context: 'web'
build_context: '{{defaultContext}}'
file: 'web/Dockerfile'
platform: linux/arm64
runs_on: depot-ubuntu-24.04-4
- service_name: "build-agent-amd64"
image_name_env: "DIFY_AGENT_IMAGE_NAME"
artifact_context: "agent"
build_context: "{{defaultContext}}"
file: "dify-agent/Dockerfile"
- service_name: 'build-agent-amd64'
image_name_env: 'DIFY_AGENT_IMAGE_NAME'
artifact_context: 'agent'
build_context: '{{defaultContext}}'
file: 'dify-agent/Dockerfile'
platform: linux/amd64
runs_on: depot-ubuntu-24.04-4
- service_name: "build-agent-arm64"
image_name_env: "DIFY_AGENT_IMAGE_NAME"
artifact_context: "agent"
build_context: "{{defaultContext}}"
file: "dify-agent/Dockerfile"
- service_name: 'build-agent-arm64'
image_name_env: 'DIFY_AGENT_IMAGE_NAME'
artifact_context: 'agent'
build_context: '{{defaultContext}}'
file: 'dify-agent/Dockerfile'
platform: linux/arm64
runs_on: depot-ubuntu-24.04-4
- service_name: "build-agent-local-sandbox-amd64"
image_name_env: "DIFY_AGENT_LOCAL_SANDBOX_IMAGE_NAME"
artifact_context: "local-sandbox"
build_context: "{{defaultContext}}:dify-agent"
file: "docker/local-sandbox/Dockerfile"
- service_name: 'build-agent-local-sandbox-amd64'
image_name_env: 'DIFY_AGENT_LOCAL_SANDBOX_IMAGE_NAME'
artifact_context: 'local-sandbox'
build_context: '{{defaultContext}}:dify-agent-runtime'
file: 'docker/Dockerfile'
platform: linux/amd64
runs_on: depot-ubuntu-24.04-4
- service_name: "build-agent-local-sandbox-arm64"
image_name_env: "DIFY_AGENT_LOCAL_SANDBOX_IMAGE_NAME"
artifact_context: "local-sandbox"
build_context: "{{defaultContext}}:dify-agent"
file: "docker/local-sandbox/Dockerfile"
- service_name: 'build-agent-local-sandbox-arm64'
image_name_env: 'DIFY_AGENT_LOCAL_SANDBOX_IMAGE_NAME'
artifact_context: 'local-sandbox'
build_context: '{{defaultContext}}:dify-agent-runtime'
file: 'docker/Dockerfile'
platform: linux/arm64
runs_on: depot-ubuntu-24.04-4
@@ -97,17 +97,17 @@ jobs:
echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV
- name: Login to Docker Hub
uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee # v4.2.0
uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4.6.0
with:
username: ${{ env.DOCKERHUB_USER }}
password: ${{ env.DOCKERHUB_TOKEN }}
- name: Set up Depot CLI
uses: depot/setup-action@15c09a5f77a0840ad4bce955686522a257853461 # v1.7.1
uses: depot/setup-action@91bc8495a33ebfc504ffc89e5674379ccf23c29c # v1.7.2
- name: Extract metadata for Docker
id: meta
uses: docker/metadata-action@80c7e94dd9b9319bd5eb7a0e0fe9291e23a2a2e9 # v6.1.0
uses: docker/metadata-action@dc802804100637a589fabce1cb79ff13a1411302 # v6.2.0
with:
images: ${{ env[matrix.image_name_env] }}
@@ -120,6 +120,7 @@ jobs:
file: ${{ matrix.file }}
platforms: ${{ matrix.platform }}
build-args: COMMIT_SHA=${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.revision'] }}
build-contexts: ${{ matrix.build_contexts }}
labels: ${{ steps.meta.outputs.labels }}
outputs: type=image,name=${{ env[matrix.image_name_env] }},push-by-digest=true,name-canonical=true,push=true
@@ -145,28 +146,29 @@ jobs:
strategy:
matrix:
include:
- service_name: "validate-api-amd64"
build_context: "{{defaultContext}}"
file: "api/Dockerfile"
- service_name: "validate-web-amd64"
build_context: "{{defaultContext}}"
file: "web/Dockerfile"
- service_name: "validate-agent-amd64"
build_context: "{{defaultContext}}"
file: "dify-agent/Dockerfile"
- service_name: "validate-agent-local-sandbox-amd64"
build_context: "{{defaultContext}}:dify-agent"
file: "docker/local-sandbox/Dockerfile"
- service_name: 'validate-api-amd64'
build_context: '{{defaultContext}}'
file: 'api/Dockerfile'
- service_name: 'validate-web-amd64'
build_context: '{{defaultContext}}'
file: 'web/Dockerfile'
- service_name: 'validate-agent-amd64'
build_context: '{{defaultContext}}'
file: 'dify-agent/Dockerfile'
- service_name: 'validate-agent-local-sandbox-amd64'
build_context: '{{defaultContext}}:dify-agent-runtime'
file: 'docker/Dockerfile'
steps:
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5 # v4.1.0
uses: docker/setup-buildx-action@f87e5991a6d7451dcb8d9637bfbc97413f497069 # v4.4.1
- name: Validate Docker image
uses: docker/build-push-action@f9f3042f7e2789586610d6e8b85c8f03e5195baf # v7.2.0
uses: docker/build-push-action@c3c9e263c25d99ce0380d002d59b67737d91b0dc # v7.4.0
with:
push: false
context: ${{ matrix.build_context }}
file: ${{ matrix.file }}
build-contexts: ${{ matrix.build_contexts }}
platforms: linux/amd64
create-manifest:
@@ -176,18 +178,18 @@ jobs:
strategy:
matrix:
include:
- service_name: "merge-api-images"
image_name_env: "DIFY_API_IMAGE_NAME"
context: "api"
- service_name: "merge-web-images"
image_name_env: "DIFY_WEB_IMAGE_NAME"
context: "web"
- service_name: "merge-agent-images"
image_name_env: "DIFY_AGENT_IMAGE_NAME"
context: "agent"
- service_name: "merge-agent-local-sandbox-images"
image_name_env: "DIFY_AGENT_LOCAL_SANDBOX_IMAGE_NAME"
context: "local-sandbox"
- service_name: 'merge-api-images'
image_name_env: 'DIFY_API_IMAGE_NAME'
context: 'api'
- service_name: 'merge-web-images'
image_name_env: 'DIFY_WEB_IMAGE_NAME'
context: 'web'
- service_name: 'merge-agent-images'
image_name_env: 'DIFY_AGENT_IMAGE_NAME'
context: 'agent'
- service_name: 'merge-agent-local-sandbox-images'
image_name_env: 'DIFY_AGENT_LOCAL_SANDBOX_IMAGE_NAME'
context: 'local-sandbox'
steps:
- name: Download digests
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
@@ -197,14 +199,14 @@ jobs:
merge-multiple: true
- name: Login to Docker Hub
uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee # v4.2.0
uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4.6.0
with:
username: ${{ env.DOCKERHUB_USER }}
password: ${{ env.DOCKERHUB_TOKEN }}
- name: Extract metadata for Docker
id: meta
uses: docker/metadata-action@80c7e94dd9b9319bd5eb7a0e0fe9291e23a2a2e9 # v6.1.0
uses: docker/metadata-action@dc802804100637a589fabce1cb79ff13a1411302 # v6.2.0
with:
images: ${{ env[matrix.image_name_env] }}
tags: |
@@ -227,3 +229,38 @@ jobs:
IMAGE_VERSION: ${{ steps.meta.outputs.version }}
run: |
docker buildx imagetools inspect "$IMAGE_NAME:$IMAGE_VERSION"
sync-e2b-template:
needs: create-manifest
runs-on: ubuntu-24.04
if: github.repository == 'langgenius/dify' && startsWith(github.ref, 'refs/tags/')
strategy:
matrix:
include:
- project: dev
api_key_secret: E2B_API_KEY_DEV
- project: prod
api_key_secret: E2B_API_KEY_PROD
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Use Node.js
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version-file: package.json
cache: ''
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@f87e5991a6d7451dcb8d9637bfbc97413f497069 # v4.4.1
- name: Login to Docker Hub
uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4.6.0
with:
username: ${{ env.DOCKERHUB_USER }}
password: ${{ env.DOCKERHUB_TOKEN }}
- name: Sync E2B Template (${{ matrix.project }})
env:
E2B_API_KEY: ${{ secrets[matrix.api_key_secret] }}
run: ./dify-agent-runtime/docker/sync-e2b-template.sh

View File

@@ -4,19 +4,19 @@ on:
workflow_dispatch:
inputs:
cli_ref:
description: "Git ref (default: current branch)"
description: 'Git ref (default: current branch)'
type: string
required: false
edition:
description: "Dify edition"
description: 'Dify edition'
type: choice
required: false
default: ee
options: [ee, ce]
test_scope:
description: "smoke = [P0] only / full = all cases"
description: 'smoke = [P0] only / full = all cases'
type: choice
required: false
default: full
@@ -24,23 +24,23 @@ on:
# ── Suite on/off ────────────────────────────────────────────────────────
suite_framework_output_error:
description: "framework + output + error-handling suites"
description: 'framework + output + error-handling suites'
type: boolean
default: true
suite_discovery:
description: "discovery suite (get app / describe app)"
description: 'discovery suite (get app / describe app)'
type: boolean
default: true
suite_run:
description: "run suite (basic / streaming / conversation / file / hitl)"
description: 'run suite (basic / streaming / conversation / file / hitl)'
type: boolean
default: true
suite_auth:
description: "auth suite (login / status / whoami / use / devices / logout)"
description: 'auth suite (login / status / whoami / use / devices / logout)'
type: boolean
default: true
suite_agent:
description: "agent suite"
description: 'agent suite'
type: boolean
default: true
@@ -51,35 +51,34 @@ permissions:
# Each job reads DIFY_E2E_TOKEN + app IDs from the provision job outputs,
# so global-setup skips minting and finds existing apps in < 10 s.
env:
DIFY_E2E_NO_KEYRING: "1" # Linux CI has no keychain; skip probe
VITEST_RETRY: "2" # Retry flaky staging responses
DIFY_E2E_NO_KEYRING: '1' # Linux CI has no keychain; skip probe
VITEST_RETRY: '2' # Retry flaky staging responses
jobs:
# ════════════════════════════════════════════════════════════════════════════
# 0. PROVISION — mint token + import DSL fixtures (runs once, outputs IDs)
# ════════════════════════════════════════════════════════════════════════════
# ════════════════════════════════════════════════════════════════════════════
# 0. PROVISION — mint token + import DSL fixtures (runs once, outputs IDs)
# ════════════════════════════════════════════════════════════════════════════
provision:
name: "Provision: mint token + DSL apps"
name: 'Provision: mint token + DSL apps'
runs-on: ubuntu-latest
timeout-minutes: 10
outputs:
token: ${{ steps.out.outputs.DIFY_E2E_TOKEN }}
workspace_id: ${{ steps.out.outputs.DIFY_E2E_WORKSPACE_ID }}
workspace_name: ${{ steps.out.outputs.DIFY_E2E_WORKSPACE_NAME }}
ws2_id: ${{ steps.out.outputs.DIFY_E2E_WS2_ID }}
chat_app_id: ${{ steps.out.outputs.DIFY_E2E_CHAT_APP_ID }}
workflow_app_id: ${{ steps.out.outputs.DIFY_E2E_WORKFLOW_APP_ID }}
file_app_id: ${{ steps.out.outputs.DIFY_E2E_FILE_APP_ID }}
file_chat_app_id: ${{ steps.out.outputs.DIFY_E2E_FILE_CHAT_APP_ID }}
hitl_app_id: ${{ steps.out.outputs.DIFY_E2E_HITL_APP_ID }}
hitl_external_app_id: ${{ steps.out.outputs.DIFY_E2E_HITL_EXTERNAL_APP_ID }}
hitl_single_action_app_id: ${{ steps.out.outputs.DIFY_E2E_HITL_SINGLE_ACTION_APP_ID }}
hitl_multi_node_app_id: ${{ steps.out.outputs.DIFY_E2E_HITL_MULTI_NODE_APP_ID }}
ws2_app_id: ${{ steps.out.outputs.DIFY_E2E_WS2_APP_ID }}
token: ${{ steps.out.outputs.DIFY_E2E_TOKEN }}
workspace_id: ${{ steps.out.outputs.DIFY_E2E_WORKSPACE_ID }}
workspace_name: ${{ steps.out.outputs.DIFY_E2E_WORKSPACE_NAME }}
ws2_id: ${{ steps.out.outputs.DIFY_E2E_WS2_ID }}
chat_app_id: ${{ steps.out.outputs.DIFY_E2E_CHAT_APP_ID }}
workflow_app_id: ${{ steps.out.outputs.DIFY_E2E_WORKFLOW_APP_ID }}
file_app_id: ${{ steps.out.outputs.DIFY_E2E_FILE_APP_ID }}
file_chat_app_id: ${{ steps.out.outputs.DIFY_E2E_FILE_CHAT_APP_ID }}
hitl_app_id: ${{ steps.out.outputs.DIFY_E2E_HITL_APP_ID }}
hitl_external_app_id: ${{ steps.out.outputs.DIFY_E2E_HITL_EXTERNAL_APP_ID }}
hitl_single_action_app_id: ${{ steps.out.outputs.DIFY_E2E_HITL_SINGLE_ACTION_APP_ID }}
hitl_multi_node_app_id: ${{ steps.out.outputs.DIFY_E2E_HITL_MULTI_NODE_APP_ID }}
ws2_app_id: ${{ steps.out.outputs.DIFY_E2E_WS2_APP_ID }}
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v4
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
ref: ${{ inputs.cli_ref || github.ref }}
persist-credentials: false
@@ -88,10 +87,9 @@ jobs:
with:
bun-version: latest
- uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6.0.9
- uses: pnpm/setup@fbda4c85fc2e1e08721cd8763afea8f48d60f024 # v3.0.0
with:
package_json_field: packageManager
run_install: false
install: false
- name: Install CLI dependencies
working-directory: cli
@@ -101,19 +99,19 @@ jobs:
id: out
working-directory: cli
env:
DIFY_E2E_HOST: ${{ secrets.DIFY_E2E_HOST }}
DIFY_E2E_EMAIL: ${{ secrets.DIFY_E2E_EMAIL }}
DIFY_E2E_HOST: ${{ secrets.DIFY_E2E_HOST }}
DIFY_E2E_EMAIL: ${{ secrets.DIFY_E2E_EMAIL }}
DIFY_E2E_PASSWORD: ${{ secrets.DIFY_E2E_PASSWORD }}
DIFY_E2E_TOKEN: ${{ secrets.DIFY_E2E_TOKEN }}
DIFY_E2E_EDITION: ${{ inputs.edition || 'ee' }}
DIFY_E2E_TOKEN: ${{ secrets.DIFY_E2E_TOKEN }}
DIFY_E2E_EDITION: ${{ inputs.edition || 'ee' }}
run: bun scripts/e2e-provision.ts
# ════════════════════════════════════════════════════════════════════════════
# 1-B. framework + output + error-handling (parallel with run/discovery)
# ════════════════════════════════════════════════════════════════════════════
# ════════════════════════════════════════════════════════════════════════════
# 1-B. framework + output + error-handling (parallel with run/discovery)
# ════════════════════════════════════════════════════════════════════════════
suite-framework-output-error:
name: "Suite: framework + output + error-handling"
if: ${{ inputs.suite_framework_output_error != 'false' }}
name: 'Suite: framework + output + error-handling'
if: ${{ inputs.suite_framework_output_error }}
needs: provision
runs-on: ubuntu-latest
timeout-minutes: 20
@@ -123,31 +121,29 @@ jobs:
shell: bash
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v4
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
ref: ${{ inputs.cli_ref || github.ref }}
persist-credentials: false
- uses: ./.github/actions/setup-web
- uses: oven-sh/setup-bun@v2
with: { bun-version: latest }
- uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6.0.9
with: { package_json_field: packageManager, run_install: false }
- run: pnpm install --frozen-lockfile
with:
bun-version: latest
- run: pnpm tree:gen
- name: Run framework + output + error-handling
env:
DIFY_E2E_HOST: ${{ secrets.DIFY_E2E_HOST }}
DIFY_E2E_EMAIL: ${{ secrets.DIFY_E2E_EMAIL }}
DIFY_E2E_PASSWORD: ${{ secrets.DIFY_E2E_PASSWORD }}
DIFY_E2E_EDITION: ${{ inputs.edition || 'ee' }}
DIFY_E2E_TOKEN: ${{ needs.provision.outputs.token }}
DIFY_E2E_WORKSPACE_ID: ${{ needs.provision.outputs.workspace_id }}
DIFY_E2E_HOST: ${{ secrets.DIFY_E2E_HOST }}
DIFY_E2E_EMAIL: ${{ secrets.DIFY_E2E_EMAIL }}
DIFY_E2E_PASSWORD: ${{ secrets.DIFY_E2E_PASSWORD }}
DIFY_E2E_EDITION: ${{ inputs.edition || 'ee' }}
DIFY_E2E_TOKEN: ${{ needs.provision.outputs.token }}
DIFY_E2E_WORKSPACE_ID: ${{ needs.provision.outputs.workspace_id }}
DIFY_E2E_WORKSPACE_NAME: ${{ needs.provision.outputs.workspace_name }}
DIFY_E2E_CHAT_APP_ID: ${{ needs.provision.outputs.chat_app_id }}
DIFY_E2E_CHAT_APP_ID: ${{ needs.provision.outputs.chat_app_id }}
DIFY_E2E_WORKFLOW_APP_ID: ${{ needs.provision.outputs.workflow_app_id }}
DIFY_E2E_INCLUDE: "test/e2e/suites/framework/**/*.e2e.ts,test/e2e/suites/output/**/*.e2e.ts,test/e2e/suites/error-handling/**/*.e2e.ts"
DIFY_E2E_INCLUDE: 'test/e2e/suites/framework/**/*.e2e.ts,test/e2e/suites/output/**/*.e2e.ts,test/e2e/suites/error-handling/**/*.e2e.ts'
run: |
if [ "${{ inputs.test_scope }}" = "smoke" ]; then
pnpm test:e2e -- -t "\[P0\]"
@@ -155,12 +151,12 @@ jobs:
pnpm test:e2e
fi
# ════════════════════════════════════════════════════════════════════════════
# 1-C. Discovery (parallel)
# ════════════════════════════════════════════════════════════════════════════
# ════════════════════════════════════════════════════════════════════════════
# 1-C. Discovery (parallel)
# ════════════════════════════════════════════════════════════════════════════
suite-discovery:
name: "Suite: discovery"
if: ${{ inputs.suite_discovery != 'false' }}
name: 'Suite: discovery'
if: ${{ inputs.suite_discovery }}
needs: provision
runs-on: ubuntu-latest
timeout-minutes: 20
@@ -170,32 +166,30 @@ jobs:
shell: bash
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v4
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
ref: ${{ inputs.cli_ref || github.ref }}
persist-credentials: false
- uses: ./.github/actions/setup-web
- uses: oven-sh/setup-bun@v2
with: { bun-version: latest }
- uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6.0.9
with: { package_json_field: packageManager, run_install: false }
- run: pnpm install --frozen-lockfile
with:
bun-version: latest
- run: pnpm tree:gen
- name: Run discovery suite
env:
DIFY_E2E_HOST: ${{ secrets.DIFY_E2E_HOST }}
DIFY_E2E_EMAIL: ${{ secrets.DIFY_E2E_EMAIL }}
DIFY_E2E_PASSWORD: ${{ secrets.DIFY_E2E_PASSWORD }}
DIFY_E2E_EDITION: ${{ inputs.edition || 'ee' }}
DIFY_E2E_TOKEN: ${{ needs.provision.outputs.token }}
DIFY_E2E_WORKSPACE_ID: ${{ needs.provision.outputs.workspace_id }}
DIFY_E2E_HOST: ${{ secrets.DIFY_E2E_HOST }}
DIFY_E2E_EMAIL: ${{ secrets.DIFY_E2E_EMAIL }}
DIFY_E2E_PASSWORD: ${{ secrets.DIFY_E2E_PASSWORD }}
DIFY_E2E_EDITION: ${{ inputs.edition || 'ee' }}
DIFY_E2E_TOKEN: ${{ needs.provision.outputs.token }}
DIFY_E2E_WORKSPACE_ID: ${{ needs.provision.outputs.workspace_id }}
DIFY_E2E_WORKSPACE_NAME: ${{ needs.provision.outputs.workspace_name }}
DIFY_E2E_WS2_ID: ${{ needs.provision.outputs.ws2_id }}
DIFY_E2E_CHAT_APP_ID: ${{ needs.provision.outputs.chat_app_id }}
DIFY_E2E_WS2_ID: ${{ needs.provision.outputs.ws2_id }}
DIFY_E2E_CHAT_APP_ID: ${{ needs.provision.outputs.chat_app_id }}
DIFY_E2E_WORKFLOW_APP_ID: ${{ needs.provision.outputs.workflow_app_id }}
DIFY_E2E_INCLUDE: "test/e2e/suites/discovery/**/*.e2e.ts"
DIFY_E2E_INCLUDE: 'test/e2e/suites/discovery/**/*.e2e.ts'
run: |
if [ "${{ inputs.test_scope }}" = "smoke" ]; then
pnpm test:e2e -- -t "\[P0\]"
@@ -203,12 +197,12 @@ jobs:
pnpm test:e2e
fi
# ════════════════════════════════════════════════════════════════════════════
# 1-D. Run suite — 5 files in matrix (parallel)
# ════════════════════════════════════════════════════════════════════════════
# ════════════════════════════════════════════════════════════════════════════
# 1-D. Run suite — 5 files in matrix (parallel)
# ════════════════════════════════════════════════════════════════════════════
suite-run:
name: "Suite: run / ${{ matrix.name }}"
if: ${{ inputs.suite_run != 'false' }}
name: 'Suite: run / ${{ matrix.name }}'
if: ${{ inputs.suite_run }}
needs: provision
runs-on: ubuntu-latest
timeout-minutes: 20
@@ -233,38 +227,36 @@ jobs:
shell: bash
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v4
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
ref: ${{ inputs.cli_ref || github.ref }}
persist-credentials: false
- uses: ./.github/actions/setup-web
- uses: oven-sh/setup-bun@v2
with: { bun-version: latest }
- uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6.0.9
with: { package_json_field: packageManager, run_install: false }
- run: pnpm install --frozen-lockfile
with:
bun-version: latest
- run: pnpm tree:gen
- name: "Run run/${{ matrix.name }}"
- name: 'Run run/${{ matrix.name }}'
env:
DIFY_E2E_HOST: ${{ secrets.DIFY_E2E_HOST }}
DIFY_E2E_EMAIL: ${{ secrets.DIFY_E2E_EMAIL }}
DIFY_E2E_PASSWORD: ${{ secrets.DIFY_E2E_PASSWORD }}
DIFY_E2E_EDITION: ${{ inputs.edition || 'ee' }}
DIFY_E2E_SSO_TOKEN: ${{ secrets.DIFY_E2E_SSO_TOKEN }}
DIFY_E2E_TOKEN: ${{ needs.provision.outputs.token }}
DIFY_E2E_WORKSPACE_ID: ${{ needs.provision.outputs.workspace_id }}
DIFY_E2E_WORKSPACE_NAME: ${{ needs.provision.outputs.workspace_name }}
DIFY_E2E_CHAT_APP_ID: ${{ needs.provision.outputs.chat_app_id }}
DIFY_E2E_WORKFLOW_APP_ID: ${{ needs.provision.outputs.workflow_app_id }}
DIFY_E2E_FILE_APP_ID: ${{ needs.provision.outputs.file_app_id }}
DIFY_E2E_FILE_CHAT_APP_ID: ${{ needs.provision.outputs.file_chat_app_id }}
DIFY_E2E_HITL_APP_ID: ${{ needs.provision.outputs.hitl_app_id }}
DIFY_E2E_HITL_EXTERNAL_APP_ID: ${{ needs.provision.outputs.hitl_external_app_id }}
DIFY_E2E_HOST: ${{ secrets.DIFY_E2E_HOST }}
DIFY_E2E_EMAIL: ${{ secrets.DIFY_E2E_EMAIL }}
DIFY_E2E_PASSWORD: ${{ secrets.DIFY_E2E_PASSWORD }}
DIFY_E2E_EDITION: ${{ inputs.edition || 'ee' }}
DIFY_E2E_SSO_TOKEN: ${{ secrets.DIFY_E2E_SSO_TOKEN }}
DIFY_E2E_TOKEN: ${{ needs.provision.outputs.token }}
DIFY_E2E_WORKSPACE_ID: ${{ needs.provision.outputs.workspace_id }}
DIFY_E2E_WORKSPACE_NAME: ${{ needs.provision.outputs.workspace_name }}
DIFY_E2E_CHAT_APP_ID: ${{ needs.provision.outputs.chat_app_id }}
DIFY_E2E_WORKFLOW_APP_ID: ${{ needs.provision.outputs.workflow_app_id }}
DIFY_E2E_FILE_APP_ID: ${{ needs.provision.outputs.file_app_id }}
DIFY_E2E_FILE_CHAT_APP_ID: ${{ needs.provision.outputs.file_chat_app_id }}
DIFY_E2E_HITL_APP_ID: ${{ needs.provision.outputs.hitl_app_id }}
DIFY_E2E_HITL_EXTERNAL_APP_ID: ${{ needs.provision.outputs.hitl_external_app_id }}
DIFY_E2E_HITL_SINGLE_ACTION_APP_ID: ${{ needs.provision.outputs.hitl_single_action_app_id }}
DIFY_E2E_HITL_MULTI_NODE_APP_ID: ${{ needs.provision.outputs.hitl_multi_node_app_id }}
DIFY_E2E_INCLUDE: "test/e2e/suites/run/${{ matrix.file }}"
DIFY_E2E_HITL_MULTI_NODE_APP_ID: ${{ needs.provision.outputs.hitl_multi_node_app_id }}
DIFY_E2E_INCLUDE: 'test/e2e/suites/run/${{ matrix.file }}'
run: |
if [ "${{ inputs.test_scope }}" = "smoke" ]; then
pnpm test:e2e -- -t "\[P0\]"
@@ -274,18 +266,18 @@ jobs:
- name: Upload results on failure
if: failure()
uses: actions/upload-artifact@v7
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: e2e-run-${{ matrix.name }}-${{ github.run_id }}
path: cli/test-results/
retention-days: 3
# ════════════════════════════════════════════════════════════════════════════
# 1-E. auth/login + status + whoami (parallel, read-only, safe)
# ════════════════════════════════════════════════════════════════════════════
# ════════════════════════════════════════════════════════════════════════════
# 1-E. auth/login + status + whoami (parallel, read-only, safe)
# ════════════════════════════════════════════════════════════════════════════
suite-auth-safe:
name: "Suite: auth (login / status / whoami)"
if: ${{ inputs.suite_auth != 'false' }}
name: 'Suite: auth (login / status / whoami)'
if: ${{ inputs.suite_auth }}
needs: provision
runs-on: ubuntu-latest
timeout-minutes: 15
@@ -295,30 +287,28 @@ jobs:
shell: bash
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v4
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
ref: ${{ inputs.cli_ref || github.ref }}
persist-credentials: false
- uses: ./.github/actions/setup-web
- uses: oven-sh/setup-bun@v2
with: { bun-version: latest }
- uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6.0.9
with: { package_json_field: packageManager, run_install: false }
- run: pnpm install --frozen-lockfile
with:
bun-version: latest
- run: pnpm tree:gen
- name: Run auth/login + status + whoami
env:
DIFY_E2E_HOST: ${{ secrets.DIFY_E2E_HOST }}
DIFY_E2E_EMAIL: ${{ secrets.DIFY_E2E_EMAIL }}
DIFY_E2E_PASSWORD: ${{ secrets.DIFY_E2E_PASSWORD }}
DIFY_E2E_EDITION: ${{ inputs.edition || 'ee' }}
DIFY_E2E_TOKEN: ${{ needs.provision.outputs.token }}
DIFY_E2E_WORKSPACE_ID: ${{ needs.provision.outputs.workspace_id }}
DIFY_E2E_HOST: ${{ secrets.DIFY_E2E_HOST }}
DIFY_E2E_EMAIL: ${{ secrets.DIFY_E2E_EMAIL }}
DIFY_E2E_PASSWORD: ${{ secrets.DIFY_E2E_PASSWORD }}
DIFY_E2E_EDITION: ${{ inputs.edition || 'ee' }}
DIFY_E2E_TOKEN: ${{ needs.provision.outputs.token }}
DIFY_E2E_WORKSPACE_ID: ${{ needs.provision.outputs.workspace_id }}
DIFY_E2E_WORKSPACE_NAME: ${{ needs.provision.outputs.workspace_name }}
DIFY_E2E_WS2_ID: ${{ needs.provision.outputs.ws2_id }}
DIFY_E2E_INCLUDE: "test/e2e/suites/auth/login.e2e.ts,test/e2e/suites/auth/status.e2e.ts,test/e2e/suites/auth/whoami.e2e.ts"
DIFY_E2E_WS2_ID: ${{ needs.provision.outputs.ws2_id }}
DIFY_E2E_INCLUDE: 'test/e2e/suites/auth/login.e2e.ts,test/e2e/suites/auth/status.e2e.ts,test/e2e/suites/auth/whoami.e2e.ts'
run: |
if [ "${{ inputs.test_scope }}" = "smoke" ]; then
pnpm test:e2e -- -t "\[P0\]"
@@ -326,15 +316,15 @@ jobs:
pnpm test:e2e
fi
# ════════════════════════════════════════════════════════════════════════════
# 2. DESTRUCTIVE — auth/use + devices + logout + agent (serial, runs LAST)
# Must wait for ALL parallel suites to finish to avoid token revocation
# invalidating other in-flight requests.
# ════════════════════════════════════════════════════════════════════════════
# ════════════════════════════════════════════════════════════════════════════
# 2. DESTRUCTIVE — auth/use + devices + logout + agent (serial, runs LAST)
# Must wait for ALL parallel suites to finish to avoid token revocation
# invalidating other in-flight requests.
# ════════════════════════════════════════════════════════════════════════════
suite-last:
name: "Suite: auth-use + devices + logout + agent (last, serial)"
name: 'Suite: auth-use + devices + logout + agent (last, serial)'
# Runs when auth is selected; also runs after all parallel jobs finish
if: ${{ inputs.suite_auth != 'false' || inputs.suite_agent != 'false' }}
if: ${{ inputs.suite_auth || inputs.suite_agent }}
needs:
- provision
- suite-framework-output-error
@@ -351,35 +341,33 @@ jobs:
shell: bash
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v4
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
ref: ${{ inputs.cli_ref || github.ref }}
persist-credentials: false
- uses: ./.github/actions/setup-web
- uses: oven-sh/setup-bun@v2
with: { bun-version: latest }
- uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6.0.9
with: { package_json_field: packageManager, run_install: false }
- run: pnpm install --frozen-lockfile
with:
bun-version: latest
- run: pnpm tree:gen
- name: Run use / devices / logout / agent (serial)
env:
DIFY_E2E_HOST: ${{ secrets.DIFY_E2E_HOST }}
DIFY_E2E_EMAIL: ${{ secrets.DIFY_E2E_EMAIL }}
DIFY_E2E_PASSWORD: ${{ secrets.DIFY_E2E_PASSWORD }}
DIFY_E2E_EDITION: ${{ inputs.edition || 'ee' }}
DIFY_E2E_TOKEN: ${{ needs.provision.outputs.token }}
DIFY_E2E_WORKSPACE_ID: ${{ needs.provision.outputs.workspace_id }}
DIFY_E2E_WORKSPACE_NAME: ${{ needs.provision.outputs.workspace_name }}
DIFY_E2E_WS2_ID: ${{ needs.provision.outputs.ws2_id }}
DIFY_E2E_CHAT_APP_ID: ${{ needs.provision.outputs.chat_app_id }}
DIFY_E2E_WORKFLOW_APP_ID: ${{ needs.provision.outputs.workflow_app_id }}
DIFY_E2E_HITL_APP_ID: ${{ needs.provision.outputs.hitl_app_id }}
DIFY_E2E_HITL_EXTERNAL_APP_ID: ${{ needs.provision.outputs.hitl_external_app_id }}
DIFY_E2E_HOST: ${{ secrets.DIFY_E2E_HOST }}
DIFY_E2E_EMAIL: ${{ secrets.DIFY_E2E_EMAIL }}
DIFY_E2E_PASSWORD: ${{ secrets.DIFY_E2E_PASSWORD }}
DIFY_E2E_EDITION: ${{ inputs.edition || 'ee' }}
DIFY_E2E_TOKEN: ${{ needs.provision.outputs.token }}
DIFY_E2E_WORKSPACE_ID: ${{ needs.provision.outputs.workspace_id }}
DIFY_E2E_WORKSPACE_NAME: ${{ needs.provision.outputs.workspace_name }}
DIFY_E2E_WS2_ID: ${{ needs.provision.outputs.ws2_id }}
DIFY_E2E_CHAT_APP_ID: ${{ needs.provision.outputs.chat_app_id }}
DIFY_E2E_WORKFLOW_APP_ID: ${{ needs.provision.outputs.workflow_app_id }}
DIFY_E2E_HITL_APP_ID: ${{ needs.provision.outputs.hitl_app_id }}
DIFY_E2E_HITL_EXTERNAL_APP_ID: ${{ needs.provision.outputs.hitl_external_app_id }}
DIFY_E2E_HITL_SINGLE_ACTION_APP_ID: ${{ needs.provision.outputs.hitl_single_action_app_id }}
DIFY_E2E_HITL_MULTI_NODE_APP_ID: ${{ needs.provision.outputs.hitl_multi_node_app_id }}
DIFY_E2E_HITL_MULTI_NODE_APP_ID: ${{ needs.provision.outputs.hitl_multi_node_app_id }}
run: |
# Collect files in safe order: use → devices → logout (revokes last) → agent
FILES=()
@@ -408,7 +396,7 @@ jobs:
- name: Upload results on failure
if: failure()
uses: actions/upload-artifact@v7
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: e2e-last-${{ github.run_id }}
path: cli/test-results/

View File

@@ -5,6 +5,7 @@ on:
branches: [main]
paths:
- 'cli/**'
- 'skills/**'
- 'packages/contracts/generated/api/openapi/**'
workflow_dispatch:
@@ -23,7 +24,7 @@ jobs:
working-directory: ./cli
steps:
- name: Checkout
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
fetch-depth: 0
@@ -36,7 +37,7 @@ jobs:
uses: ./.github/actions/setup-web
- name: Setup Bun
uses: oven-sh/setup-bun@4bc047ad259df6fc24a6c9b0f9a0cb08cf17fbe5 # v2.0.2
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0
with:
bun-version-file: cli/.bun-version

View File

@@ -7,12 +7,22 @@ on:
description: Dify release tag to attach difyctl assets to (blank = latest stable)
required: false
type: string
dry_run:
description: Build and checksum only — skip asset upload and stale-asset prune
required: false
type: boolean
default: false
workflow_call:
inputs:
release_tag:
description: Dify release tag to attach difyctl assets to (blank = latest stable)
required: false
type: string
dry_run:
description: Build and checksum only — skip asset upload and stale-asset prune
required: false
type: boolean
default: false
release:
types: [released]
@@ -35,15 +45,12 @@ jobs:
dify_tag: ${{ steps.resolve.outputs.dify_tag }}
steps:
- name: Checkout
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- name: Export manifest to env
run: node scripts/release-naming.mjs github-env >> "$GITHUB_ENV"
- name: Validate manifest
run: scripts/release-validate-manifest.sh
run: node scripts/release-naming.mjs validate
- name: Resolve target Dify release
id: resolve
@@ -70,20 +77,6 @@ jobs:
echo "dify_tag=${tag}" >> "$GITHUB_OUTPUT"
echo "::notice::target Dify release ${tag}"
- name: Compatibility check
env:
DIFY_TAG: ${{ steps.resolve.outputs.dify_tag }}
run: node scripts/release-naming.mjs compat-check "$DIFY_TAG"
- name: Reject duplicate difyctl version
env:
GH_TOKEN: ${{ github.token }}
run: |
if gh api "repos/${GITHUB_REPOSITORY}/git/ref/tags/${difyctlTag}" >/dev/null 2>&1; then
echo "::error::difyctl ${version} already released (tag ${difyctlTag} exists); bump cli/package.json version"
exit 1
fi
release:
name: build + attach standalone binaries (all targets)
needs: validate
@@ -98,7 +91,7 @@ jobs:
DIFY_TAG: ${{ needs.validate.outputs.dify_tag }}
steps:
- name: Checkout
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
fetch-depth: 1
@@ -114,12 +107,13 @@ jobs:
run: node scripts/release-naming.mjs github-env >> "$GITHUB_ENV"
- name: Setup Bun
uses: oven-sh/setup-bun@4bc047ad259df6fc24a6c9b0f9a0cb08cf17fbe5 # v2.0.2
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0
with:
bun-version-file: cli/.bun-version
- name: Compile standalone binaries (all targets)
run: |
CLI_VERSION="$version" \
DIFYCTL_COMMIT="$(git rev-parse HEAD)" \
DIFYCTL_BUILD_DATE="$(git log -1 --format=%cI HEAD)" \
pnpm build:bin
@@ -128,6 +122,7 @@ jobs:
run: scripts/release-write-checksums.sh
- name: Attach difyctl assets to Dify release
if: ${{ !inputs.dry_run }}
env:
GH_TOKEN: ${{ github.token }}
run: |
@@ -135,6 +130,7 @@ jobs:
--repo "$GITHUB_REPOSITORY" --clobber
- name: Prune stale difyctl assets
if: ${{ !inputs.dry_run }}
env:
GH_TOKEN: ${{ github.token }}
run: |
@@ -149,18 +145,3 @@ jobs:
--repo "$GITHUB_REPOSITORY" --yes
fi
done
- name: Create provenance tag
env:
GH_TOKEN: ${{ github.token }}
run: |
ref="refs/tags/${difyctlTag}"
sha="$(git rev-parse HEAD)"
status="$(gh api -X POST "repos/${GITHUB_REPOSITORY}/git/refs" \
-f ref="$ref" -f sha="$sha" --silent --include 2>/dev/null \
| awk 'NR==1 {print $2; exit}' || true)"
case "$status" in
201) echo "::notice::created ${ref}" ;;
422) echo "::notice::tag ${ref} already exists; skipping (immutable)" ;;
*) echo "::error::provenance tag ${ref} not created (HTTP ${status:-unknown})"; exit 1 ;;
esac

View File

@@ -4,11 +4,11 @@ on:
workflow_dispatch:
inputs:
dify_version:
description: "Dify image tag to test against (e.g. 1.7.0)"
description: 'Dify image tag to test against (e.g. 1.7.0)'
type: string
required: true
cli_ref:
description: "Git ref to build the cli from (default: current branch)"
description: 'Git ref to build the cli from (default: current branch)'
type: string
required: false
@@ -24,7 +24,7 @@ jobs:
shell: bash
steps:
- name: Checkout cli ref
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
ref: ${{ inputs.cli_ref || github.ref }}
persist-credentials: false
@@ -51,7 +51,7 @@ jobs:
- name: Run smoke against live dify
working-directory: ./cli
run: pnpm exec tsx scripts/run-smoke.ts --base-url http://localhost:5001
run: DIFY_SERVER=http://localhost:5001 bun scripts/run-smoke.ts
- name: Dump dify logs on failure
if: failure()

View File

@@ -30,7 +30,7 @@ jobs:
steps:
- name: Checkout code
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
@@ -44,14 +44,14 @@ jobs:
- name: Validate release manifest
if: matrix.os == 'depot-ubuntu-24.04'
run: scripts/release-validate-manifest.sh
run: node scripts/release-naming.mjs validate
- name: CI pipeline (typecheck, lint, coverage, build)
- name: CI pipeline (tree, coverage, build)
run: pnpm run ci
- name: Report coverage
if: ${{ env.CODECOV_TOKEN != '' && matrix.os == 'depot-ubuntu-24.04' }}
uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0
uses: codecov/codecov-action@303a32d7a59b442fa8d48b6a1cc6825c09c847a5 # v7.1.1
with:
directory: cli/coverage
flags: cli

View File

@@ -13,16 +13,16 @@ jobs:
steps:
- name: Checkout code
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0
persist-credentials: false
- name: Setup UV and Python
uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0
with:
enable-cache: true
python-version: "3.12"
python-version: '3.12'
cache-dependency-glob: api/uv.lock
- name: Install dependencies
@@ -40,7 +40,7 @@ jobs:
cp envs/middleware.env.example middleware.env
- name: Set up Middlewares
uses: hoverkraft-tech/compose-action@11beaa1c2dae4e8ed7b1665aa074723b6cecb0e4 # v3.0.0
uses: hoverkraft-tech/compose-action@b659c744ee9bed25aea2307c017ad849bd104433 # v3.2.0
with:
compose-file: |
docker/docker-compose.middleware.yaml
@@ -63,16 +63,16 @@ jobs:
steps:
- name: Checkout code
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0
persist-credentials: false
- name: Setup UV and Python
uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0
with:
enable-cache: true
python-version: "3.12"
python-version: '3.12'
cache-dependency-glob: api/uv.lock
- name: Install dependencies
@@ -94,7 +94,7 @@ jobs:
sed -i 's/DB_USERNAME=postgres/DB_USERNAME=mysql/' middleware.env
- name: Set up Middlewares
uses: hoverkraft-tech/compose-action@11beaa1c2dae4e8ed7b1665aa074723b6cecb0e4 # v3.0.0
uses: hoverkraft-tech/compose-action@b659c744ee9bed25aea2307c017ad849bd104433 # v3.2.0
with:
compose-file: |
docker/docker-compose.middleware.yaml

View File

@@ -5,9 +5,9 @@ permissions:
on:
workflow_run:
workflows: ["Build and Push API & Web"]
workflows: ['Build and Push API & Web']
branches:
- "deploy/agent"
- 'deploy/agent'
types:
- completed

View File

@@ -2,9 +2,9 @@ name: Deploy Dev
on:
workflow_run:
workflows: ["Build and Push API & Web"]
workflows: ['Build and Push API & Web']
branches:
- "deploy/dev"
- 'deploy/dev'
types:
- completed

View File

@@ -5,9 +5,9 @@ permissions:
on:
workflow_run:
workflows: ["Build and Push API & Web"]
workflows: ['Build and Push API & Web']
branches:
- "deploy/enterprise"
- 'deploy/enterprise'
types:
- completed

View File

@@ -0,0 +1,25 @@
name: Deploy HITL IM Dev
on:
workflow_run:
workflows: ['Build and Push API & Web']
branches:
- 'build/feat/hitl-im-dev'
types:
- completed
jobs:
deploy:
runs-on: depot-ubuntu-24.04
if: |
github.event.workflow_run.conclusion == 'success' &&
github.event.workflow_run.head_branch == 'build/feat/hitl-im-dev'
steps:
- name: Deploy to server
uses: appleboy/ssh-action@0ff4204d59e8e51228ff73bce53f80d53301dee2 # v1.2.5
with:
host: ${{ secrets.HITL_SSH_HOST }}
username: ${{ secrets.SSH_USER }}
key: ${{ secrets.SSH_PRIVATE_KEY }}
script: |
${{ vars.SSH_SCRIPT || secrets.SSH_SCRIPT }}

73
.github/workflows/deploy-knowledge.yml vendored Normal file
View File

@@ -0,0 +1,73 @@
name: Deploy Knowledge
permissions:
actions: read
contents: read
on:
workflow_run:
workflows: ['Build and Push API & Web']
branches:
- 'deploy/konwledge'
types:
- completed
jobs:
deploy:
runs-on: depot-ubuntu-24.04
if: |
github.event.workflow_run.conclusion == 'success' &&
github.event.workflow_run.head_branch == 'deploy/konwledge'
steps:
- name: Wait for KnowledgeFS CI
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
timeout-minutes: 35
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const workflowId = "knowledge-fs-ci.yml";
const headBranch = context.payload.workflow_run.head_branch;
const headSha = context.payload.workflow_run.head_sha;
const deadline = Date.now() + 30 * 60 * 1000;
const pollIntervalMs = 15 * 1000;
while (Date.now() < deadline) {
const { data } = await github.rest.actions.listWorkflowRuns({
owner: context.repo.owner,
repo: context.repo.repo,
workflow_id: workflowId,
branch: headBranch,
event: "push",
head_sha: headSha,
per_page: 10,
});
const run = data.workflow_runs[0];
if (!run) {
core.info(`Waiting for ${workflowId} to start for ${headSha}.`);
} else if (run.status !== "completed") {
core.info(`Waiting for ${run.html_url}; current status is ${run.status}.`);
} else if (run.conclusion !== "success") {
throw new Error(
`${workflowId} did not succeed for ${headSha}: ${run.conclusion} (${run.html_url})`,
);
} else {
core.info(`KnowledgeFS CI succeeded for ${headSha}: ${run.html_url}`);
return;
}
await new Promise((resolve) => setTimeout(resolve, pollIntervalMs));
}
throw new Error(`Timed out waiting for ${workflowId} to succeed for ${headSha}.`);
- name: Deploy to server
uses: appleboy/ssh-action@0ff4204d59e8e51228ff73bce53f80d53301dee2 # v1.2.5
with:
host: ${{ secrets.SSH_NEW_RAG_HOST }}
username: ${{ secrets.SSH_USER }}
key: ${{ secrets.SSH_PRIVATE_KEY }}
# Allow the shared deployment lock and Celery warm shutdown to finish.
command_timeout: 300m
script: |
${{ vars.SSH_SCRIPT || secrets.SSH_SCRIPT }}

View File

@@ -5,9 +5,9 @@ permissions:
on:
workflow_run:
workflows: ["Build and Push API & Web"]
workflows: ['Build and Push API & Web']
branches:
- "deploy/saas"
- 'deploy/saas'
types:
- completed

47
.github/workflows/dify-agent-tests.yml vendored Normal file
View File

@@ -0,0 +1,47 @@
name: Dify Agent Tests
on:
workflow_call:
permissions:
contents: read
concurrency:
group: dify-agent-tests-${{ github.head_ref || github.run_id }}
cancel-in-progress: true
jobs:
dify-agent-unit:
name: Dify Agent Unit Tests
runs-on: depot-ubuntu-24.04
defaults:
run:
shell: bash
working-directory: dify-agent
strategy:
matrix:
python-version:
- '3.12'
steps:
- name: Checkout code
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0
persist-credentials: false
- name: Setup UV and Python
uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0
with:
enable-cache: true
python-version: ${{ matrix.python-version }}
cache-dependency-glob: dify-agent/uv.lock
- name: Check UV lockfile
run: uv lock --check
- name: Install dependencies
run: uv sync --extra server --dev
- name: Run unit tests
run: uv run pytest

View File

@@ -3,7 +3,7 @@ name: Build docker image
on:
pull_request:
branches:
- "main"
- 'main'
paths:
- api/Dockerfile
- api/Dockerfile.dockerignore
@@ -13,6 +13,11 @@ on:
- dify-agent/README.md
- dify-agent/src/**
- web/Dockerfile
- dify-agent-runtime/docker/Dockerfile
- dify-agent-runtime/go.mod
- dify-agent-runtime/go.sum
- dify-agent-runtime/cmd/**
- dify-agent-runtime/internal/**
concurrency:
group: docker-build-${{ github.head_ref || github.run_id }}
@@ -28,29 +33,39 @@ jobs:
strategy:
matrix:
include:
- service_name: "api-amd64"
- service_name: 'api-amd64'
platform: linux/amd64
runs_on: depot-ubuntu-24.04-4
context: "{{defaultContext}}"
file: "api/Dockerfile"
- service_name: "api-arm64"
context: '{{defaultContext}}'
file: 'api/Dockerfile'
- service_name: 'api-arm64'
platform: linux/arm64
runs_on: depot-ubuntu-24.04-4
context: "{{defaultContext}}"
file: "api/Dockerfile"
- service_name: "web-amd64"
context: '{{defaultContext}}'
file: 'api/Dockerfile'
- service_name: 'web-amd64'
platform: linux/amd64
runs_on: depot-ubuntu-24.04-4
context: "{{defaultContext}}"
file: "web/Dockerfile"
- service_name: "web-arm64"
context: '{{defaultContext}}'
file: 'web/Dockerfile'
- service_name: 'web-arm64'
platform: linux/arm64
runs_on: depot-ubuntu-24.04-4
context: "{{defaultContext}}"
file: "web/Dockerfile"
context: '{{defaultContext}}'
file: 'web/Dockerfile'
- service_name: 'local-sandbox-amd64'
platform: linux/amd64
runs_on: depot-ubuntu-24.04-4
context: '{{defaultContext}}:dify-agent-runtime'
file: 'docker/Dockerfile'
- service_name: 'local-sandbox-arm64'
platform: linux/arm64
runs_on: depot-ubuntu-24.04-4
context: '{{defaultContext}}:dify-agent-runtime'
file: 'docker/Dockerfile'
steps:
- name: Set up Depot CLI
uses: depot/setup-action@15c09a5f77a0840ad4bce955686522a257853461 # v1.7.1
uses: depot/setup-action@91bc8495a33ebfc504ffc89e5674379ccf23c29c # v1.7.2
- name: Build Docker Image
uses: depot/build-push-action@98e78adca7817480b8185f474a400b451d74e287 # v1.18.0
@@ -59,6 +74,7 @@ jobs:
push: false
context: ${{ matrix.context }}
file: ${{ matrix.file }}
build-contexts: ${{ matrix.build_contexts }}
platforms: ${{ matrix.platform }}
build-docker-fork:
@@ -69,20 +85,24 @@ jobs:
strategy:
matrix:
include:
- service_name: "api-amd64"
context: "{{defaultContext}}"
file: "api/Dockerfile"
- service_name: "web-amd64"
context: "{{defaultContext}}"
file: "web/Dockerfile"
- service_name: 'api-amd64'
context: '{{defaultContext}}'
file: 'api/Dockerfile'
- service_name: 'web-amd64'
context: '{{defaultContext}}'
file: 'web/Dockerfile'
- service_name: 'local-sandbox-amd64'
context: '{{defaultContext}}:dify-agent-runtime'
file: 'docker/Dockerfile'
steps:
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5 # v4.1.0
uses: docker/setup-buildx-action@f87e5991a6d7451dcb8d9637bfbc97413f497069 # v4.4.1
- name: Build Docker Image
uses: docker/build-push-action@f9f3042f7e2789586610d6e8b85c8f03e5195baf # v7.2.0
uses: docker/build-push-action@c3c9e263c25d99ce0380d002d59b67737d91b0dc # v7.4.0
with:
push: false
context: ${{ matrix.context }}
file: ${{ matrix.file }}
build-contexts: ${{ matrix.build_contexts }}
platforms: linux/amd64

View File

@@ -24,7 +24,7 @@ jobs:
name: Require cherry-pick provenance
runs-on: depot-ubuntu-24.04
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0

39
.github/workflows/image-resources.yml vendored Normal file
View File

@@ -0,0 +1,39 @@
name: Image optimization
on:
pull_request:
permissions:
contents: read
jobs:
image-resources:
name: Image optimization
runs-on: depot-ubuntu-24.04
steps:
- name: Checkout code
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
ref: ${{ github.event.pull_request.head.sha }}
persist-credentials: false
fetch-depth: 0
- name: Set up workspace toolchain
uses: ./.github/actions/setup-web
with:
run-install: 'false'
- name: Install image checker dependencies
run: pnpm --filter @dify/image-resources... install --frozen-lockfile --ignore-scripts
- name: Type-check image checker
run: pnpm --filter @dify/image-resources type-check
- name: Test image checker
run: pnpm --filter @dify/image-resources test
- name: Check image optimization
env:
BASE_SHA: ${{ github.event.pull_request.base.sha }}
run: |
pnpm --filter @dify/image-resources check:images --base "$BASE_SHA"

View File

@@ -1,4 +1,4 @@
name: "Pull Request Labeler"
name: 'Pull Request Labeler'
on:
pull_request_target:
@@ -9,6 +9,6 @@ jobs:
pull-requests: write
runs-on: depot-ubuntu-24.04
steps:
- uses: actions/labeler@f27b608878404679385c85cfa523b85ccb86e213 # v6.1.0
- uses: actions/labeler@bf12e9b00b37c5c0ca2b87b79b2daf7891dbda13 # v7.0.0
with:
sync-labels: true

View File

@@ -2,12 +2,10 @@ name: Main CI Pipeline
on:
pull_request:
branches: ["main"]
branches: ['main']
merge_group:
branches: ["main"]
branches: ['main']
types: [checks_requested]
push:
branches: ["main"]
permissions:
actions: write
@@ -17,19 +15,22 @@ permissions:
statuses: write
concurrency:
group: main-ci-${{ github.head_ref || github.run_id }}
cancel-in-progress: true
# Pull request deduplication is owned by skip-duplicate-actions so pre_job can
# publish should_skip before required status finalizers run.
group: main-ci-${{ github.event.merge_group.head_sha || github.run_id }}
cancel-in-progress: ${{ github.event_name == 'merge_group' }}
jobs:
# Keep orchestration independent of the Depot pool used for test execution.
pre_job:
name: Skip Duplicate Checks
runs-on: depot-ubuntu-24.04
runs-on: ubuntu-24.04
outputs:
should_skip: ${{ steps.skip_check.outputs.should_skip || 'false' }}
steps:
- id: skip_check
continue-on-error: true
uses: fkirc/skip-duplicate-actions@f75f66ce1886f00957d99748a42c724f4330bdcf # v5.3.1
uses: fkirc/skip-duplicate-actions@b974a9395958c231af965b70070979a577efa578 # v5.3.2
with:
cancel_others: 'true'
concurrent_skipping: same_content_newer
@@ -37,9 +38,7 @@ jobs:
# Check which paths were changed to determine which tests to run
check-changes:
name: Check Changed Files
needs: pre_job
if: needs.pre_job.outputs.should_skip != 'true'
runs-on: depot-ubuntu-24.04
runs-on: ubuntu-24.04
outputs:
api-changed: ${{ steps.changes.outputs.api }}
cli-changed: ${{ steps.changes.outputs.cli }}
@@ -47,14 +46,32 @@ jobs:
web-changed: ${{ steps.changes.outputs.web }}
vdb-changed: ${{ steps.changes.outputs.vdb }}
migration-changed: ${{ steps.changes.outputs.migration }}
sandbox-runtime-changed: ${{ steps.changes.outputs.sandbox-runtime }}
dify-agent-changed: ${{ steps.changes.outputs.dify-agent }}
python-style-changed: ${{ steps.changes.outputs.python-style }}
dify-agent-style-changed: ${{ steps.changes.outputs.dify-agent-style }}
web-style-changed: ${{ steps.changes.outputs.web-style }}
ts-common-style-changed: ${{ steps.changes.outputs.ts-common-style }}
superlinter-changed: ${{ steps.changes.outputs.superlinter }}
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
- uses: dorny/paths-filter@fbd0ab8f3e69293af611ebaee6363fc25e6d187d # v4.0.1
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: dorny/paths-filter@ceb8a2b8f2d89434be7ff52d3de7ec3738c5cc9d # v4.0.3
id: changes
with:
filters: |
api:
- 'api/**'
- 'scripts/ast_grep_guard.py'
- 'scripts/check_no_new_getattr.py'
- 'scripts/check_no_spec_mock.py'
- 'scripts/check_no_new_controller_sqlalchemy.py'
- 'scripts/lint_controller_sqlalchemy.py'
- 'scripts/ast_grep_rules/no_new_getattr.yml'
- 'scripts/ast_grep_rules/no_spec_mock.yml'
- 'scripts/ast_grep_rules/no_new_controller_sqlalchemy.yml'
- 'scripts/ast_grep_rules/no_new_session_mock.yml'
- '.github/workflows/style.yml'
- '.github/workflows/main-ci.yml'
- '.github/workflows/api-tests.yml'
- 'docker/.env.example'
- 'docker/envs/middleware.env.example'
@@ -65,15 +82,15 @@ jobs:
- 'docker/volumes/sandbox/conf/**'
cli:
- 'cli/**'
- 'skills/**'
- 'packages/contracts/**'
- 'packages/tsconfig/**'
- 'package.json'
- 'pnpm-lock.yaml'
- 'pnpm-workspace.yaml'
- 'eslint.config.mjs'
- 'lint.config.ts'
- '.npmrc'
- '.nvmrc'
- '.github/workflows/cli-tests.yml'
- '.github/workflows/cli-docker-build.yml'
- '.github/actions/setup-web/**'
web:
- 'web/**'
@@ -81,24 +98,26 @@ jobs:
- 'package.json'
- 'pnpm-lock.yaml'
- 'pnpm-workspace.yaml'
- '.nvmrc'
- '.github/workflows/main-ci.yml'
- '.github/workflows/web-tests.yml'
- '.github/actions/setup-web/**'
e2e:
- 'api/**'
- 'api/pyproject.toml'
- 'api/uv.lock'
- 'e2e/**'
- 'web/**'
- 'packages/**'
- 'package.json'
- 'pnpm-lock.yaml'
- 'pnpm-workspace.yaml'
- '.nvmrc'
- 'docker/docker-compose.middleware.yaml'
- 'docker/envs/middleware.env.example'
- 'docker/ssrf_proxy/**'
- 'docker/volumes/sandbox/conf/**'
- '.github/workflows/web-e2e.yml'
- '.github/workflows/main-ci.yml'
- '.github/actions/setup-web/**'
- '.github/actions/setup-core-e2e/**'
- '.github/actions/wait-e2e-web-build/**'
vdb:
- 'api/core/rag/datasource/**'
- 'api/tests/integration_tests/vdb/**'
@@ -124,6 +143,12 @@ jobs:
- 'docker/volumes/**'
- 'api/uv.lock'
- 'api/pyproject.toml'
sandbox-runtime:
- 'dify-agent-runtime/**'
- '.github/workflows/sandbox-runtime-tests.yml'
dify-agent:
- 'dify-agent/**'
- '.github/workflows/dify-agent-tests.yml'
migration:
- 'api/migrations/**'
- 'api/.env.example'
@@ -135,8 +160,70 @@ jobs:
- 'docker/generate_docker_compose'
- 'docker/ssrf_proxy/**'
- 'docker/volumes/sandbox/conf/**'
python-style:
- 'api/**'
- 'scripts/ast_grep_guard.py'
- 'scripts/check_no_new_getattr.py'
- 'scripts/check_no_spec_mock.py'
- 'scripts/check_no_new_controller_sqlalchemy.py'
- 'scripts/check_no_new_session_mock.py'
- 'scripts/lint_controller_sqlalchemy.py'
- 'scripts/ast_grep_rules/no_new_getattr.yml'
- 'scripts/ast_grep_rules/no_spec_mock.yml'
- 'scripts/ast_grep_rules/no_new_controller_sqlalchemy.yml'
- 'scripts/ast_grep_rules/no_new_session_mock.yml'
- '.github/workflows/style.yml'
- '.github/workflows/main-ci.yml'
dify-agent-style:
- 'dify-agent/**'
- '.github/workflows/style.yml'
- '.github/workflows/main-ci.yml'
web-style:
- 'web/**'
- 'e2e/**'
- 'sdks/nodejs-client/**'
- 'packages/**'
- 'package.json'
- 'pnpm-lock.yaml'
- 'pnpm-workspace.yaml'
- 'knip.config.ts'
- 'scripts/check-web-production-unused-after-knip-fix.mjs'
- '.npmrc'
- '.github/workflows/main-ci.yml'
- '.github/workflows/web-bundle-size.yml'
- '.github/workflows/style.yml'
- '.github/actions/setup-web/**'
ts-common-style:
- 'web/**'
- 'cli/**'
- 'skills/**'
- 'e2e/**'
- 'sdks/nodejs-client/**'
- 'packages/**'
- 'package.json'
- 'pnpm-lock.yaml'
- 'pnpm-workspace.yaml'
- 'tsconfig.json'
- 'vite.config.ts'
- 'lint.config.ts'
- 'eslint.config.mjs'
- 'knip.config.ts'
- 'scripts/check-web-production-unused-after-knip-fix.mjs'
- 'oxlint-suppressions.json'
- 'eslint-suppressions.json'
- '.vscode/**'
- '.github/**'
superlinter:
- '**.sh'
- '**.yaml'
- '**.yml'
- '**Dockerfile'
- 'dev/**'
- '.editorconfig'
- '.vite-hooks/**'
# Run tests in parallel while always emitting stable required checks.
# Finalizers report unchanged paths directly, avoiding separate skip-only jobs.
# Keep each required check name stable and fail closed if classification fails.
api-tests-run:
name: Run API Tests
needs:
@@ -146,17 +233,6 @@ jobs:
uses: ./.github/workflows/api-tests.yml
secrets: inherit
api-tests-skip:
name: Skip API Tests
needs:
- pre_job
- check-changes
if: needs.pre_job.outputs.should_skip != 'true' && needs.check-changes.outputs.api-changed != 'true'
runs-on: depot-ubuntu-24.04
steps:
- name: Report skipped API tests
run: echo "No API-related changes detected; skipping API tests."
api-tests:
name: API Tests
if: ${{ always() }}
@@ -164,21 +240,26 @@ jobs:
- pre_job
- check-changes
- api-tests-run
- api-tests-skip
runs-on: depot-ubuntu-24.04
runs-on: ubuntu-24.04
steps:
- name: Finalize API Tests status
env:
SHOULD_SKIP_WORKFLOW: ${{ needs.pre_job.outputs.should_skip }}
TESTS_CHANGED: ${{ needs.check-changes.outputs.api-changed }}
RUN_RESULT: ${{ needs.api-tests-run.result }}
SKIP_RESULT: ${{ needs.api-tests-skip.result }}
PRE_JOB_RESULT: ${{ needs.pre_job.result }}
CHANGES_RESULT: ${{ needs.check-changes.result }}
run: |
if [[ "$SHOULD_SKIP_WORKFLOW" == 'true' ]]; then
echo "API tests were skipped because this workflow run duplicated a successful or newer run."
exit 0
fi
if [[ "$PRE_JOB_RESULT" != 'success' || "$CHANGES_RESULT" != 'success' ]]; then
echo "Cannot finalize tests: duplicate check=$PRE_JOB_RESULT, change detection=$CHANGES_RESULT" >&2
exit 1
fi
if [[ "$TESTS_CHANGED" == 'true' ]]; then
if [[ "$RUN_RESULT" == 'success' ]]; then
echo "API tests ran successfully."
@@ -189,12 +270,12 @@ jobs:
exit 1
fi
if [[ "$SKIP_RESULT" == 'success' ]]; then
if [[ "$TESTS_CHANGED" == 'false' && "$RUN_RESULT" == 'skipped' ]]; then
echo "API tests were skipped because no API-related files changed."
exit 0
fi
echo "API tests were not required, but the skip job finished with result: $SKIP_RESULT" >&2
echo "Unexpected test state: changed=$TESTS_CHANGED, result=$RUN_RESULT" >&2
exit 1
cli-tests-run:
@@ -206,17 +287,6 @@ jobs:
uses: ./.github/workflows/cli-tests.yml
secrets: inherit
cli-tests-skip:
name: Skip CLI Tests
needs:
- pre_job
- check-changes
if: needs.pre_job.outputs.should_skip != 'true' && needs.check-changes.outputs.cli-changed != 'true'
runs-on: depot-ubuntu-24.04
steps:
- name: Report skipped CLI tests
run: echo "No CLI-related changes detected; skipping CLI tests."
cli-tests:
name: CLI Tests
if: ${{ always() }}
@@ -224,21 +294,26 @@ jobs:
- pre_job
- check-changes
- cli-tests-run
- cli-tests-skip
runs-on: depot-ubuntu-24.04
runs-on: ubuntu-24.04
steps:
- name: Finalize CLI Tests status
env:
SHOULD_SKIP_WORKFLOW: ${{ needs.pre_job.outputs.should_skip }}
TESTS_CHANGED: ${{ needs.check-changes.outputs.cli-changed }}
RUN_RESULT: ${{ needs.cli-tests-run.result }}
SKIP_RESULT: ${{ needs.cli-tests-skip.result }}
PRE_JOB_RESULT: ${{ needs.pre_job.result }}
CHANGES_RESULT: ${{ needs.check-changes.result }}
run: |
if [[ "$SHOULD_SKIP_WORKFLOW" == 'true' ]]; then
echo "CLI tests were skipped because this workflow run duplicated a successful or newer run."
exit 0
fi
if [[ "$PRE_JOB_RESULT" != 'success' || "$CHANGES_RESULT" != 'success' ]]; then
echo "Cannot finalize tests: duplicate check=$PRE_JOB_RESULT, change detection=$CHANGES_RESULT" >&2
exit 1
fi
if [[ "$TESTS_CHANGED" == 'true' ]]; then
if [[ "$RUN_RESULT" == 'success' ]]; then
echo "CLI tests ran successfully."
@@ -249,12 +324,12 @@ jobs:
exit 1
fi
if [[ "$SKIP_RESULT" == 'success' ]]; then
if [[ "$TESTS_CHANGED" == 'false' && "$RUN_RESULT" == 'skipped' ]]; then
echo "CLI tests were skipped because no CLI-related files changed."
exit 0
fi
echo "CLI tests were not required, but the skip job finished with result: $SKIP_RESULT" >&2
echo "Unexpected test state: changed=$TESTS_CHANGED, result=$RUN_RESULT" >&2
exit 1
web-tests-run:
@@ -266,17 +341,6 @@ jobs:
uses: ./.github/workflows/web-tests.yml
secrets: inherit
web-tests-skip:
name: Skip Web Tests
needs:
- pre_job
- check-changes
if: needs.pre_job.outputs.should_skip != 'true' && needs.check-changes.outputs.web-changed != 'true'
runs-on: depot-ubuntu-24.04
steps:
- name: Report skipped web tests
run: echo "No web-related changes detected; skipping web tests."
web-tests:
name: Web Tests
if: ${{ always() }}
@@ -284,21 +348,26 @@ jobs:
- pre_job
- check-changes
- web-tests-run
- web-tests-skip
runs-on: depot-ubuntu-24.04
runs-on: ubuntu-24.04
steps:
- name: Finalize Web Tests status
env:
SHOULD_SKIP_WORKFLOW: ${{ needs.pre_job.outputs.should_skip }}
TESTS_CHANGED: ${{ needs.check-changes.outputs.web-changed }}
RUN_RESULT: ${{ needs.web-tests-run.result }}
SKIP_RESULT: ${{ needs.web-tests-skip.result }}
PRE_JOB_RESULT: ${{ needs.pre_job.result }}
CHANGES_RESULT: ${{ needs.check-changes.result }}
run: |
if [[ "$SHOULD_SKIP_WORKFLOW" == 'true' ]]; then
echo "Web tests were skipped because this workflow run duplicated a successful or newer run."
exit 0
fi
if [[ "$PRE_JOB_RESULT" != 'success' || "$CHANGES_RESULT" != 'success' ]]; then
echo "Cannot finalize tests: duplicate check=$PRE_JOB_RESULT, change detection=$CHANGES_RESULT" >&2
exit 1
fi
if [[ "$TESTS_CHANGED" == 'true' ]]; then
if [[ "$RUN_RESULT" == 'success' ]]; then
echo "Web tests ran successfully."
@@ -309,12 +378,12 @@ jobs:
exit 1
fi
if [[ "$SKIP_RESULT" == 'success' ]]; then
if [[ "$TESTS_CHANGED" == 'false' && "$RUN_RESULT" == 'skipped' ]]; then
echo "Web tests were skipped because no web-related files changed."
exit 0
fi
echo "Web tests were not required, but the skip job finished with result: $SKIP_RESULT" >&2
echo "Unexpected test state: changed=$TESTS_CHANGED, result=$RUN_RESULT" >&2
exit 1
web-e2e-run:
@@ -324,17 +393,9 @@ jobs:
- check-changes
if: needs.pre_job.outputs.should_skip != 'true' && needs.check-changes.outputs.e2e-changed == 'true'
uses: ./.github/workflows/web-e2e.yml
web-e2e-skip:
name: Skip Web Full-Stack E2E
needs:
- pre_job
- check-changes
if: needs.pre_job.outputs.should_skip != 'true' && needs.check-changes.outputs.e2e-changed != 'true'
runs-on: depot-ubuntu-24.04
steps:
- name: Report skipped web full-stack e2e
run: echo "No E2E-related changes detected; skipping web full-stack E2E."
with:
run-external-runtime: false
secrets: inherit
web-e2e:
name: Web Full-Stack E2E
@@ -343,21 +404,26 @@ jobs:
- pre_job
- check-changes
- web-e2e-run
- web-e2e-skip
runs-on: depot-ubuntu-24.04
runs-on: ubuntu-24.04
steps:
- name: Finalize Web Full-Stack E2E status
env:
SHOULD_SKIP_WORKFLOW: ${{ needs.pre_job.outputs.should_skip }}
TESTS_CHANGED: ${{ needs.check-changes.outputs.e2e-changed }}
RUN_RESULT: ${{ needs.web-e2e-run.result }}
SKIP_RESULT: ${{ needs.web-e2e-skip.result }}
PRE_JOB_RESULT: ${{ needs.pre_job.result }}
CHANGES_RESULT: ${{ needs.check-changes.result }}
run: |
if [[ "$SHOULD_SKIP_WORKFLOW" == 'true' ]]; then
echo "Web full-stack E2E was skipped because this workflow run duplicated a successful or newer run."
exit 0
fi
if [[ "$PRE_JOB_RESULT" != 'success' || "$CHANGES_RESULT" != 'success' ]]; then
echo "Cannot finalize tests: duplicate check=$PRE_JOB_RESULT, change detection=$CHANGES_RESULT" >&2
exit 1
fi
if [[ "$TESTS_CHANGED" == 'true' ]]; then
if [[ "$RUN_RESULT" == 'success' ]]; then
echo "Web full-stack E2E ran successfully."
@@ -368,19 +434,30 @@ jobs:
exit 1
fi
if [[ "$SKIP_RESULT" == 'success' ]]; then
if [[ "$TESTS_CHANGED" == 'false' && "$RUN_RESULT" == 'skipped' ]]; then
echo "Web full-stack E2E was skipped because no E2E-related files changed."
exit 0
fi
echo "Web full-stack E2E was not required, but the skip job finished with result: $SKIP_RESULT" >&2
echo "Unexpected test state: changed=$TESTS_CHANGED, result=$RUN_RESULT" >&2
exit 1
style-check:
name: Style Check
needs: pre_job
if: needs.pre_job.outputs.should_skip != 'true'
if: ${{ always() }}
needs:
- pre_job
- check-changes
uses: ./.github/workflows/style.yml
with:
base-rev: ${{ github.event.pull_request.base.sha || github.event.merge_group.base_sha }}
classification-succeeded: ${{ needs.check-changes.result == 'success' }}
run-python-style: ${{ needs.check-changes.outputs.python-style-changed == 'true' }}
run-dify-agent-style: ${{ needs.check-changes.outputs.dify-agent-style-changed == 'true' }}
run-web-style: ${{ needs.check-changes.outputs.web-style-changed == 'true' }}
run-ts-common-style: ${{ needs.check-changes.outputs.ts-common-style-changed == 'true' }}
run-superlinter: ${{ needs.check-changes.outputs.superlinter-changed == 'true' }}
skip-checks: ${{ needs.pre_job.outputs.should_skip == 'true' }}
vdb-tests-run:
name: Run VDB Tests
@@ -390,17 +467,6 @@ jobs:
if: needs.pre_job.outputs.should_skip != 'true' && needs.check-changes.outputs.vdb-changed == 'true'
uses: ./.github/workflows/vdb-tests.yml
vdb-tests-skip:
name: Skip VDB Tests
needs:
- pre_job
- check-changes
if: needs.pre_job.outputs.should_skip != 'true' && needs.check-changes.outputs.vdb-changed != 'true'
runs-on: depot-ubuntu-24.04
steps:
- name: Report skipped VDB tests
run: echo "No VDB-related changes detected; skipping VDB tests."
vdb-tests:
name: VDB Tests
if: ${{ always() }}
@@ -408,21 +474,26 @@ jobs:
- pre_job
- check-changes
- vdb-tests-run
- vdb-tests-skip
runs-on: depot-ubuntu-24.04
runs-on: ubuntu-24.04
steps:
- name: Finalize VDB Tests status
env:
SHOULD_SKIP_WORKFLOW: ${{ needs.pre_job.outputs.should_skip }}
TESTS_CHANGED: ${{ needs.check-changes.outputs.vdb-changed }}
RUN_RESULT: ${{ needs.vdb-tests-run.result }}
SKIP_RESULT: ${{ needs.vdb-tests-skip.result }}
PRE_JOB_RESULT: ${{ needs.pre_job.result }}
CHANGES_RESULT: ${{ needs.check-changes.result }}
run: |
if [[ "$SHOULD_SKIP_WORKFLOW" == 'true' ]]; then
echo "VDB tests were skipped because this workflow run duplicated a successful or newer run."
exit 0
fi
if [[ "$PRE_JOB_RESULT" != 'success' || "$CHANGES_RESULT" != 'success' ]]; then
echo "Cannot finalize tests: duplicate check=$PRE_JOB_RESULT, change detection=$CHANGES_RESULT" >&2
exit 1
fi
if [[ "$TESTS_CHANGED" == 'true' ]]; then
if [[ "$RUN_RESULT" == 'success' ]]; then
echo "VDB tests ran successfully."
@@ -433,12 +504,12 @@ jobs:
exit 1
fi
if [[ "$SKIP_RESULT" == 'success' ]]; then
if [[ "$TESTS_CHANGED" == 'false' && "$RUN_RESULT" == 'skipped' ]]; then
echo "VDB tests were skipped because no VDB-related files changed."
exit 0
fi
echo "VDB tests were not required, but the skip job finished with result: $SKIP_RESULT" >&2
echo "Unexpected test state: changed=$TESTS_CHANGED, result=$RUN_RESULT" >&2
exit 1
db-migration-test-run:
@@ -449,17 +520,6 @@ jobs:
if: needs.pre_job.outputs.should_skip != 'true' && needs.check-changes.outputs.migration-changed == 'true'
uses: ./.github/workflows/db-migration-test.yml
db-migration-test-skip:
name: Skip DB Migration Test
needs:
- pre_job
- check-changes
if: needs.pre_job.outputs.should_skip != 'true' && needs.check-changes.outputs.migration-changed != 'true'
runs-on: depot-ubuntu-24.04
steps:
- name: Report skipped DB migration tests
run: echo "No migration-related changes detected; skipping DB migration tests."
db-migration-test:
name: DB Migration Test
if: ${{ always() }}
@@ -467,21 +527,26 @@ jobs:
- pre_job
- check-changes
- db-migration-test-run
- db-migration-test-skip
runs-on: depot-ubuntu-24.04
runs-on: ubuntu-24.04
steps:
- name: Finalize DB Migration Test status
env:
SHOULD_SKIP_WORKFLOW: ${{ needs.pre_job.outputs.should_skip }}
TESTS_CHANGED: ${{ needs.check-changes.outputs.migration-changed }}
RUN_RESULT: ${{ needs.db-migration-test-run.result }}
SKIP_RESULT: ${{ needs.db-migration-test-skip.result }}
PRE_JOB_RESULT: ${{ needs.pre_job.result }}
CHANGES_RESULT: ${{ needs.check-changes.result }}
run: |
if [[ "$SHOULD_SKIP_WORKFLOW" == 'true' ]]; then
echo "DB migration tests were skipped because this workflow run duplicated a successful or newer run."
exit 0
fi
if [[ "$PRE_JOB_RESULT" != 'success' || "$CHANGES_RESULT" != 'success' ]]; then
echo "Cannot finalize tests: duplicate check=$PRE_JOB_RESULT, change detection=$CHANGES_RESULT" >&2
exit 1
fi
if [[ "$TESTS_CHANGED" == 'true' ]]; then
if [[ "$RUN_RESULT" == 'success' ]]; then
echo "DB migration tests ran successfully."
@@ -492,10 +557,118 @@ jobs:
exit 1
fi
if [[ "$SKIP_RESULT" == 'success' ]]; then
if [[ "$TESTS_CHANGED" == 'false' && "$RUN_RESULT" == 'skipped' ]]; then
echo "DB migration tests were skipped because no migration-related files changed."
exit 0
fi
echo "DB migration tests were not required, but the skip job finished with result: $SKIP_RESULT" >&2
echo "Unexpected test state: changed=$TESTS_CHANGED, result=$RUN_RESULT" >&2
exit 1
sandbox-runtime-tests-run:
name: Run Sandbox Runtime Tests
needs:
- pre_job
- check-changes
if: needs.pre_job.outputs.should_skip != 'true' && needs.check-changes.outputs.sandbox-runtime-changed == 'true'
uses: ./.github/workflows/sandbox-runtime-tests.yml
secrets: inherit
sandbox-runtime-tests:
name: Sandbox Runtime Tests
if: ${{ always() }}
needs:
- pre_job
- check-changes
- sandbox-runtime-tests-run
runs-on: ubuntu-24.04
steps:
- name: Finalize Sandbox Runtime Tests status
env:
SHOULD_SKIP_WORKFLOW: ${{ needs.pre_job.outputs.should_skip }}
TESTS_CHANGED: ${{ needs.check-changes.outputs.sandbox-runtime-changed }}
RUN_RESULT: ${{ needs.sandbox-runtime-tests-run.result }}
PRE_JOB_RESULT: ${{ needs.pre_job.result }}
CHANGES_RESULT: ${{ needs.check-changes.result }}
run: |
if [[ "$SHOULD_SKIP_WORKFLOW" == 'true' ]]; then
echo "Sandbox runtime tests were skipped because this workflow run duplicated a successful or newer run."
exit 0
fi
if [[ "$PRE_JOB_RESULT" != 'success' || "$CHANGES_RESULT" != 'success' ]]; then
echo "Cannot finalize tests: duplicate check=$PRE_JOB_RESULT, change detection=$CHANGES_RESULT" >&2
exit 1
fi
if [[ "$TESTS_CHANGED" == 'true' ]]; then
if [[ "$RUN_RESULT" == 'success' ]]; then
echo "Sandbox runtime tests ran successfully."
exit 0
fi
echo "Sandbox runtime tests were required but finished with result: $RUN_RESULT" >&2
exit 1
fi
if [[ "$TESTS_CHANGED" == 'false' && "$RUN_RESULT" == 'skipped' ]]; then
echo "Sandbox runtime tests were skipped because no sandbox-runtime-related files changed."
exit 0
fi
echo "Unexpected test state: changed=$TESTS_CHANGED, result=$RUN_RESULT" >&2
exit 1
dify-agent-tests-run:
name: Run Dify Agent Tests
needs:
- pre_job
- check-changes
if: needs.pre_job.outputs.should_skip != 'true' && needs.check-changes.outputs.dify-agent-changed == 'true'
uses: ./.github/workflows/dify-agent-tests.yml
secrets: inherit
dify-agent-tests:
name: Dify Agent Tests
if: ${{ always() }}
needs:
- pre_job
- check-changes
- dify-agent-tests-run
runs-on: ubuntu-24.04
steps:
- name: Finalize Dify Agent Tests status
env:
SHOULD_SKIP_WORKFLOW: ${{ needs.pre_job.outputs.should_skip }}
TESTS_CHANGED: ${{ needs.check-changes.outputs.dify-agent-changed }}
RUN_RESULT: ${{ needs.dify-agent-tests-run.result }}
PRE_JOB_RESULT: ${{ needs.pre_job.result }}
CHANGES_RESULT: ${{ needs.check-changes.result }}
run: |
if [[ "$SHOULD_SKIP_WORKFLOW" == 'true' ]]; then
echo "Dify agent tests were skipped because this workflow run duplicated a successful or newer run."
exit 0
fi
if [[ "$PRE_JOB_RESULT" != 'success' || "$CHANGES_RESULT" != 'success' ]]; then
echo "Cannot finalize tests: duplicate check=$PRE_JOB_RESULT, change detection=$CHANGES_RESULT" >&2
exit 1
fi
if [[ "$TESTS_CHANGED" == 'true' ]]; then
if [[ "$RUN_RESULT" == 'success' ]]; then
echo "Dify agent tests ran successfully."
exit 0
fi
echo "Dify agent tests were required but finished with result: $RUN_RESULT" >&2
exit 1
fi
if [[ "$TESTS_CHANGED" == 'false' && "$RUN_RESULT" == 'skipped' ]]; then
echo "Dify agent tests were skipped because no dify-agent-related files changed."
exit 0
fi
echo "Unexpected test state: changed=$TESTS_CHANGED, result=$RUN_RESULT" >&2
exit 1

122
.github/workflows/post-merge.yml vendored Normal file
View File

@@ -0,0 +1,122 @@
name: Post-Merge Checks
on:
push:
branches: ['main']
permissions:
contents: read
concurrency:
group: post-merge-${{ github.sha }}
cancel-in-progress: false
jobs:
check-changes:
name: Check Changed Files
runs-on: depot-ubuntu-24.04
outputs:
external-e2e-changed: ${{ steps.changes.outputs.external_e2e }}
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: dorny/paths-filter@ceb8a2b8f2d89434be7ff52d3de7ec3738c5cc9d # v4.0.3
id: changes
with:
filters: |
external_e2e:
- 'e2e/features/agent-v2/**'
- 'e2e/features/step-definitions/agent-v2/**'
- 'e2e/features/step-definitions/common/**'
- 'e2e/features/support/**'
- 'e2e/fixtures/auth.ts'
- 'e2e/fixtures/test-materials/**'
- 'e2e/scripts/**'
- 'e2e/support/**'
- 'e2e/cucumber.config.ts'
- 'e2e/package.json'
- 'e2e/test-env.ts'
- 'e2e/tsconfig.json'
- 'package.json'
- 'pnpm-lock.yaml'
- '.github/workflows/post-merge.yml'
- '.github/workflows/web-e2e.yml'
- '.github/actions/setup-web/**'
- 'docker/docker-compose.middleware.yaml'
- 'docker/envs/middleware.env.example'
- 'docker/ssrf_proxy/**'
- 'docker/volumes/sandbox/conf/**'
- 'dify-agent/**'
- 'dify-agent-runtime/**'
- 'api/pyproject.toml'
- 'api/uv.lock'
- 'api/tests/integration_tests/.env.example'
- 'api/clients/agent_backend/**'
- 'api/core/app/apps/agent_app/**'
- 'api/core/workflow/nodes/agent_v2/**'
- 'api/controllers/console/agent/**'
- 'api/controllers/console/app/agent*.py'
- 'api/controllers/console/app/audio.py'
- 'api/controllers/common/agent_access.py'
- 'api/controllers/inner_api/agent/**'
- 'api/controllers/inner_api/wraps.py'
- 'api/controllers/service_api/app/completion.py'
- 'api/controllers/service_api/wraps.py'
- 'api/controllers/web/completion.py'
- 'api/controllers/web/wraps.py'
- 'api/services/agent_llm_inner_service.py'
- 'api/services/agent_tool_inner_service.py'
- 'api/services/audio_service.py'
- 'api/services/entities/agent_llm_inner.py'
- 'api/services/entities/agent_tool_inner.py'
- 'api/services/errors/agent_tool_inner.py'
- 'api/services/agent/**'
- 'api/core/plugin/**'
- 'api/services/plugin/**'
- 'api/core/tools/**'
- 'api/services/tools/**'
- 'packages/contracts/package.json'
- 'packages/contracts/console.ts'
- 'packages/contracts/generated/api/console/router.gen.ts'
- 'packages/contracts/generated/api/web/**'
- 'packages/contracts/generated/api/console/agent/**'
- 'packages/contracts/generated/api/console/apps/**'
- 'packages/contracts/generated/api/console/datasets/**'
- 'packages/contracts/generated/api/console/orpc.gen.ts'
- 'packages/contracts/generated/api/console/workspaces/**'
- 'packages/contracts/generated/api/service/**'
- 'web/features/agent-v2/**'
- 'web/app/\(commonLayout\)/agents/**'
- 'web/app/\(commonLayout\)/@detailSidebar/agents/**'
- 'web/app/\(shareLayout\)/chat/**'
- 'web/app/\(shareLayout\)/components/**'
- 'web/app/components/base/chat/chat-with-history/**'
- 'web/app/components/base/chat/chat/**'
- 'web/app/components/base/voice-input/**'
- 'web/app/components/workflow/index.tsx'
- 'web/app/components/workflow/block-selector/**'
- 'web/app/components/workflow/hooks/use-node-keyboard-interactions.ts'
- 'web/app/components/workflow/hooks/use-nodes-interactions.ts'
- 'web/app/components/workflow/hooks/use-nodes-sync-draft.ts'
- 'web/app/components/workflow/nodes/_base/**'
- 'web/app/components/workflow/nodes/agent-v2/**'
- 'web/i18n/locales/en-US/agent-v-2.json'
- 'web/i18n/locales/en-US/common.json'
- 'web/service/base.ts'
- 'web/service/console/**'
- 'web/service/share.ts'
- 'web/service/use-share.ts'
- 'web/service/webapp-address.ts'
- 'web/package.json'
- 'pnpm-workspace.yaml'
external-e2e:
name: External Runtime E2E
needs: check-changes
if: needs.check-changes.outputs.external-e2e-changed == 'true'
permissions:
actions: read
contents: read
uses: ./.github/workflows/web-e2e.yml
with:
run-external-runtime: true
secrets: inherit

View File

@@ -17,12 +17,12 @@ jobs:
pull-requests: write
steps:
- name: Checkout PR branch
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0
- name: Setup Python & UV
uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0
with:
enable-cache: true

View File

@@ -21,10 +21,10 @@ jobs:
if: ${{ github.event.workflow_run.conclusion == 'success' && github.event.workflow_run.pull_requests[0].head.repo.full_name != github.repository }}
steps:
- name: Checkout default branch (trusted code)
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Setup Python & UV
uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0
with:
enable-cache: true

View File

@@ -17,12 +17,12 @@ jobs:
pull-requests: write
steps:
- name: Checkout PR branch
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0
- name: Setup Python & UV
uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0
with:
enable-cache: true

View File

@@ -0,0 +1,98 @@
name: Sandbox Runtime Tests
on:
workflow_call:
permissions:
contents: read
concurrency:
group: sandbox-runtime-tests-${{ github.head_ref || github.run_id }}
cancel-in-progress: true
jobs:
sandbox-runtime-unit:
name: Sandbox Runtime Unit Tests
runs-on: depot-ubuntu-24.04
defaults:
run:
shell: bash
working-directory: dify-agent-runtime
steps:
- name: Checkout code
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0
persist-credentials: false
- name: Setup Go
uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0
with:
go-version-file: dify-agent-runtime/go.mod
cache-dependency-path: dify-agent-runtime/go.sum
- name: Run unit tests
run: go test -race -count=1 ./...
sandbox-runtime-lint:
name: Sandbox Runtime Lint
runs-on: depot-ubuntu-24.04
defaults:
run:
shell: bash
working-directory: dify-agent-runtime
steps:
- name: Checkout code
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0
persist-credentials: false
- name: Setup Go
uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0
with:
go-version-file: dify-agent-runtime/go.mod
cache-dependency-path: dify-agent-runtime/go.sum
- name: Run golangci-lint
uses: golangci/golangci-lint-action@ba0d7d2ec06a0ea1cb5fa41b2e4a3ab91d21278a # v9.3.0
with:
working-directory: dify-agent-runtime
version: latest
sandbox-runtime-integration:
name: Sandbox Runtime Integration Tests
runs-on: depot-ubuntu-24.04
defaults:
run:
shell: bash
working-directory: dify-agent-runtime
steps:
- name: Checkout code
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0
persist-credentials: false
- name: Setup Go
uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0
with:
go-version-file: dify-agent-runtime/go.mod
cache-dependency-path: dify-agent-runtime/go.sum
- name: Build and start runtime
run: make integration-up
- name: Run integration tests
run: make integration-test
- name: Dump container logs on failure
if: failure()
run: make integration-logs || true
- name: Stop runtime container
if: always()
run: make integration-down

View File

@@ -8,7 +8,7 @@ on:
- reopened
- synchronize
merge_group:
branches: ["main"]
branches: ['main']
types: [checks_requested]
jobs:

55
.github/workflows/size-labeler.yml vendored Normal file
View File

@@ -0,0 +1,55 @@
name: Pull Request Size Labeler
on:
pull_request_target:
types: [opened, reopened, synchronize, ready_for_review, edited]
permissions:
pull-requests: write
concurrency:
group: size-labeler-${{ github.event.pull_request.number }}
cancel-in-progress: false
jobs:
label:
runs-on: depot-ubuntu-24.04
steps:
# Only read PR metadata. Never check out or execute the PR's code here.
- uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
with:
script: |
const { owner, repo } = context.repo
const issue_number = context.payload.pull_request.number
const { data: pr } = await github.rest.pulls.get({ owner, repo, pull_number: issue_number })
const files = await github.paginate(github.rest.pulls.listFiles, {
owner, repo, pull_number: issue_number, per_page: 100,
})
// GitHub caps this endpoint at 3,000 files; avoid labeling a partial count.
if (files.length !== pr.changed_files) {
core.warning('Skipping size label because the changed-file list is incomplete')
return
}
const ignoredNames = new Set(['uv.lock', 'pnpm-lock.yaml', 'package-lock.json', 'yarn.lock'])
const changes = files
.filter(file => !ignoredNames.has(file.filename.split('/').pop()))
.reduce((total, file) => total + file.additions + file.deletions, 0)
// Match the descriptions of the repository's existing size labels.
const buckets = [
[10, 'size:XS'], [30, 'size:S'], [100, 'size:M'],
[500, 'size:L'], [1000, 'size:XL'], [Infinity, 'size:XXL'],
]
const label = buckets.find(([limit]) => changes < limit)[1]
const sizeLabels = new Set(buckets.map(([, name]) => name))
const labels = await github.paginate(github.rest.issues.listLabelsOnIssue, {
owner, repo, issue_number, per_page: 100,
})
// Add first so an API error cannot leave the PR without a size label.
if (!labels.some(item => item.name === label)) {
await github.rest.issues.addLabels({ owner, repo, issue_number, labels: [label] })
}
for (const item of labels) {
if (sizeLabels.has(item.name) && item.name !== label) {
await github.rest.issues.removeLabel({ owner, repo, issue_number, name: item.name })
}
}

View File

@@ -11,20 +11,19 @@ on:
jobs:
stale:
runs-on: depot-ubuntu-24.04
permissions:
issues: write
pull-requests: write
steps:
- uses: actions/stale@eb5cf3af3ac0a1aa4c9c45633dd1ae542a27a899 # v10.3.0
- uses: actions/stale@4391f3da665fdf50b6810c1a66712fb9ba21aa93 # v11.0.0
with:
days-before-issue-stale: 15
days-before-issue-close: 3
repo-token: ${{ secrets.GITHUB_TOKEN }}
stale-issue-message: "Closed due to inactivity. If you have any questions, you can reopen it."
stale-pr-message: "Closed due to inactivity. If you have any questions, you can reopen it."
stale-issue-message: 'Closed due to inactivity. If you have any questions, you can reopen it.'
stale-pr-message: 'Closed due to inactivity. If you have any questions, you can reopen it.'
stale-issue-label: 'no-issue-activity'
stale-pr-label: 'no-pr-activity'
any-of-labels: '🌚 invalid,🙋‍♂️ question,wont-fix,no-issue-activity,no-pr-activity,💪 enhancement,🤔 cant-reproduce,🙏 help wanted'

View File

@@ -2,10 +2,39 @@ name: Style check
on:
workflow_call:
concurrency:
group: style-${{ github.head_ref || github.run_id }}
cancel-in-progress: true
inputs:
base-rev:
required: true
type: string
classification-succeeded:
description: Whether the caller successfully classified the changed files.
required: true
type: boolean
run-python-style:
description: Run Python style checks for the changed files.
required: true
type: boolean
run-dify-agent-style:
description: Run Dify Agent style checks for the changed files.
required: true
type: boolean
run-web-style:
description: Run Web style checks for the changed files.
required: true
type: boolean
run-ts-common-style:
description: Run shared TypeScript style checks for the changed files.
required: true
type: boolean
run-superlinter:
description: Run SuperLinter for the changed files.
required: true
type: boolean
skip-checks:
description: Create the required check runs without repeating previously successful work.
required: false
type: boolean
default: false
permissions:
checks: write
@@ -15,52 +44,90 @@ permissions:
jobs:
python-style:
name: Python Style
if: ${{ !inputs.skip-checks && (!inputs.classification-succeeded || inputs.run-python-style || inputs.run-dify-agent-style) }}
runs-on: depot-ubuntu-24.04
steps:
- name: Verify changed-file classification
if: ${{ !inputs.classification-succeeded }}
run: |
echo "Changed-file classification failed; refusing to skip Python style checks." >&2
exit 1
- name: Checkout code
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- name: Check changed files
id: changed-files
uses: tj-actions/changed-files@9426d40962ed5378910ee2e21d5f8c6fcbf2dd96 # v47.0.6
with:
files: |
api/**
.github/workflows/style.yml
fetch-depth: 0
- name: Setup UV and Python
if: steps.changed-files.outputs.any_changed == 'true'
uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0
with:
enable-cache: false
python-version: "3.12"
cache-dependency-glob: api/uv.lock
python-version: '3.12'
cache-dependency-glob: |
api/uv.lock
dify-agent/uv.lock
- name: Install dependencies
if: steps.changed-files.outputs.any_changed == 'true'
if: inputs.run-python-style
run: uv sync --project api --dev
- name: Run Import Linter
if: steps.changed-files.outputs.any_changed == 'true'
if: inputs.run-python-style
run: uv run --directory api --dev lint-imports
- name: Run Response Contract Linter
if: steps.changed-files.outputs.any_changed == 'true'
if: inputs.run-python-style
run: uv run --project api --dev python api/dev/lint_response_contracts.py --fail-on-mismatch
- name: Run No New Getattr Guard
if: inputs.run-python-style
run: uv run --project api python scripts/check_no_new_getattr.py --base-rev "${{ inputs.base-rev }}"
- name: Run No New Controller SQLAlchemy Guard
if: inputs.run-python-style
run: uv run --project api python scripts/check_no_new_controller_sqlalchemy.py --base-rev "${{ inputs.base-rev }}"
- name: Run No New Session Mock Guard
if: inputs.run-python-style
run: uv run --project api python scripts/check_no_new_session_mock.py --base-rev "${{ inputs.base-rev }}"
- name: Run No Spec Mock Guard
if: inputs.run-python-style
run: uv run --project api python scripts/check_no_spec_mock.py
- name: Run Type Checks
if: steps.changed-files.outputs.any_changed == 'true'
if: inputs.run-python-style
env:
PYREFLY_OUTPUT_FORMAT: github
run: make type-check-core
- name: Run Dify Agent Ruff
if: inputs.run-dify-agent-style
run: make -C dify-agent check
- name: Run Dify Agent Type Checks
if: inputs.run-dify-agent-style
run: make -C dify-agent typecheck
- name: Dotenv check
if: steps.changed-files.outputs.any_changed == 'true'
if: inputs.run-python-style
run: uv run --project api dotenv-linter ./api/.env.example ./web/.env.example
web-style:
name: Web Style
web-build:
name: Web Build and Bundle Analysis
if: ${{ !inputs.skip-checks && inputs.classification-succeeded && inputs.run-web-style }}
permissions:
contents: read
pull-requests: write
uses: ./.github/workflows/web-bundle-size.yml
with:
base-rev: ${{ inputs.base-rev }}
web-style-checks:
name: Web Static Checks
if: ${{ !inputs.skip-checks && (!inputs.classification-succeeded || inputs.run-web-style) }}
runs-on: depot-ubuntu-24.04
defaults:
run:
@@ -70,143 +137,130 @@ jobs:
pull-requests: read
steps:
- name: Verify changed-file classification
if: ${{ !inputs.classification-succeeded }}
working-directory: .
run: |
echo "Changed-file classification failed; refusing to skip Web style checks." >&2
exit 1
- name: Checkout code
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- name: Check changed files
id: changed-files
uses: tj-actions/changed-files@9426d40962ed5378910ee2e21d5f8c6fcbf2dd96 # v47.0.6
with:
files: |
web/**
e2e/**
sdks/nodejs-client/**
packages/**
package.json
pnpm-lock.yaml
pnpm-workspace.yaml
.nvmrc
.github/workflows/style.yml
.github/actions/setup-web/**
- name: Setup web environment
if: steps.changed-files.outputs.any_changed == 'true'
uses: ./.github/actions/setup-web
- name: Check generated i18n types
run: vp run i18n:check-types
- name: Web tsslint
if: steps.changed-files.outputs.any_changed == 'true'
env:
NODE_OPTIONS: --max-old-space-size=4096
run: vp run lint:tss
- name: Web dead code check
if: steps.changed-files.outputs.any_changed == 'true'
working-directory: .
run: vp run knip
- name: Web dead code check production
if: steps.changed-files.outputs.any_changed == 'true'
working-directory: .
run: vp run knip:production
- name: Web production unused declarations check
if: steps.changed-files.outputs.any_changed == 'true'
working-directory: .
run: vp run knip:production-unused-check
# Preserve the existing required check while build and static checks run in parallel.
web-style:
name: Web Style
if: ${{ always() && !inputs.skip-checks && (!inputs.classification-succeeded || inputs.run-web-style) }}
needs: [web-build, web-style-checks]
runs-on: ubuntu-24.04
permissions: {}
steps:
- name: Verify web checks
env:
BUILD_RESULT: ${{ needs.web-build.result }}
STYLE_RESULT: ${{ needs.web-style-checks.result }}
run: |
if [[ "$BUILD_RESULT" != 'success' || "$STYLE_RESULT" != 'success' ]]; then
echo "Web checks failed: build=$BUILD_RESULT, static checks=$STYLE_RESULT" >&2
exit 1
fi
ts-common-style:
name: TS Common
runs-on: depot-ubuntu-24.04
if: ${{ !inputs.skip-checks && (!inputs.classification-succeeded || inputs.run-ts-common-style) }}
runs-on: depot-ubuntu-24.04-4
permissions:
checks: write
pull-requests: read
steps:
- name: Verify changed-file classification
if: ${{ !inputs.classification-succeeded }}
run: |
echo "Changed-file classification failed; refusing to skip TypeScript style checks." >&2
exit 1
- name: Checkout code
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- name: Check changed files
id: changed-files
uses: tj-actions/changed-files@9426d40962ed5378910ee2e21d5f8c6fcbf2dd96 # v47.0.6
with:
files: |
web/**
cli/**
e2e/**
sdks/nodejs-client/**
packages/**
package.json
pnpm-lock.yaml
pnpm-workspace.yaml
.nvmrc
eslint.config.mjs
.github/workflows/style.yml
.github/actions/setup-web/**
- name: Setup web environment
if: steps.changed-files.outputs.any_changed == 'true'
uses: ./.github/actions/setup-web
- name: Restore ESLint cache
if: steps.changed-files.outputs.any_changed == 'true'
id: eslint-cache-restore
uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
- name: Restore static check task cache
id: static-check-cache
uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
with:
path: .eslintcache
key: ${{ runner.os }}-eslint-${{ hashFiles('pnpm-lock.yaml', 'eslint.config.mjs', 'web/eslint.config.mjs', 'web/eslint.constants.mjs', 'web/plugins/eslint/**') }}-${{ github.sha }}
path: node_modules/.vite/task-cache
key: vite-task-static-v1-${{ runner.os }}-${{ runner.arch }}-${{ github.run_id }}-${{ github.run_attempt }}
restore-keys: |
${{ runner.os }}-eslint-${{ hashFiles('pnpm-lock.yaml', 'eslint.config.mjs', 'web/eslint.config.mjs', 'web/eslint.constants.mjs', 'web/plugins/eslint/**') }}-
vite-task-static-v1-${{ runner.os }}-${{ runner.arch }}-
- name: Style check
if: steps.changed-files.outputs.any_changed == 'true'
run: vp run lint:ci
- name: Static check
run: vp run -w check
- name: Type check
if: steps.changed-files.outputs.any_changed == 'true'
run: vp run type-check
- name: Save ESLint cache
if: steps.changed-files.outputs.any_changed == 'true' && success() && steps.eslint-cache-restore.outputs.cache-hit != 'true'
uses: actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
- name: Save static check task cache
if: success() && github.event_name != 'merge_group'
uses: actions/cache/save@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
with:
path: .eslintcache
key: ${{ steps.eslint-cache-restore.outputs.cache-primary-key }}
path: node_modules/.vite/task-cache
key: ${{ steps.static-check-cache.outputs.cache-primary-key }}
superlinter:
name: SuperLinter
if: ${{ !inputs.skip-checks && (!inputs.classification-succeeded || inputs.run-superlinter) }}
runs-on: depot-ubuntu-24.04
steps:
- name: Verify changed-file classification
if: ${{ !inputs.classification-succeeded }}
run: |
echo "Changed-file classification failed; refusing to skip SuperLinter." >&2
exit 1
- name: Checkout code
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0
persist-credentials: false
- name: Check changed files
id: changed-files
uses: tj-actions/changed-files@9426d40962ed5378910ee2e21d5f8c6fcbf2dd96 # v47.0.6
with:
files: |
**.sh
**.yaml
**.yml
**Dockerfile
dev/**
.editorconfig
- name: Super-linter
uses: super-linter/super-linter/slim@9e863354e3ff62e0727d37183162c4a88873df41 # v8.6.0
if: steps.changed-files.outputs.any_changed == 'true'
uses: super-linter/super-linter/slim@2da136927bd4a73596db63044b504547c62cb854 # v9.0.0
env:
BASH_SEVERITY: warning
DEFAULT_BRANCH: origin/main
EDITORCONFIG_FILE_NAME: editorconfig-checker.json
FILTER_REGEX_INCLUDE: pnpm-lock.yaml
ENABLE_GITHUB_PULL_REQUEST_SUMMARY_COMMENT: false
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
IGNORE_GENERATED_FILES: true
IGNORE_GITIGNORED_FILES: true
VALIDATE_ALL_CODEBASE: false
VALIDATE_BASH: true
VALIDATE_BASH_EXEC: true
# FIXME: temporarily disabled until api-docker.yaml's run script is fixed for shellcheck

View File

@@ -9,6 +9,8 @@ on:
- package.json
- pnpm-lock.yaml
- pnpm-workspace.yaml
- .github/actions/setup-web/**
- .github/workflows/tool-test-sdks.yaml
concurrency:
group: sdk-tests-${{ github.head_ref || github.run_id }}
@@ -24,19 +26,17 @@ jobs:
working-directory: sdks/nodejs-client
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- name: Use Node.js
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version: 22
cache: ''
cache-dependency-path: 'pnpm-lock.yaml'
- name: Install Dependencies
run: pnpm install --frozen-lockfile
- name: Setup web environment
uses: ./.github/actions/setup-web
- name: Test
run: pnpm test
- name: Build and verify package entry points
run: |
pnpm build
node --input-type=module -e "import { access } from 'node:fs/promises'; import 'dify-client'; await access('dist/index.d.ts')"

View File

@@ -8,15 +8,19 @@ on:
workflow_dispatch:
inputs:
files:
description: 'Specific files to translate (space-separated, e.g., "app common"). Required for full mode; leave empty in incremental mode to use en-US files changed since HEAD~1.'
description: 'Specific files to translate (space-separated, e.g., "app common").
Required for full mode; leave empty in incremental mode to use en-US
files changed since HEAD~1.'
required: false
type: string
languages:
description: 'Specific languages to translate (space-separated, e.g., "zh-Hans ja-JP"). Leave empty for all supported target languages except en-US.'
description: 'Specific languages to translate (space-separated, e.g., "zh-Hans
ja-JP"). Leave empty for all supported target languages except en-US.'
required: false
type: string
mode:
description: 'Sync mode: incremental (compare with previous en-US revision) or full (sync all keys in scope)'
description: 'Sync mode: incremental (compare with previous en-US revision) or
full (sync all keys in scope)'
required: false
default: incremental
type: choice
@@ -40,9 +44,10 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0
ref: ${{ github.event.client_payload.head_sha || github.sha }}
token: ${{ secrets.GITHUB_TOKEN }}
- name: Configure Git
@@ -65,7 +70,7 @@ jobs:
/supported: true/ && value != \"en-US\" {
printf \"%s \", value
}
" web/i18n-config/languages.ts | sed 's/[[:space:]]*$//')
" web/i18n/languages.ts | sed 's/[[:space:]]*$//')
generate_changes_json() {
node .github/scripts/generate-i18n-changes.mjs
@@ -106,9 +111,9 @@ jobs:
elif [ "$SYNC_MODE" = "incremental" ]; then
BASE_SHA=$(git rev-parse HEAD~1 2>/dev/null || true)
if [ -n "$BASE_SHA" ]; then
CHANGED_FILES=$(git diff --name-only "$BASE_SHA" "$HEAD_SHA" -- 'web/i18n/en-US/*.json' 2>/dev/null | sed -n 's@^.*/@@p' | sed 's/\.json$//' | tr '\n' ' ' | sed 's/[[:space:]]*$//')
CHANGED_FILES=$(git diff --name-only --find-renames=100% --diff-filter=AMDT "$BASE_SHA" "$HEAD_SHA" -- 'web/i18n/' 2>/dev/null | sed -n '\@^web/i18n/locales/en-US/[^/]*\.json$@p' | sed -n 's@^.*/@@p' | sed 's/\.json$//' | tr '\n' ' ' | sed 's/[[:space:]]*$//')
else
CHANGED_FILES=$(find web/i18n/en-US -maxdepth 1 -type f -name '*.json' -print | sed -n 's@^.*/@@p' | sed 's/\.json$//' | sort | tr '\n' ' ' | sed 's/[[:space:]]*$//')
CHANGED_FILES=$(find web/i18n/locales/en-US -maxdepth 1 -type f -name '*.json' -print | sed -n 's@^.*/@@p' | sed 's/\.json$//' | sort | tr '\n' ' ' | sed 's/[[:space:]]*$//')
fi
elif [ "$SYNC_MODE" = "full" ]; then
echo "workflow_dispatch full mode requires the files input to stay within CI limits." >&2
@@ -158,7 +163,7 @@ jobs:
- name: Run Claude Code for Translation Sync
if: steps.context.outputs.CHANGED_FILES != ''
uses: anthropics/claude-code-action@806af32823ef69c8ef357086c573a902af641307 # v1.0.151
uses: anthropics/claude-code-action@ed670b4cf9de2a5a570d130d2f6197b9e543cd64 # v1.0.240
with:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
github_token: ${{ secrets.GITHUB_TOKEN }}
@@ -166,12 +171,12 @@ jobs:
show_full_output: ${{ github.event_name == 'workflow_dispatch' }}
prompt: |
You are the i18n sync agent for the Dify repository.
Your job is to keep translations synchronized with the English source files under `${{ github.workspace }}/web/i18n/en-US/`.
Your job is to keep translations synchronized with the English source files under `${{ github.workspace }}/web/i18n/locales/en-US/`.
Use absolute paths at all times:
- Repo root: `${{ github.workspace }}`
- Web directory: `${{ github.workspace }}/web`
- Language config: `${{ github.workspace }}/web/i18n-config/languages.ts`
- Language config: `${{ github.workspace }}/web/i18n/languages.ts`
Inputs:
- Files in scope: `${{ steps.context.outputs.CHANGED_FILES }}`
@@ -194,12 +199,12 @@ jobs:
Required execution plan:
1. Resolve target languages.
- Use the provided `Target languages` value as the source of truth.
- If it is unexpectedly empty, read `${{ github.workspace }}/web/i18n-config/languages.ts` and use every language with `supported: true` except `en-US`.
- If it is unexpectedly empty, read `${{ github.workspace }}/web/i18n/languages.ts` and use every language with `supported: true` except `en-US`.
2. Stay strictly in scope.
- Only process the files listed in `Files in scope`.
- Only process the resolved target languages, never `en-US`.
- Do not touch unrelated i18n files.
- Do not modify `${{ github.workspace }}/web/i18n/en-US/`.
- Do not modify `${{ github.workspace }}/web/i18n/locales/en-US/`.
3. Resolve source changes.
- If `Structured change set available` is `true`, read `/tmp/i18n-changes.json` and use it as the source of truth for file-level and key-level changes.
- For each file entry:
@@ -223,7 +228,7 @@ jobs:
- Match the existing terminology and register used by each locale.
- Prefer one Edit per file when stable, but prioritize correctness over batching.
6. Verify only the edited files.
- Run `vp run dify-web#lint:fix --quiet -- <relative edited i18n file paths under web/>`
- Run `vp fmt <repo-relative edited paths such as web/i18n/locales/...>`
- Run `vp run dify-web#i18n:check ${{ steps.context.outputs.FILE_ARGS }} ${{ steps.context.outputs.LANG_ARGS }}`
- If verification fails, fix the remaining problems before continuing.
7. Stop after the scoped locale files are updated and verification passes.
@@ -237,7 +242,7 @@ jobs:
if: steps.context.outputs.CHANGED_FILES != ''
shell: bash
run: |
if [ -z "$(git -C "${{ github.workspace }}" status --porcelain -- web/i18n/)" ]; then
if [ -z "$(git -C "${{ github.workspace }}" status --porcelain -- web/i18n/locales/)" ]; then
echo "has_changes=false" >> "$GITHUB_OUTPUT"
exit 0
fi
@@ -256,7 +261,7 @@ jobs:
shell: bash
run: |
git -C "${{ github.workspace }}" checkout -B "${{ steps.pr_meta.outputs.branch_name }}"
git -C "${{ github.workspace }}" add web/i18n/
git -C "${{ github.workspace }}" add web/i18n/locales/
git -C "${{ github.workspace }}" commit -m "chore(i18n): sync translations with en-US"
- name: Push translation branch
@@ -281,6 +286,7 @@ jobs:
BASE_SHA: ${{ steps.context.outputs.BASE_SHA }}
HEAD_SHA: ${{ steps.context.outputs.HEAD_SHA }}
REPO_NAME: ${{ github.repository }}
EVENT_NAME: ${{ github.event_name }}
shell: bash
run: |
PR_BODY_FILE=/tmp/i18n-pr-body.md
@@ -291,6 +297,7 @@ jobs:
export LANG_COUNT
node <<'NODE' > "$PR_BODY_FILE"
const { execFileSync } = require('node:child_process')
const fs = require('node:fs')
const changesPath = '/tmp/i18n-changes.json'
@@ -299,7 +306,25 @@ jobs:
: { changes: {} }
const filesInScope = (process.env.FILES_IN_SCOPE || '').split(/\s+/).filter(Boolean)
const sourceCommit = process.env.HEAD_SHA
let sourcePr
if (process.env.EVENT_NAME === 'repository_dispatch') {
try {
const pulls = JSON.parse(execFileSync('gh', [
'api', `repos/${process.env.REPO_NAME}/commits/${sourceCommit}/pulls`,
], { encoding: 'utf8' }))
sourcePr = pulls.find(pr => pr.merged_at && pr.merge_commit_sha === sourceCommit)
} catch (error) {
console.error(`Could not resolve source PR: ${error.message}`)
}
}
const lines = [
'## Source',
'',
...(sourcePr ? [`- **PR**: [#${sourcePr.number}](${sourcePr.html_url})`] : []),
`- **Commit**: [\`${sourceCommit.slice(0, 12)}\`](https://github.com/${process.env.REPO_NAME}/commit/${sourceCommit})`,
'',
'## Summary',
'',
`- **Files synced**: \`${process.env.FILES_IN_SCOPE || '<none>'}\``,
@@ -322,7 +347,7 @@ jobs:
'## Verification',
'',
`- \`vp run dify-web#i18n:check --file ${process.env.FILES_IN_SCOPE} --lang ${process.env.TARGET_LANGS}\``,
`- \`vp run dify-web#lint:fix --quiet -- <edited i18n files under web/>\``,
`- \`vp fmt <repo-relative edited paths such as web/i18n/locales/...>\``,
'',
'## Notes',
'',

View File

@@ -4,7 +4,7 @@ on:
push:
branches: [main]
paths:
- 'web/i18n/en-US/*.json'
- 'web/i18n/locales/en-US/*.json'
permissions:
contents: write
@@ -21,7 +21,7 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0
@@ -36,9 +36,9 @@ jobs:
HEAD_SHA="${{ github.sha }}"
if [ -n "$BASE_SHA" ]; then
CHANGED_FILES=$(git diff --name-only "$BASE_SHA" "$HEAD_SHA" -- 'web/i18n/en-US/*.json' 2>/dev/null | sed -n 's@^.*/@@p' | sed 's/\.json$//' | tr '\n' ' ' | sed 's/[[:space:]]*$//')
CHANGED_FILES=$(git diff --name-only --find-renames=100% --diff-filter=AMDT "$BASE_SHA" "$HEAD_SHA" -- 'web/i18n/' 2>/dev/null | sed -n '\@^web/i18n/locales/en-US/[^/]*\.json$@p' | sed -n 's@^.*/@@p' | sed 's/\.json$//' | tr '\n' ' ' | sed 's/[[:space:]]*$//')
else
CHANGED_FILES=$(find web/i18n/en-US -maxdepth 1 -type f -name '*.json' -print | sed -n 's@^.*/@@p' | sed 's/\.json$//' | sort | tr '\n' ' ' | sed 's/[[:space:]]*$//')
CHANGED_FILES=$(find web/i18n/locales/en-US -maxdepth 1 -type f -name '*.json' -print | sed -n 's@^.*/@@p' | sed 's/\.json$//' | sort | tr '\n' ' ' | sed 's/[[:space:]]*$//')
fi
export BASE_SHA HEAD_SHA CHANGED_FILES

View File

@@ -20,23 +20,23 @@ jobs:
strategy:
matrix:
python-version:
- "3.12"
- '3.12'
steps:
- name: Checkout code
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- name: Free Disk Space
uses: endersonmenezes/free-disk-space@7901478139cff6e9d44df5972fd8ab8fcade4db1 # v3.2.2
uses: endersonmenezes/free-disk-space@2a22f8c59cae9cddae7194b33e6b92d023b2b4b8 # v4.0.0
with:
remove_dotnet: true
remove_haskell: true
remove_tool_cache: true
- name: Setup UV and Python
uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0
with:
enable-cache: true
python-version: ${{ matrix.python-version }}
@@ -48,16 +48,16 @@ jobs:
- name: Install dependencies
run: uv sync --project api --dev
# - name: Set up Vector Store (TiDB)
# uses: hoverkraft-tech/compose-action@v2.0.2
# with:
# compose-file: docker/tidb/docker-compose.yaml
# services: |
# tidb
# tiflash
# - name: Set up Vector Store (TiDB)
# uses: hoverkraft-tech/compose-action@v2.0.2
# with:
# compose-file: docker/tidb/docker-compose.yaml
# services: |
# tidb
# tiflash
# - name: Check VDB Ready (TiDB)
# run: uv run --project api python api/providers/vdb/tidb-vector/tests/integration_tests/check_tiflash_ready.py
# - name: Check VDB Ready (TiDB)
# run: uv run --project api python api/providers/vdb/tidb-vector/tests/integration_tests/check_tiflash_ready.py
- name: Test Vector Stores
run: |

Some files were not shown because too many files have changed in this diff Show More