Compare commits

..
Author SHA1 Message Date
jyong 85e568e114 compatible query is None 2024-04-03 18:39:29 +08:00
jyong 0026cb404f compatible query is None 2024-04-03 18:38:27 +08:00
JzoNg 62919a9ff5 app list mutation 2024-04-03 18:06:36 +08:00
StyleZhang e13f8da9d5 fix: prompt editor 2024-04-03 18:04:46 +08:00
takatost 53aca1a922 add sys variables for start node 2024-04-03 17:53:54 +08:00
StyleZhang 464aee08a1 fix: prompt editor 2024-04-03 17:45:27 +08:00
Joel ab56e6b6af fix: enable memory add sys query var input 2024-04-03 17:42:21 +08:00
Joel 2a2f4cd4d5 fix: label ui 2024-04-03 17:22:10 +08:00
Joel b3a4a52a7a fix: valid tool valid empty error 2024-04-03 17:18:16 +08:00
Joel 379f9b56ad fix: start node not show sys files 2024-04-03 16:55:55 +08:00
Joel b705041dda chore: remove uage output 2024-04-03 16:52:01 +08:00
takatost fedcfe94ae update version to 0.6.0-preview-workflow.2 2024-04-03 16:50:11 +08:00
Joel add7bdc877 fix: add input instance id 2024-04-03 16:46:47 +08:00
StyleZhang 088842dcdb fix: prompt editor 2024-04-03 16:13:14 +08:00
Joel c43eaeec06 fix: can not open 2024-04-03 15:48:57 +08:00
StyleZhang f06554a11e fix: sync draft 2024-04-03 15:37:19 +08:00
Yeuoly 3ac37e802a fix: sandbox tips 2024-04-03 15:34:05 +08:00
JzoNg aee669f67d fix max length for paragraph 2024-04-03 15:32:59 +08:00
Joel c8db4d8a08 fix: editor choose context would blur 2024-04-03 15:15:35 +08:00
StyleZhang c3bb541a69 fix 2024-04-03 15:13:26 +08:00
StyleZhang ba3039d6c9 merge feat/workflow 2024-04-03 15:00:26 +08:00
Joel bd3b400121 chore: support click to show choose add var 2024-04-03 14:57:16 +08:00
StyleZhang 28e813f57f fix 2024-04-03 14:38:15 +08:00
Joel 3f11e11c2d chore: confirm ui 2024-04-03 14:08:36 +08:00
Yeuoly 37a282cc1c fix: add default lora 2024-04-03 13:51:18 +08:00
JzoNg 88ef220d4d fix app list cache 2024-04-03 13:49:29 +08:00
Yeuoly ccb67bffc4 fix: tools 2024-04-03 13:46:29 +08:00
StyleZhang 20394b3231 fix 2024-04-03 13:39:15 +08:00
nite-knite 52a1c4580c feat: update chat app publishing 2024-04-03 13:12:07 +08:00
JzoNg aca395b97d fix test run 2024-04-03 12:44:32 +08:00
StyleZhang 459b690416 fix: prompt-editor 2024-04-03 12:31:40 +08:00
Yeuoly d48bdf3e14 chore: generic 2024-04-03 12:02:51 +08:00
Joel 9fea2fd44b feat: change from creditical schema value from api 2024-04-03 11:56:54 +08:00
Joel f291aec2cd chore: start input placeholder and bg 2024-04-03 11:41:44 +08:00
takatost 00d9c48461 fix migration version dependency 2024-04-02 22:46:38 +08:00
takatost fef62d937d Merge branch 'main' into feat/workflow 2024-04-02 22:36:27 +08:00
takatost 6b06c5b957 optimize workflow inputs 2024-04-02 22:36:07 +08:00
takatost 5a4ea0932a add inputs for workflow_started event 2024-04-02 21:13:08 +08:00
StyleZhang f7e4f0a988 fix: run error 2024-04-02 21:05:04 +08:00
StyleZhang cf449b31a1 code node rename 2024-04-02 20:48:46 +08:00
StyleZhang f7184c0e36 fix: tool node check 2024-04-02 20:19:50 +08:00
JzoNg 5df66579a8 fix crash of advanced prompt app 2024-04-02 20:12:43 +08:00
StyleZhang d260e6b064 fix: prompt-editor 2024-04-02 19:55:58 +08:00
Yeuoly 01c6a35966 chore: encoder 2024-04-02 19:25:52 +08:00
StyleZhang 0202469254 fix: checklist 2024-04-02 19:06:22 +08:00
Joel fb2fa625b4 fix: use sys query instead user query 2024-04-02 18:46:44 +08:00
Joel fbdf2ba839 fix: classify default two classifies and empty check 2024-04-02 18:41:31 +08:00
Joel 716936e37a fix: remove key replicate 2024-04-02 18:30:57 +08:00
Yeuoly 1c004e0df6 optimize: sd 2024-04-02 18:21:08 +08:00
Joel 59d279fbe0 fix: remove rename check 2024-04-02 18:12:44 +08:00
Joel 2d7c43b60f feat: http panel 2024-04-02 17:45:12 +08:00
Joel a9f7f88a9a feat: answer support render var input 2024-04-02 17:38:05 +08:00
nite-knite 56cb9ccec1 feat: update workflow app publishing 2024-04-02 17:33:35 +08:00
StyleZhang e0a152164b fix: prompt-editor 2024-04-02 17:20:32 +08:00
JzoNg d72524ceb0 hide result info in chatflow 2024-04-02 17:16:39 +08:00
jyong 74538fb3b2 Merge remote-tracking branch 'origin/feat/workflow' into feat/workflow 2024-04-02 16:59:04 +08:00
jyong f832211e2e db migrate merge 2024-04-02 16:58:49 +08:00
Yeuoly e46c3a9235 optimize: tool 2024-04-02 16:58:24 +08:00
JzoNg 36c3774fac modify test run panel 2024-04-02 16:57:28 +08:00
jyong 5e201324d6 Merge branch 'main' into feat/workflow
# Conflicts:
#	api/.env.example
#	docker/docker-compose.yaml
2024-04-02 16:55:43 +08:00
Joel 5adbcacc52 fix: end node can not selector 2024-04-02 15:52:15 +08:00
takatost 8b01796f5d fix external data convert 2024-04-02 15:30:39 +08:00
Joel 34f4f76f67 fix: handle debug run valid 2024-04-02 15:27:03 +08:00
Yeuoly 01e832a587 fix: linter 2024-04-02 15:25:15 +08:00
Yeuoly 1af2d06d29 feat: add tool benchmark 2024-04-02 15:23:54 +08:00
Joel 426abe2134 fix: variable type add missing key 2024-04-02 15:14:00 +08:00
StyleZhang f62775bcad fix: prompt-editor 2024-04-02 14:12:52 +08:00
Joel 7a2083a6b7 fix: num suuport var insert 2024-04-02 14:12:34 +08:00
jyong 09650b9d47 Merge remote-tracking branch 'origin/feat/workflow' into feat/workflow 2024-04-02 14:03:02 +08:00
jyong f19219ab8d fix knowledge retrival 2024-04-02 14:02:49 +08:00
Joel 8be04b57f9 fix: http attr key rerender 2024-04-02 13:55:30 +08:00
StyleZhang ef39fa3fb2 node connect 2024-04-02 13:23:36 +08:00
JzoNg fe569559ac fix app type label 2024-04-02 12:56:11 +08:00
JzoNg 8125d8fc9f modify params of app switch 2024-04-02 12:45:33 +08:00
JzoNg fd8ed95209 fix prompt log 2024-04-02 12:34:40 +08:00
JzoNg cf22842554 support app creation in nav 2024-04-02 12:15:28 +08:00
takatost 0fcb746c08 add created_at for app model config 2024-04-02 12:07:30 +08:00
StyleZhang 9d7ab0400d chat error 2024-04-02 12:01:32 +08:00
Yeuoly 396a3e0456 feat: add tool parameter type converter 2024-04-02 11:58:50 +08:00
Joel 56a1d5330a chore: types 2024-04-02 11:50:03 +08:00
takatost c5e58c713c remove not necessary error reporting 2024-04-02 11:15:50 +08:00
Joel 6e0f13f269 feat: tool new struct 2024-04-02 11:14:33 +08:00
JzoNg 00728c2b1d support type fitlering for app template 2024-04-01 22:55:53 +08:00
JzoNg 9fb7100b3f modify style of app type tag 2024-04-01 22:55:53 +08:00
StyleZhang 4e31d7b64f chat 2024-04-01 21:17:39 +08:00
takatost 1ab3b73c14 add app info for workflow convert 2024-04-01 21:00:08 +08:00
StyleZhang b5fa68fdfe node selected 2024-04-01 20:47:59 +08:00
Yeuoly 31f24e1a14 enhance: enable configurate limitation of code 2024-04-01 20:47:26 +08:00
StyleZhang e800109c02 node selected 2024-04-01 20:33:20 +08:00
Joel 5c3162cc33 fix: http delete btn hide 2024-04-01 19:58:51 +08:00
StyleZhang 04b4be27b7 refresh history 2024-04-01 19:41:37 +08:00
takatost 5793855115 fix http single run 2024-04-01 19:40:49 +08:00
Joel 41cce464ca fix: http var inputs 2024-04-01 19:36:09 +08:00
takatost 8c55ff392d fix bugs 2024-04-01 19:33:53 +08:00
StyleZhang 45d5d259a4 fix prompt editor 2024-04-01 19:03:34 +08:00
Joel e08d871837 fix: http other params check 2024-04-01 18:48:36 +08:00
Joel ab2c112059 feat: reuse get vars inputs and http request url 2024-04-01 18:33:17 +08:00
Joel a42f26d857 fix: object label not pass the right value 2024-04-01 17:52:11 +08:00
Joel 6fea18b4d0 feat: insert var key ui 2024-04-01 17:40:31 +08:00
Joel 7e259600bf fix: debugger form struct and textare line-height 2024-04-01 17:40:31 +08:00
Yeuoly 75e95e09d3 fix: test 2024-04-01 17:07:09 +08:00
StyleZhang 51f225e567 fix 2024-04-01 16:57:42 +08:00
Joel 53c988718b fix: no var caused bugs 2024-04-01 16:57:03 +08:00
Joel 74ead43ae1 fix: query selector set sys value problem 2024-04-01 16:50:09 +08:00
StyleZhang d0509213d1 prompt editor 2024-04-01 16:47:41 +08:00
Yeuoly 5b81234db8 fix: tool entities 2024-04-01 16:43:10 +08:00
StyleZhang df9e2e478f workflow template 2024-04-01 16:38:37 +08:00
takatost 7c64f2cfe0 feat: use en-US recommended apps as fallback if using unmaintained language 2024-04-01 16:24:59 +08:00
takatost 3b3d19dab7 Merge branch 'main' into feat/workflow
# Conflicts:
#	api/controllers/console/explore/recommended_app.py
2024-04-01 16:22:49 +08:00
JzoNg 806f27c370 revert automatic prompt 2024-04-01 16:00:34 +08:00
Yeuoly 86a32517e5 fix: tool variable selectors 2024-04-01 15:42:00 +08:00
takatost 072967a1d3 fix node single step run of answer & http request & llm 2024-04-01 15:24:35 +08:00
StyleZhang 9147e0046f node connect 2024-04-01 14:10:05 +08:00
JzoNg f967203012 remove automatic 2024-04-01 13:31:30 +08:00
Joel e2d0ff4784 chore: run text font size 2024-04-01 13:19:40 +08:00
StyleZhang 85ce2e8df8 merge main 2024-04-01 13:09:40 +08:00
Joel c330f89c77 feat: support llm single run 2024-04-01 12:55:20 +08:00
StyleZhang ffb698922a fix: edge 2024-04-01 12:54:15 +08:00
takatost 50a7c2c92c fix bug 2024-04-01 12:51:01 +08:00
Joel 0843af2996 fix: sys var not show 2024-04-01 12:39:54 +08:00
Joel e9985f0696 chore: enchance debug show name 2024-04-01 12:29:51 +08:00
StyleZhang dfad42075c sys variable 2024-04-01 12:06:22 +08:00
Joel 705d765a71 feat: llm show vars 2024-04-01 11:48:42 +08:00
Joel e03367a188 feat: get input vars 2024-04-01 10:38:12 +08:00
Yeuoly c20685e669 fix 2024-03-29 22:26:26 +08:00
takatost 429dd11dd7 add icon for tool node execution 2024-03-29 22:22:58 +08:00
takatost b394dd6fb0 fix convert bug 2024-03-29 21:43:44 +08:00
takatost a30a6dda63 Merge branch 'main' into feat/workflow
# Conflicts:
#	docker/docker-compose.yaml
2024-03-29 21:18:16 +08:00
takatost de3b7e8815 http request node support template variable 2024-03-29 20:54:17 +08:00
Yeuoly 142d1be4f8 refactor 2024-03-29 20:53:48 +08:00
Yeuoly fb364d44d1 refactor 2024-03-29 20:12:26 +08:00
jyong a647698c32 Merge remote-tracking branch 'origin/feat/workflow' into feat/workflow 2024-03-29 19:44:35 +08:00
jyong 75ffdc9d3f fixed single retrival 2024-03-29 19:44:26 +08:00
StyleZhang 0d12e5c795 run history 2024-03-29 19:32:38 +08:00
jyong bab88efda9 Merge remote-tracking branch 'origin/feat/workflow' into feat/workflow 2024-03-29 19:29:42 +08:00
jyong ca6acf2650 fixed single retrival 2024-03-29 19:29:27 +08:00
Yeuoly 11b428a73f feat: agent log 2024-03-29 19:23:48 +08:00
nite-knite f43faa125b feat: add condition placeholder to if-else node 2024-03-29 19:08:35 +08:00
Joel 6b3bc789b5 fix: http text pass vars 2024-03-29 19:04:53 +08:00
Joel 586488c6a9 feat: llm output and raw text 2024-03-29 19:04:53 +08:00
jyong 704cb42869 Merge remote-tracking branch 'origin/feat/workflow' into feat/workflow
# Conflicts:
#	api/core/workflow/nodes/question_classifier/question_classifier_node.py
2024-03-29 19:00:21 +08:00
jyong 2d26c4745b add history message 2024-03-29 18:58:59 +08:00
takatost 971436d935 llm and answer node support inner variable template 2024-03-29 18:44:30 +08:00
Joel 8a2d04b305 chore: llm editor bg and not flash 2024-03-29 18:32:59 +08:00
StyleZhang 7c45f369d1 checklist 2024-03-29 18:27:41 +08:00
JzoNg 6444d94f41 fix style of app card 2024-03-29 18:24:46 +08:00
Joel a8236a270a feat: body to json editor 2024-03-29 18:19:45 +08:00
StyleZhang 760ada399f checklist 2024-03-29 18:08:27 +08:00
Joel 815262b9a6 chore: remove input vars 2024-03-29 18:02:06 +08:00
Joel 83651a038f feat: http attr support selct keys 2024-03-29 17:55:59 +08:00
Joel 589ac9b22c feat: http key value inputs 2024-03-29 17:24:36 +08:00
StyleZhang d673b4c219 fix: prompt editor 2024-03-29 17:20:48 +08:00
Joel 4e548fff5e feat: add insert var tooltip 2024-03-29 16:58:07 +08:00
Joel 636603d5af chore: type picker 2024-03-29 16:32:36 +08:00
Joel 950a52f4fc feat: input var ui 2024-03-29 16:19:09 +08:00
StyleZhang b50e897aa0 fix: prompt editor 2024-03-29 16:08:10 +08:00
StyleZhang d7be9c0afc prompt editor 2024-03-29 14:59:13 +08:00
StyleZhang 06a6d398cd checklist 2024-03-29 14:56:47 +08:00
Joel 12ed31be4d feat: api support var logic 2024-03-29 14:56:32 +08:00
Joel 8d2ac8ff8f feat: ignore invalid vars keys 2024-03-29 13:56:13 +08:00
Joel 91b84d8f1e chore: http node check 2024-03-29 13:01:36 +08:00
Joel 46cc635e05 fix: error status code 2024-03-29 12:35:04 +08:00
Joel 1ea8504cf1 chore: code output var empty check 2024-03-29 11:48:45 +08:00
Joel a32465eeb8 chore: handle key exists check 2024-03-29 11:37:16 +08:00
Joel f930521d64 chore: start var name check 2024-03-29 11:19:24 +08:00
JzoNg 42ad622a6c fix tool icon 2024-03-28 21:49:56 +08:00
JzoNg 4eb9027510 add icon for tool node in web app 2024-03-28 21:47:10 +08:00
JzoNg 05bb65bd94 add icon for tool node 2024-03-28 21:37:23 +08:00
Yeuoly 85285931e2 feat: add agent tool invoke meta 2024-03-28 20:04:31 +08:00
JzoNg d7c4032917 fix style of app creation 2024-03-28 19:48:45 +08:00
Yeuoly c1466a7a4d Merge branch 'feat/merge-tool-engine' into feat/workflow 2024-03-28 18:44:12 +08:00
Yeuoly 51404f9035 refactor: tool engine 2024-03-28 18:36:58 +08:00
Joel c1bf4c6405 chore: var picker ui 2024-03-28 18:23:05 +08:00
Joel b8818c90b0 feat: answer use selector vars 2024-03-28 17:41:41 +08:00
Joel ead55ce931 chore: support hide editor var search 2024-03-28 17:37:11 +08:00
takatost 0a0d9565ac add icon return for tool node in workflow event stream 2024-03-28 17:26:09 +08:00
StyleZhang 4235baf493 editor 2024-03-28 17:11:39 +08:00
Joel 82a82fff35 chore: llm remove var inputs 2024-03-28 16:54:14 +08:00
Joel 4934a655dd chore: xxx 2024-03-28 16:48:54 +08:00
Joel 615178dafa feat: get var list hooks 2024-03-28 16:44:11 +08:00
Joel 08650339d7 feat: split var reference 2024-03-28 15:27:11 +08:00
StyleZhang 12ea3af242 fix: sync draft 2024-03-28 14:47:09 +08:00
takatost 858ab8c8c4 merge main 2024-03-28 14:38:21 +08:00
takatost 63a4ddc251 add text/plain support for draft sync api 2024-03-28 14:36:24 +08:00
StyleZhang aa4d734244 fix 2024-03-28 12:39:24 +08:00
Joel 85b45a7cd0 fix: http json value would changed 2024-03-28 11:34:31 +08:00
StyleZhang de3fd0f382 fix 2024-03-27 21:00:53 +08:00
JzoNg db3f38bc2b workflow webapp result modification 2024-03-27 18:42:07 +08:00
StyleZhang d239e6bf0f fix 2024-03-27 17:36:16 +08:00
jyong 9e4b39e19f fix question classifier node type 2024-03-27 17:03:49 +08:00
Yeuoly 078b10a9f0 fix: linter 2024-03-27 16:01:09 +08:00
Yeuoly c70d0546ae sign single step files 2024-03-27 16:00:54 +08:00
JzoNg c3d926e2ed templates filtering 2024-03-27 15:49:33 +08:00
Joel 78a851d240 fix: hide readonly tooltip 2024-03-27 14:47:23 +08:00
Yeuoly 6256a3fadb fix: missing datasets 2024-03-27 14:44:04 +08:00
jyong 8def0f8cf2 Merge remote-tracking branch 'origin/feat/workflow' into feat/workflow 2024-03-27 14:19:38 +08:00
jyong a29d3f2400 fix question classifier issue when llm
is completion mode
2024-03-27 14:19:23 +08:00
Joel 794c57b938 fix: code editor readonly can get focus 2024-03-27 13:49:22 +08:00
Joel 9eff8715fb fix: model params in question classify 2024-03-27 13:38:26 +08:00
Yeuoly e952e01dfe fix: sql 2024-03-27 12:28:07 +08:00
Yeuoly a20d305842 fix: missing agent 2024-03-27 12:26:00 +08:00
Yeuoly 17d1e2e5b7 fix: template transform node output length 2024-03-27 11:51:12 +08:00
Joel 1c05d2ef7f fix: questioin classify memory limit 2024-03-27 11:06:51 +08:00
StyleZhang f9caa09cac fix: empty chat 2024-03-27 10:39:41 +08:00
JzoNg 829a7b0d16 Merge branch 'main' into feat/workflow 2024-03-27 10:33:28 +08:00
JzoNg 83aaacd71d app creation update 2024-03-26 18:53:02 +08:00
Joel a56115a664 chore: message type i18n 2024-03-26 18:07:35 +08:00
Joel b5578c754f fix: var too long 2024-03-26 17:18:23 +08:00
Joel de00245af0 fix: not highlight query block 2024-03-26 17:02:41 +08:00
Joel 2c9d4c8dca feat: value support hights 2024-03-26 16:47:38 +08:00
Joel 1ac96564a0 feat: http node hightlight node 2024-03-26 16:35:53 +08:00
StyleZhang c15677634f merge main 2024-03-26 15:25:02 +08:00
Joel 2dd2c8c358 feat: support url highlight 2024-03-26 15:02:34 +08:00
Joel 8e3be982eb feat: chat memory placeholder 2024-03-26 14:19:50 +08:00
Joel 46f4e61edc fix: tools value too long ui 2024-03-26 13:52:35 +08:00
StyleZhang a35b5e4fff chat restart 2024-03-25 18:42:51 +08:00
StyleZhang 07091c9d33 node panel resize 2024-03-25 18:02:09 +08:00
Joel b3db119146 feat: memory example 2024-03-25 16:36:33 +08:00
Joel 28206cac72 feat: move start output var to vars 2024-03-25 15:51:31 +08:00
Joel 47f2fe591d feat: default fold output 2024-03-25 15:24:33 +08:00
Joel acd0e22b9e feat: handle limit tool var type 2024-03-25 15:00:36 +08:00
Joel 2ebd8d9fdc feat: support var search 2024-03-25 14:30:43 +08:00
Joel b5fe1f7c46 chore: var reference support portal 2024-03-25 11:34:56 +08:00
takatost d7b2fe1e8b update docker compose images verison 2024-03-24 00:14:53 +09:00
takatost fac9459402 add workflow image build 2024-03-23 23:19:33 +09:00
takatost 6cf0e0c242 Merge branch 'main' into feat/workflow 2024-03-23 23:09:36 +09:00
takatost 656bd9257d Merge branch 'feat/workflow-backend' into feat/workflow 2024-03-23 23:09:20 +09:00
Yeuoly 38441c930c fix: tool sort 2024-03-23 17:54:40 +08:00
StyleZhang dafdbfa0fd fix: next step tool icon 2024-03-23 12:15:38 +08:00
JzoNg a264973366 hide log panel in web app 2024-03-22 17:23:40 +08:00
Joel 5843b30a13 feat: support var remove in code node 2024-03-22 15:20:09 +08:00
Joel 340ae3c52f feat: remove var check in start node 2024-03-22 15:10:01 +08:00
StyleZhang 817e16493f checklist 2024-03-22 14:58:11 +08:00
Joel 66cf787755 fix: can remove struct 2024-03-22 14:35:22 +08:00
StyleZhang 4f3872277c all tools 2024-03-22 13:08:28 +08:00
Yeuoly 9b84086bac fix: tool provider icon 2024-03-22 12:43:56 +08:00
JzoNg ce2b2755af add description for workflow 2024-03-22 10:30:20 +08:00
takatost a91bec033d fix bug 2024-03-21 22:04:43 +08:00
JzoNg 096cc74373 hide node info in chat 2024-03-21 19:56:43 +08:00
takatost 34db42ecea fix bug 2024-03-21 18:37:37 +08:00
takatost 34e8d2f6bb add message error record 2024-03-21 18:30:23 +08:00
Joel a771d59b1e fix: model param inner ui 2024-03-21 18:14:12 +08:00
JzoNg 3a00941125 fix style of dataset 2024-03-21 18:08:10 +08:00
StyleZhang 8e9ade14df fix: style 2024-03-21 17:49:12 +08:00
JzoNg a1ec45fdd1 fix style of message log operation 2024-03-21 17:47:23 +08:00
Joel 9295739dc0 fix: model trigger ui 2024-03-21 17:45:45 +08:00
StyleZhang 4afb16844c chat stop 2024-03-21 17:30:59 +08:00
takatost c4e6ed1aa2 optimize codes 2024-03-21 17:12:52 +08:00
takatost 95c5848d05 update workflow app bind datasets 2024-03-21 17:06:45 +08:00
JzoNg 8e56096f83 fix style of nav 2024-03-21 16:58:00 +08:00
Joel c8f51dd6db chore: edit code support line wrap 2024-03-21 16:56:49 +08:00
Joel ebbb30de44 fix: wrong infernece 2024-03-21 16:48:53 +08:00
Joel fe1168d15a feat: code var sync 2024-03-21 16:43:36 +08:00
StyleZhang fd7fded6e5 fix: style 2024-03-21 16:34:56 +08:00
Joel 8cffbc6b2a chore: more info to workflows 2024-03-21 16:23:47 +08:00
Yeuoly fa673f9b4c fix: raw text 2024-03-21 16:21:59 +08:00
Joel 178f1fc5d6 fix: tools var renmae problem 2024-03-21 16:15:50 +08:00
Yeuoly 0c409e2b9e enhance: increase code timeout 2024-03-21 16:14:16 +08:00
StyleZhang e366e12be0 fix: running line 2024-03-21 16:12:55 +08:00
Joel 8e0d8fdb3f feat: other nodes support rename and fix knonw set var bug 2024-03-21 16:06:45 +08:00
StyleZhang 524b19bb3a node style 2024-03-21 15:59:20 +08:00
JzoNg fb2e351c08 fix icons 2024-03-21 15:56:20 +08:00
Yeuoly 260fef40c4 enhance: full tools 2024-03-21 15:40:08 +08:00
takatost 72818e946d fix llm memory 2024-03-21 15:36:25 +08:00
Joel e673c64534 feat: llm rename 2024-03-21 15:23:38 +08:00
Joel 93bbb2694f temp publish not check valid 2024-03-21 15:18:10 +08:00
Joel b038b7aa33 fix: can not choose var type 2024-03-21 15:14:54 +08:00
Joel 02a059bdc6 feat: var name rename struct 2024-03-21 15:07:44 +08:00
StyleZhang 267d9568c6 fix: running status 2024-03-21 15:03:49 +08:00
takatost d71eae8f93 fix qc 2024-03-21 15:02:55 +08:00
StyleZhang 8bdaab96b1 fix 2024-03-21 14:25:11 +08:00
takatost a05fcedd61 fix stop 2024-03-21 14:04:22 +08:00
takatost 0db67a2fd3 fix features not publish 2024-03-21 13:47:10 +08:00
JzoNg 6e56a504fd fix docs for advanced-chat 2024-03-21 12:39:46 +08:00
JzoNg 69fa8c9794 add docs for advanced-chat 2024-03-21 12:36:28 +08:00
JzoNg 8dc8650ecb fix type of workflow process 2024-03-21 09:24:09 +08:00
JzoNg 40775e27ce correct api doc of workflow 2024-03-20 23:46:53 +08:00
JzoNg 6fb294202d modify workflow web app output 2024-03-20 23:07:43 +08:00
Yeuoly bd409a3caf enhance: code node validator 2024-03-20 23:01:24 +08:00
takatost 0d0da9a892 fix variable assigner multi route 2024-03-20 22:49:24 +08:00
takatost a7e2f9caf0 fix variable assigner 2024-03-20 22:27:59 +08:00
Joel 3d4d60a353 feat: llm intput only number and str 2024-03-20 22:00:56 +08:00
Joel 75e876b14e chore: reduce more var limit 2024-03-20 21:56:18 +08:00
Joel 66fd60bc6f fix: var objects sorts change 2024-03-20 21:56:18 +08:00
takatost c3e7299494 fix service api blocking mode 2024-03-20 21:55:06 +08:00
StyleZhang 8fc576870d fix 2024-03-20 20:52:19 +08:00
Joel d4f362164f fix: memory support switch 2024-03-20 20:50:16 +08:00
StyleZhang 94ca0edb68 run history 2024-03-20 20:27:52 +08:00
takatost a0dde6e4da fix bug 2024-03-20 20:02:51 +08:00
Joel 17f572f23f feat: can not add context 2024-03-20 19:35:42 +08:00
StyleZhang 137746387d fix style 2024-03-20 19:24:47 +08:00
JzoNg 9b5deaf80a add proccess of workflow in web app 2024-03-20 18:56:03 +08:00
Joel 1201bef879 chore: picker width set 2024-03-20 18:18:34 +08:00
takatost 30a9b8b917 fix bug 2024-03-20 17:52:47 +08:00
takatost 77bdc6ffb1 fix bug 2024-03-20 17:36:56 +08:00
takatost a65c99496b add extra info for workflow stream output 2024-03-20 17:34:07 +08:00
Joel a8c86b759d fix: var02 icon show 2024-03-20 17:31:46 +08:00
StyleZhang 76081db6e4 fix: style 2024-03-20 17:27:45 +08:00
Joel 0606b6f922 fix: remove datasets problem 2024-03-20 17:23:18 +08:00
Joel 9ed2a99abf feat: var reference support readonly 2024-03-20 17:01:53 +08:00
Joel 8f311b020a feat: tools readonly 2024-03-20 16:56:09 +08:00
Yeuoly de6cbc36bb enhance: code return tyoe 2024-03-20 16:54:32 +08:00
Joel 0aa984219f feat: telmplate transform support readonly 2024-03-20 16:52:01 +08:00
Joel c9168c19cd feat: question classify support readonly 2024-03-20 16:48:52 +08:00
Joel beca05848c feat: llm support readonly 2024-03-20 16:43:00 +08:00
StyleZhang 2e5acef1b6 fix 2024-03-20 16:42:13 +08:00
Joel c4811f921f feat: retrieval support readonly 2024-03-20 16:36:49 +08:00
Joel 7569346943 feat: if support readonly 2024-03-20 16:27:41 +08:00
StyleZhang 2919cc9adf fix 2024-03-20 16:25:02 +08:00
JzoNg 18883d9faa fix agent config 2024-03-20 16:20:19 +08:00
Joel e462ddb805 feat: http support readonly 2024-03-20 16:17:04 +08:00
Joel df274416f9 feat: end support readonly 2024-03-20 16:00:41 +08:00
JzoNg b35d9f6c36 fix style of running workflow 2024-03-20 15:54:21 +08:00
Joel 4c5737fc7f feat: code support readonly 2024-03-20 15:53:14 +08:00
Joel 7bb1decaf8 feat: support prompt readonly 2024-03-20 15:46:21 +08:00
StyleZhang 4bef2eed25 chat add workflow process 2024-03-20 15:44:51 +08:00
takatost 0d2a90adf3 fix knowledge retriever return 2024-03-20 15:43:22 +08:00
Joel 38a1ea139a feat: answer support readonly 2024-03-20 15:32:06 +08:00
Joel 698eb9671f feat: start support readonly 2024-03-20 15:09:12 +08:00
Joel 1b857eba29 chore: remove useless 2024-03-20 14:49:39 +08:00
Joel b060b773ef fix: set default logic error 2024-03-20 14:42:35 +08:00
Joel ae197fb2ba fix: switch provider call infinate 2024-03-20 14:42:35 +08:00
StyleZhang 2697454a8e fix 2024-03-20 14:10:43 +08:00
Joel 2a75258836 feat: not show var 2024-03-20 13:55:26 +08:00
takatost b50f221327 fix bug 2024-03-20 12:47:36 +08:00
Joel d984eb3648 chore: workflow editor not choose outtool in var 2024-03-20 12:05:30 +08:00
Joel 4df8fa0afb feat: if change to defalut operator 2024-03-20 11:42:57 +08:00
Joel 67b3ee3776 feat: ifelse check and item choose var first 2024-03-20 11:35:31 +08:00
takatost 8337e3c6ba fix lint 2024-03-20 11:23:33 +08:00
takatost a9b8917e22 fix bug 2024-03-20 11:23:25 +08:00
JzoNg 70698b553e fix prompt log in completion debug 2024-03-20 11:09:03 +08:00
Joel b131c5dc73 fix: code defalut may not switch if not load config 2024-03-20 10:50:43 +08:00
Joel 15e2ab9203 feat: ifelse not set var not change selector 2024-03-20 10:50:43 +08:00
JzoNg d5c79e0489 fix user-inputs generation 2024-03-20 10:45:30 +08:00
jyong 884eeebe83 fix react response 2024-03-20 04:00:50 +08:00
jyong 9042db301d fix page content is empty 2024-03-20 03:50:28 +08:00
takatost f4f8d6c652 Merge branch 'main' into feat/workflow-backend
# Conflicts:
#	api/core/model_runtime/model_providers/anthropic/llm/llm.py
2024-03-20 00:06:33 +08:00
takatost 20cd3e52d0 fix qc bug 2024-03-19 23:55:06 +08:00
takatost 53fa4ffe73 fix bug 2024-03-19 21:53:24 +08:00
takatost 8acd6f2531 fix bug 2024-03-19 21:10:19 +08:00
takatost 8d8bbc586e fix bug 2024-03-19 20:57:07 +08:00
takatost df4e1339da fix convert bug 2024-03-19 20:51:06 +08:00
takatost 0183651cd5 fix stream output 2024-03-19 20:34:43 +08:00
StyleZhang 9f024835aa chat 2024-03-19 20:34:10 +08:00
jyong 45017f3f35 fix knowledge single retrieve when function call response is none 2024-03-19 20:08:16 +08:00
StyleZhang 089072432e chat log 2024-03-19 19:46:14 +08:00
jyong 6e600bc0dc Merge remote-tracking branch 'origin/feat/workflow-backend' into feat/workflow-backend 2024-03-19 19:41:33 +08:00
jyong 25995eb735 fix knowledge single retrieve when function call response is none 2024-03-19 19:41:18 +08:00
JzoNg 28dc089540 fix style of node tracing 2024-03-19 19:24:36 +08:00
StyleZhang 8967c4c8f6 fix 2024-03-19 19:19:47 +08:00
Yeuoly 3969ed6f69 enhance: check valid JSON 2024-03-19 19:01:09 +08:00
JzoNg 56b025ebdd fix import by DSL 2024-03-19 18:57:57 +08:00
JzoNg aab5566d98 fix app switch 2024-03-19 18:49:51 +08:00
Yeuoly a9e44b1fd2 fix: missing head 2024-03-19 18:38:06 +08:00
takatost bae1bc2e4b fix 2024-03-19 18:37:27 +08:00
StyleZhang b9f58d3c1d Merge branch 'main' into feat/workflow 2024-03-19 18:37:09 +08:00
takatostandtakatost 7c7f3958ff feat: optimize ollama model default parameters (#2894) 2024-03-19 18:36:30 +08:00
Lance MaotakatostOSS-MAOLONGDONG\kaihong <maolongdong@kaihong.com>
85da94aac4 fix incorrect exception raised by api tool which leads to incorrect L… (#2886)
Co-authored-by: OSS-MAOLONGDONG\kaihong <maolongdong@kaihong.com>
2024-03-19 18:36:30 +08:00
Su Yangandtakatost 5350753905 chore: update Qwen model params (#2892) 2024-03-19 18:36:30 +08:00
crazywoolaandtakatost e7895cdc53 chore: update pr template (#2893) 2024-03-19 18:36:30 +08:00
Su Yangandtakatost b84d4bdb85 chore: Update TongYi models prices (#2890) 2024-03-19 18:36:30 +08:00
呆萌闷油瓶andtakatost 66538d8cbd feat:support azure openai llm 0125 version (#2889) 2024-03-19 18:36:30 +08:00
Su Yangandtakatost 4e24e116aa chore: use API Key instead of APIKey (#2888) 2024-03-19 18:36:29 +08:00
Bowen Liangandtakatost 3f13c47b9b Bump tiktoken to 0.6.0 to support text-embedding-3-* in encoding_for_model (#2891) 2024-03-19 18:36:29 +08:00
Su Yangandtakatost 10237c99e4 fix: anthropic system prompt not working (#2885) 2024-03-19 18:36:28 +08:00
Su Yangandtakatost faf936416f fix: Fix the problem of system not working (#2884) 2024-03-19 18:36:14 +08:00
crazywoolaandtakatost 779f77ccd6 feat: add icons for 01.ai (#2883) 2024-03-19 18:36:14 +08:00
Su Yangandtakatost 758b8bf812 i18n: update bedrock label (#2879) 2024-03-19 18:36:14 +08:00
c61f51dc5d feat: AWS Bedrock Claude3 (#2864)
Co-authored-by: crazywoola <427733928@qq.com>
Co-authored-by: Chenhe Gu <guchenhe@gmail.com>
2024-03-19 18:36:14 +08:00
Yeuoly b17e30b1c2 fix: form-data 2024-03-19 18:30:13 +08:00
Joel 0756b09cf5 chore: var assigner output 2024-03-19 18:19:07 +08:00
Yeuoly 2f16b3600c fix: avoid space in http key 2024-03-19 18:13:30 +08:00
Yeuoly 55d2417906 fix: invalid http header 2024-03-19 18:12:50 +08:00
Joel 49dd5b76f1 chore: http remove blank to value 2024-03-19 18:08:09 +08:00
Joel 43429108f5 chore: http files 2024-03-19 18:05:32 +08:00
Joel 18159b1a4b feat: valid assignes 2024-03-19 18:03:54 +08:00
StyleZhang b31da3b195 initial node position 2024-03-19 17:59:35 +08:00
takatost 17b7426cc6 fix external_data_tools bug 2024-03-19 17:58:33 +08:00
Joel ba7b9a595b fix: tool invaild 2024-03-19 17:52:43 +08:00
takatost 7778901630 fix tool image render 2024-03-19 17:49:26 +08:00
JzoNg 8f7356cc12 fix completion log item 2024-03-19 17:37:17 +08:00
Joel d49834ee56 feat: if node valid 2024-03-19 17:33:49 +08:00
Joel e4fdf1730e chore: change output 2024-03-19 17:29:40 +08:00
StyleZhang f41a619490 check before publish 2024-03-19 17:24:35 +08:00
jyong 1607fcfaa7 fix knowledge single retrieve when function call response is none 2024-03-19 17:18:29 +08:00
Yeuoly 8386abaed1 fix: file 2024-03-19 17:07:44 +08:00
JzoNg 16a1562900 fix style of tip modal 2024-03-19 17:06:33 +08:00
Joel 9b1869f521 feat: template transform code valid 2024-03-19 16:58:13 +08:00
Joel 3dfcd9ca67 feat: valid question classify 2024-03-19 16:58:13 +08:00
takatost 74408c4ced fix app convert 2024-03-19 16:44:28 +08:00
JzoNg 653917649d add beta tag and fix some style 2024-03-19 16:43:24 +08:00
JzoNg 00f51749a3 add switch operation in app list 2024-03-19 16:18:22 +08:00
Joel 8d3158a6d5 feat: tool valid 2024-03-19 16:14:25 +08:00
StyleZhang dbaf54c93d chat 2024-03-19 16:04:34 +08:00
takatost 7762737796 optimize app list desc 2024-03-19 15:40:03 +08:00
takatost 133d52deb9 fix bug 2024-03-19 15:32:10 +08:00
StyleZhang 0ede136d67 fix: single run sync draft 2024-03-19 15:30:13 +08:00
Joel 8d82d9f7ef fix: overwrite defalut value in tool 2024-03-19 15:27:33 +08:00
JzoNg 1532564601 modify operations in app list 2024-03-19 15:27:14 +08:00
takatost 24ac4996c0 fix bug 2024-03-19 15:20:03 +08:00
takatost 112593119a fix suggested_questions_after_answer 2024-03-19 15:12:29 +08:00
StyleZhang 0c100ac0b1 fix node 2024-03-19 15:07:13 +08:00
Joel 45168d0e00 remove log 2024-03-19 14:55:11 +08:00
Joel dc91b2e3df fix: retieveal output error and var ref error 2024-03-19 14:54:23 +08:00
StyleZhang ced6a5c18b answer node 2024-03-19 14:50:33 +08:00
JzoNg 0b7cdd1e5d node collapse 2024-03-19 14:47:03 +08:00
Joel 67de047122 fix: http not pass headers and so on 2024-03-19 14:42:54 +08:00
jyong 4ec14d8d91 fix knowledge single retrieve when function call response is none 2024-03-19 14:17:22 +08:00
Joel 09516726e9 fix: overwrite template 2024-03-19 13:58:51 +08:00
Joel 6bfd61a887 feat: retrieval check valid 2024-03-19 13:58:51 +08:00
StyleZhang a436550dff workflow info 2024-03-19 13:50:10 +08:00
StyleZhang f5a3069913 sync draft 2024-03-19 13:18:14 +08:00
JzoNg cf0c96e0d1 fix workflow outputs 2024-03-19 12:34:03 +08:00
Joel 978ee93df7 fix: not show sys var type 2024-03-19 11:54:47 +08:00
Joel f3bf4c7730 feat: code default value 2024-03-19 11:36:29 +08:00
Joel d2de16fba2 fix: var list defalut 2024-03-19 10:57:05 +08:00
Joel 90543c458c feat: valid before run struct 2024-03-19 10:46:28 +08:00
JzoNg d6e655eaae fix restart button 2024-03-19 09:43:39 +08:00
JzoNg 9884466ef0 fix judgement of app configure 2024-03-19 09:33:18 +08:00
JzoNg 3b4676d8e9 fix agent configuration 2024-03-19 08:55:47 +08:00
JzoNg 3ee9f74cf8 fix style of completion creation 2024-03-19 08:02:56 +08:00
takatost 1c7573a686 add logging callback for workflow 2024-03-19 04:37:29 +08:00
takatost 2da7cc6928 fix file bugs 2024-03-19 03:56:47 +08:00
JzoNg fda802e796 chore: remove comments 2024-03-18 22:46:19 +08:00
jyong 5a5beb5b59 Merge remote-tracking branch 'origin/feat/workflow-backend' into feat/workflow-backend 2024-03-18 22:38:27 +08:00
jyong a0b16e541c question classifier 2024-03-18 22:38:12 +08:00
JzoNg a67777b8e2 app overview 2024-03-18 22:32:21 +08:00
Joel eae4c80679 fix: input text error 2024-03-18 22:12:46 +08:00
Yeuoly ac63b5385a fix: set code execution timeout 2024-03-18 22:12:21 +08:00
StyleZhang f61ceadec5 fix 2024-03-18 22:03:26 +08:00
Yeuoly 5ff2fbed59 fix: linter 2024-03-18 22:00:35 +08:00
Yeuoly d24cf9e56a limit http response 2024-03-18 22:00:34 +08:00
Joel 7b9fbccf60 feat: support add files and vision 2024-03-18 21:59:51 +08:00
takatost 0b07c6914a fix bugs 2024-03-18 21:52:39 +08:00
jyong f803fb5855 Merge remote-tracking branch 'origin/feat/workflow-backend' into feat/workflow-backend 2024-03-18 21:51:32 +08:00
jyong cd3c2f6b00 knowledge fix 2024-03-18 21:51:23 +08:00
takatost 587ba27f8c fix bugs 2024-03-18 21:42:45 +08:00
takatost 1b0acdbe63 fix message resign url 2024-03-18 21:22:58 +08:00
jyong 3e810bc490 knowledge fix 2024-03-18 21:22:16 +08:00
Yeuoly cc86850ad9 pure: rm file transformer 2024-03-18 21:17:13 +08:00
Yeuoly fed19db938 feat: http download file 2024-03-18 21:16:21 +08:00
takatost 9175eb455f fix context 2024-03-18 21:11:27 +08:00
StyleZhang a89287bf20 block icon 2024-03-18 21:03:02 +08:00
takatost 977020f580 lint fix 2024-03-18 20:59:22 +08:00
takatost a2195c813c fix file render 2024-03-18 20:59:11 +08:00
jyong d5a404236a knowledge fix 2024-03-18 20:54:50 +08:00
JzoNg 202492e5ac message log style modified 2024-03-18 20:54:18 +08:00
Joel 601e888fde feat: handle sys var to run 2024-03-18 20:40:38 +08:00
jyong 4a483a8754 Merge remote-tracking branch 'origin/feat/workflow-backend' into feat/workflow-backend 2024-03-18 20:35:23 +08:00
jyong a4f367b8ff knowledge fix 2024-03-18 20:35:10 +08:00
Yeuoly e225a3d33c linter 2024-03-18 20:22:25 +08:00
Joel 31b6383697 fix: to new sys vars 2024-03-18 20:12:43 +08:00
Yeuoly e7d6def1e8 fix: trim file extension 2024-03-18 19:59:54 +08:00
Yeuoly 197c0bb1a3 fix: jsonable_encoder 2024-03-18 19:56:38 +08:00
Joel d6953f28d3 chore: remove not necessary config 2024-03-18 19:52:40 +08:00
StyleZhang 249f013ca3 fix 2024-03-18 19:50:55 +08:00
takatost 387a6cfee4 remove answer as end 2024-03-18 19:25:18 +08:00
StyleZhang 81cbf2e713 node prev available nodes 2024-03-18 19:22:58 +08:00
jyong e66c55ba9e fix enable annotation reply when collection is None 2024-03-18 19:21:36 +08:00
Joel 56044a104c remove logs 2024-03-18 19:14:21 +08:00
Joel c409ab4c3c feat: knowledge support one sigle 2024-03-18 18:49:01 +08:00
Yeuoly 487efcb206 fix: support deprecated tools 2024-03-18 18:45:29 +08:00
StyleZhang 4eb7546177 workflow publish 2024-03-18 18:45:24 +08:00
Yeuoly 4b561aec93 feat: workflow statistics 2024-03-18 18:44:27 +08:00
takatost 34695f02fb add model config for conversation 2024-03-18 18:25:46 +08:00
takatost aa421269c4 deduct llm quota use llm node func 2024-03-18 18:01:57 +08:00
takatost 09cfbe117e fix annotation bugs 2024-03-18 17:57:10 +08:00
takatost 0ea233edbe Merge branch 'main' into feat/workflow-backend 2024-03-18 17:20:25 +08:00
takatost d69e0a79d4 fix file upload config internal err 2024-03-18 16:55:15 +08:00
Joel 7320ac41af feat: support context and other var reset 2024-03-18 16:50:52 +08:00
takatost 08b1f5d7c3 fix web app bugs 2024-03-18 16:48:31 +08:00
takatost 61b41ca04b fix retriever resource 2024-03-18 16:38:39 +08:00
JzoNg 8d4f40bc7c fix style of chat message log 2024-03-18 16:37:50 +08:00
Joel 3e9c7dccc0 feat: prompt editor set context status setter 2024-03-18 16:25:20 +08:00
StyleZhang 672b8f14f2 chat 2024-03-18 16:14:05 +08:00
StyleZhang 513d075ebc chat 2024-03-18 16:03:57 +08:00
Joel 8d34082246 feat: llm default 2024-03-18 15:56:37 +08:00
jyong 5ed181dd42 knowledge entities fix 2024-03-18 15:54:59 +08:00
JzoNg 9d8f9f6f63 fix app template list filtering 2024-03-18 15:52:02 +08:00
Joel 8e8c39a88c feat: sys var remove nodeid 2024-03-18 15:46:36 +08:00
jyong 41d9fdee50 Merge remote-tracking branch 'origin/feat/workflow-backend' into feat/workflow-backend 2024-03-18 15:40:26 +08:00
jyong 9e37021387 knowledge entities fix 2024-03-18 15:40:11 +08:00
takatost bf06be0c75 fix migration order 2024-03-18 15:37:23 +08:00
takatost a93a2e2e0c Merge branch 'main' into feat/workflow-backend 2024-03-18 15:35:04 +08:00
takatost 02337cbb09 fix answer message save 2024-03-18 15:07:56 +08:00
StyleZhang c35c0fc6f4 chat upload file 2024-03-18 15:04:32 +08:00
Joel 1482eb0348 feat: generation support vars 2024-03-18 14:57:28 +08:00
JzoNg cbe7116bb7 fix data fetching of app list 2024-03-18 14:54:01 +08:00
StyleZhang 788550affa chat upload file 2024-03-18 14:49:40 +08:00
Joel 25949338cb feat: editor history and query 2024-03-18 14:49:15 +08:00
takatost 958da42f74 fix advanced chat answer 2024-03-18 14:28:07 +08:00
JzoNg 6e8ea528c2 fix loading of run 2024-03-18 14:19:47 +08:00
JzoNg d537efe97a refactor run data fetching 2024-03-18 14:15:29 +08:00
JzoNg 0439276866 add tracing panel 2024-03-18 13:24:27 +08:00
takatost 69c8e4ddd1 fix source handle 2024-03-18 13:11:58 +08:00
JzoNg 711f7107b4 fix merge 2024-03-18 13:11:17 +08:00
StyleZhang ea4476ac6e init edges 2024-03-18 12:49:55 +08:00
Joel 13dbc7f0ce feat: handle questioin classify 2024-03-18 11:26:26 +08:00
Joel b8ecfd859b feat: fill single run form variable with constant value first time 2024-03-18 11:03:23 +08:00
Joel 4daf93ef4f feat: form input var type 2024-03-18 10:52:45 +08:00
Joel 90b7ca1df1 chore: merge main 2024-03-18 10:34:57 +08:00
takatost 96f38b2d15 fix bug 2024-03-18 00:13:34 +08:00
takatost 8a27e51658 add Bad Request when generating 2024-03-17 21:40:59 +08:00
takatost 8ecec84dcf Merge branch 'main' into feat/workflow-backend
# Conflicts:
#	api/core/application_manager.py
2024-03-17 21:38:33 +08:00
takatost a2b3096159 add text chunk subscribe for advanced chat blocking mode 2024-03-17 21:36:22 +08:00
takatost 80f1fbba56 add image file as markdown stream outupt 2024-03-17 21:27:08 +08:00
Yeuoly d8ab611480 fix: code 2024-03-17 21:08:41 +08:00
StyleZhang 722ff7795d insert node 2024-03-17 20:19:58 +08:00
takatost 73c2b35dfe add completion app creation back 2024-03-17 16:30:04 +08:00
Yeuoly b99eadecf6 fix: code template 2024-03-17 16:18:15 +08:00
JzoNg 843db3dbdf fix typo 2024-03-17 15:06:53 +08:00
JzoNg 3b660f1698 chat list api 2024-03-17 15:03:37 +08:00
JzoNg a2e30e6aa9 message log 2024-03-17 14:05:56 +08:00
JzoNg 9638885a67 fix prompt log 2024-03-17 12:41:23 +08:00
StyleZhang cd01c890e1 chat record 2024-03-17 09:53:16 +08:00
StyleZhang 552ccb058b stop & restart 2024-03-17 09:25:19 +08:00
takatost 36180b1001 add model support for kr node single_retrieval_config 2024-03-16 22:22:08 +08:00
takatost 65ed4dc91f refactor recommend app api 2024-03-16 22:13:06 +08:00
takatost c709e339b1 fix route 2024-03-16 18:48:16 +08:00
takatost 3cf8416484 add workflow api for installed app & web api & service api 2024-03-16 16:27:39 +08:00
takatost d2d47d0e0e fix bug 2024-03-16 15:09:47 +08:00
StyleZhang 05f97f6e06 fix chat 2024-03-16 15:00:30 +08:00
takatost 11dfdb236d lint fix 2024-03-16 14:45:39 +08:00
takatost 6df520ebc6 add skip ran node 2024-03-16 14:45:16 +08:00
takatost a047a98462 advanced chat support 2024-03-16 14:30:53 +08:00
jyong 1df68a546e variable assigner node 2024-03-16 01:15:40 +08:00
jyong 5013ea09d5 variable assigner node 2024-03-16 00:54:29 +08:00
jyong d92d952e76 Merge remote-tracking branch 'origin/feat/workflow-backend' into feat/workflow-backend 2024-03-16 00:37:15 +08:00
jyong 4af304e6ae question classifier 2024-03-16 00:36:58 +08:00
takatost 5c4d1c52ee add conversation_id & message_id to advanced-chat workflow-runs API 2024-03-15 22:24:00 +08:00
Joel 5ee7fc4fde feat: tools vars limit 2024-03-15 22:15:36 +08:00
takatost b0cf8c00db add created_at return in publish workflow 2024-03-15 22:08:25 +08:00
Joel 338dd1c714 feat: http var limit 2024-03-15 22:04:07 +08:00
Joel af9ae91934 feat: template transform default 2024-03-15 21:58:56 +08:00
takatost d122daca87 fix conversation filter 2024-03-15 21:56:17 +08:00
Joel ec49da073e feat: code default value 2024-03-15 21:54:16 +08:00
takatost 62846be275 refactor app generate pipeline 2024-03-15 21:42:22 +08:00
Joel 6b9cc927c0 feat: llm default value 2024-03-15 21:41:27 +08:00
StyleZhang a577db9ddd stop run 2024-03-15 21:33:51 +08:00
JzoNg e5c8743712 fix elpased time 2024-03-15 21:15:44 +08:00
Joel 777cca1a09 feat: question classify init 2024-03-15 20:50:55 +08:00
StyleZhang e3c65c072c node value init 2024-03-15 20:26:00 +08:00
StyleZhang 9b069bd3d4 node value form 2024-03-15 20:18:19 +08:00
StyleZhang 56c53d1f07 node value init 2024-03-15 20:18:19 +08:00
JzoNg 6146f24932 fix tip of workflow 2024-03-15 20:15:57 +08:00
JzoNg 9908a8bf1f prompt log 2024-03-15 19:55:33 +08:00
StyleZhang e33260d2e2 node value init 2024-03-15 19:51:46 +08:00
jyong 5713ee5fce Merge remote-tracking branch 'origin/feat/workflow-backend' into feat/workflow-backend
# Conflicts:
#	api/constants/languages.py
#	api/controllers/console/app/app.py
#	api/controllers/console/app/model_config.py
2024-03-15 19:50:50 +08:00
StyleZhang 129a68bb06 auto layout 2024-03-15 19:34:50 +08:00
Joel aff5ab933b feat: knowledge node var init value and limit 2024-03-15 19:22:35 +08:00
JzoNg 4835358f24 modify prompt log 2024-03-15 18:26:56 +08:00
jyongandtakatost 9b57b4c6c8 dataset retrival 2024-03-15 18:22:48 +08:00
jyongandtakatost 785dfc5c00 dataset retrival 2024-03-15 18:22:48 +08:00
takatost 12eb236364 answer stream output support 2024-03-15 18:22:48 +08:00
Yeuolyandtakatost 1cfeb989f7 fix: code default output 2024-03-15 18:22:47 +08:00
Yeuolyandtakatost ede65eca4d fix: tool 2024-03-15 18:22:47 +08:00
Yeuolyandtakatost dc53362506 fix: conversation_id equals to none 2024-03-15 18:22:47 +08:00
Yeuolyandtakatost 74e644be1c fix: linter 2024-03-15 18:22:47 +08:00
Yeuolyandtakatost 6e51ce123c fix: null conversation id 2024-03-15 18:22:47 +08:00
takatost 737321da75 add advanced chat apis support 2024-03-15 18:22:47 +08:00
takatost 72d2f76d24 fix default configs 2024-03-15 18:22:47 +08:00
Yeuolyandtakatost 87a36a1fc8 fix: linter 2024-03-15 18:22:47 +08:00
Yeuolyandtakatost c2ded79cb2 fix: node type 2024-03-15 18:22:47 +08:00
takatost fb6e5bf4d5 fix publish route 2024-03-15 18:22:47 +08:00
Yeuolyandtakatost 6633a92e1a fix: http 2024-03-15 18:22:47 +08:00
takatost 44c4d5be72 add answer output parse 2024-03-15 18:22:47 +08:00
takatost 5a67c09b48 use answer node instead of end in advanced chatbot 2024-03-15 18:22:47 +08:00
Yeuolyandtakatost 0614ddde7d fix: allow None AuthorizationConfig 2024-03-15 18:22:47 +08:00
takatost e5ff06bcb7 fix err typo 2024-03-15 18:22:47 +08:00
Yeuolyandtakatost 6b19ba3bb2 enhance: sandbox-docker-compose 2024-03-15 18:22:47 +08:00
takatost 735b55e61b add if-else node 2024-03-15 18:22:47 +08:00
takatost 7e53625eae fix value type 2024-03-15 18:22:47 +08:00
takatost 5213b0aade add sequence_number for workflow_started event 2024-03-15 18:22:47 +08:00
takatost 2b4b6817a3 record inputs and process data when node failed 2024-03-15 18:22:47 +08:00
takatost da3e1e9d14 add deduct quota for llm node 2024-03-15 18:22:47 +08:00
takatost e4794e309a add llm node test 2024-03-15 18:22:47 +08:00
Yeuolyandtakatost e6572ef2d7 fix: linter 2024-03-15 18:22:47 +08:00
Yeuolyandtakatost 2182533af8 feat: javascript code 2024-03-15 18:22:47 +08:00
takatost d88ac6c238 add llm node 2024-03-15 18:22:47 +08:00
takatost e8751bebfa fix single step run error 2024-03-15 18:22:47 +08:00
Yeuolyandtakatost 92c1da8dbe fix: remove answer 2024-03-15 18:22:47 +08:00
Yeuolyandtakatost 951aaf5161 feat: sandbox 2024-03-15 18:22:47 +08:00
Yeuolyandtakatost a420953385 feat: docker-compose 2024-03-15 18:22:47 +08:00
Yeuolyandtakatost b102562614 fix: forward-ref 2024-03-15 18:22:47 +08:00
Yeuolyandtakatost 2c2b9e7389 test: template transform 2024-03-15 18:22:47 +08:00
Yeuolyandtakatost 513a8655b1 test: tool 2024-03-15 18:22:47 +08:00
Yeuolyandtakatost d3385a2715 feat 2024-03-15 18:22:47 +08:00
Yeuolyandtakatost ebf9c41adb feat: http 2024-03-15 18:22:47 +08:00
jyongandtakatost 7372776992 knowledge node 2024-03-15 18:22:47 +08:00
takatost 7f7269d261 remove unused params in workflow_run_for_list_fields 2024-03-15 18:22:47 +08:00
takatost f2bb0012fd add debug code 2024-03-15 18:22:47 +08:00
takatost 33113034ea add single step run 2024-03-15 18:22:47 +08:00
Yeuolyandtakatost 88c29f613f fix: typing 2024-03-15 18:22:47 +08:00
Yeuolyandtakatost f318fa058c feat: add variable selector mapping 2024-03-15 18:22:47 +08:00
Yeuolyandtakatost 407bfb8182 feat: add user uid 2024-03-15 18:22:47 +08:00
Yeuolyandtakatost 91845fc9f6 fix: linter 2024-03-15 18:22:47 +08:00
Yeuolyandtakatost f911b1c488 feat: support empty code output children 2024-03-15 18:22:47 +08:00
takatost 7a6fa3655f add user for node 2024-03-15 18:22:47 +08:00
Yeuolyandtakatost 5eb7b4d56a feat: tool entity 2024-03-15 18:22:47 +08:00
Yeuolyandtakatost 5e4bd9fc38 feat: tool node 2024-03-15 18:22:47 +08:00
Yeuolyandtakatost f8cba2679e fix: linter 2024-03-15 18:22:47 +08:00
Yeuolyandtakatost e0883302d2 feat: jinja2 2024-03-15 18:22:47 +08:00
takatost a0a1618869 add tenant_id / app_id / workflow_id for nodes 2024-03-15 18:22:47 +08:00
takatost be68369983 add workflow_app_log codes 2024-03-15 18:22:47 +08:00
Yeuolyandtakatost 9d0a832e40 refactor: github actions 2024-03-15 18:22:47 +08:00
Yeuolyandtakatost 8031262006 feat: workflow mock test 2024-03-15 18:22:47 +08:00
takatost 751489fa54 modify readme 2024-03-15 18:22:47 +08:00
Yeuolyandtakatost 1e6feadc7e fix: code node dose not work as expected 2024-03-15 18:22:47 +08:00
takatost 2d8497f79b add readme for db connection management in App Runner and Task Pipeline 2024-03-15 18:22:47 +08:00
takatost 61a1aadf9c optimize workflow db connections 2024-03-15 18:22:47 +08:00
takatost 8b832097de optimize db connections 2024-03-15 18:22:45 +08:00
takatost 7e4daf131e optimize db connections 2024-03-15 18:17:05 +08:00
takatost de3978fdbb optimize db connections 2024-03-15 18:17:05 +08:00
Yeuolyandtakatost 51f6ab49cf fix: linter 2024-03-15 18:17:05 +08:00
Yeuolyandtakatost 2895c3bc8c feat: template transform 2024-03-15 18:17:05 +08:00
Yeuolyandtakatost 3d5f9b5a1e fix: missing _extract_variable_selector_to_variable_mapping 2024-03-15 18:17:05 +08:00
Yeuolyandtakatost 614bc2e075 feat: http reqeust 2024-03-15 18:17:05 +08:00
Yeuolyandtakatost 193bcce236 feat: http request 2024-03-15 18:17:05 +08:00
Yeuolyandtakatost a0fd731170 feat: mapping variables 2024-03-15 18:17:05 +08:00
takatost 2f57d090a1 refactor pipeline and remove node run run_args 2024-03-15 18:17:05 +08:00
Yeuolyandtakatost 4c5822fb6e fix: transform 2024-03-15 18:17:05 +08:00
takatost e90637f67a fix generate bug 2024-03-15 18:17:05 +08:00
Yeuolyandtakatost 9b0f83f807 fix: add max number array length 2024-03-15 18:17:05 +08:00
takatost fc573564b4 refactor workflow runner 2024-03-15 18:17:05 +08:00
Yeuolyandtakatost 5596b3b00b fix: linter 2024-03-15 18:17:05 +08:00
Yeuolyandtakatost cb02b1e12e feat: code 2024-03-15 18:17:05 +08:00
Yeuolyandtakatost 736e386f15 fix: bugs 2024-03-15 18:17:05 +08:00
takatost c152d55f68 fix workflow app bugs 2024-03-15 18:17:05 +08:00
takatost 1a0b6adc2c fix stream bugs 2024-03-15 18:17:05 +08:00
takatost 1914dfea77 fix bugs 2024-03-15 18:17:05 +08:00
takatost 1f986a3abb fix bugs 2024-03-15 18:17:05 +08:00
takatost b174f85237 fix bug 2024-03-15 18:17:05 +08:00
takatost 2ad9c76093 modify migrations 2024-03-15 18:17:05 +08:00
takatost 8684b172d2 add start, end, direct answer node 2024-03-15 18:17:05 +08:00
takatost 3e54cb26be move funcs 2024-03-15 18:17:05 +08:00
takatost 079cc082a3 use callback to filter workflow stream output 2024-03-15 18:17:05 +08:00
takatost a1bc6b50c5 refactor workflow generate pipeline 2024-03-15 18:17:05 +08:00
takatost 7d28fe8ea5 completed workflow engine main logic 2024-03-15 18:17:05 +08:00
takatost dd50deaa43 fix audio voice arg 2024-03-15 18:17:04 +08:00
takatost 79a10e9729 add updated_at to sync workflow api 2024-03-15 18:17:04 +08:00
takatost a5de7b10f3 update ruff check 2024-03-15 18:17:04 +08:00
takatost bc4edbfc2b lint fix 2024-03-15 18:17:04 +08:00
takatost 75f1355d4c add few workflow run codes 2024-03-15 18:17:04 +08:00
takatost 1a86e79d4a lint fix 2024-03-15 18:17:04 +08:00
takatost c8a1f923f5 lint fix 2024-03-15 18:17:04 +08:00
takatost df753e84a3 fix workflow api return 2024-03-15 18:17:04 +08:00
takatost 3086893ee7 fix typo 2024-03-15 18:17:04 +08:00
takatost 242fcf0145 fix typo 2024-03-15 18:17:04 +08:00
takatost de40422205 lint fix 2024-03-15 18:17:04 +08:00
takatost df809ff435 add get default node config 2024-03-15 18:17:04 +08:00
takatost 75559bcbf9 replace block type to node type 2024-03-15 18:17:04 +08:00
takatost d9b8a938c6 use enum instead 2024-03-15 18:17:04 +08:00
takatost e9004a06a5 lint fix 2024-03-15 18:17:04 +08:00
takatost be709d4b84 add AdvancedChatAppGenerateTaskPipeline 2024-03-15 18:17:04 +08:00
takatost 602bc67495 lint fix 2024-03-15 18:17:04 +08:00
takatost e498efce2d refactor app generate 2024-03-15 18:17:04 +08:00
takatost 09dfe80718 add app copy api 2024-03-15 18:17:04 +08:00
takatost 06b05163f6 update app import response 2024-03-15 18:17:04 +08:00
takatost b80092ea12 lint fix 2024-03-15 18:17:04 +08:00
takatost 2eaae6742a lint fix 2024-03-15 18:17:04 +08:00
takatost 3f5d1a79c6 refactor apps 2024-03-15 18:17:04 +08:00
takatost 15c7e0ec2f lint fix 2024-03-15 18:17:04 +08:00
takatost 43b0440358 support workflow features 2024-03-15 18:17:03 +08:00
takatost 9651a208a9 lint fix 2024-03-15 18:15:54 +08:00
takatost 7bff65304f add features structure validate 2024-03-15 18:15:54 +08:00
takatost 8a8882ed8d move workflow_id to app 2024-03-15 18:15:54 +08:00
takatost 9467fe9aa9 lint fix 2024-03-15 18:15:54 +08:00
takatost 799db69e4f refactor app 2024-03-15 18:15:48 +08:00
takatost 896c200211 fix import problem 2024-03-15 18:15:17 +08:00
takatost 3badc4423a fix: wrong default model parameters when creating app 2024-03-15 18:15:17 +08:00
takatost d741527ae4 lint 2024-03-15 18:15:17 +08:00
takatost 77618823a5 add features update api
refactor app model config validation
2024-03-15 18:15:17 +08:00
takatost dd70aeff24 lint fix 2024-03-15 18:15:17 +08:00
takatost 022b7d5dd4 optimize default model exceptions 2024-03-15 18:15:17 +08:00
takatost 11337e51c5 lint fix 2024-03-15 18:15:17 +08:00
takatost 7724d010b6 add app description
add update app api
2024-03-15 18:15:16 +08:00
takatost 124aa9db08 lint fix 2024-03-15 18:15:16 +08:00
takatost 20cf075b2d add workflow runs & workflow node executions api 2024-03-15 18:15:16 +08:00
takatost bf4a5f6b33 lint fix 2024-03-15 18:15:16 +08:00
takatost 03749917f0 add workflow app log api 2024-03-15 18:15:16 +08:00
takatost 7d51d6030b remove publish workflow when app import 2024-03-15 18:15:16 +08:00
takatost 742b87df5e lint fix 2024-03-15 18:15:16 +08:00
takatost a457faa2bf trigger app_model_config_was_updated when app import 2024-03-15 18:15:16 +08:00
takatost 4f50f113dd lint fix 2024-03-15 18:15:16 +08:00
takatost 8b529a3ec7 refactor app api 2024-03-15 18:15:16 +08:00
takatost 84c3ec0ea7 site init move to event handler 2024-03-15 18:15:16 +08:00
takatost c13e8077ba fix agent app converter command 2024-03-15 18:15:16 +08:00
takatost 9f42892b42 lint fix 2024-03-15 18:15:16 +08:00
takatost 27ba5a0bce refactor app mode
add app import and export
2024-03-15 18:15:13 +08:00
takatost 78afba49bf lint fix 2024-03-15 18:13:55 +08:00
takatost a9192bc1c6 make recommended app list api public 2024-03-15 18:13:55 +08:00
takatost 77f04603b3 fix bugs 2024-03-15 18:13:55 +08:00
takatost 34ed5e428c fix bugs 2024-03-15 18:13:55 +08:00
takatost 98cb17e79e lint fix 2024-03-15 18:13:55 +08:00
takatost fce20e483c restore completion app 2024-03-15 18:13:55 +08:00
takatost 97c4733e79 lint fix 2024-03-15 18:13:55 +08:00
takatost 748aa22ee2 add manual convert logic 2024-03-15 18:13:55 +08:00
takatost 2ba7ac8bc1 add expert mode of chatapp convert command 2024-03-15 18:13:55 +08:00
takatost 7458fde5a5 add agent app convert command 2024-03-15 18:13:55 +08:00
takatost f11bf9153d add more tests 2024-03-15 18:13:55 +08:00
takatost 0806b3163a add to http request node convert tests 2024-03-15 18:13:55 +08:00
takatost 45621ba4d7 add api extension to http request node convert 2024-03-15 18:13:55 +08:00
takatost 6aecf42b6e fix prompt transform bugs 2024-03-15 18:13:55 +08:00
takatost 3b234febf5 fix bugs and add unit tests 2024-03-15 18:13:55 +08:00
takatost 8642354a2a lint 2024-03-15 18:13:55 +08:00
takatost c028e5f889 add app convert codes 2024-03-15 18:13:55 +08:00
takatost 3642dd3a73 add workflow logics 2024-03-15 18:13:55 +08:00
takatost 603b1e9ed4 lint 2024-03-15 18:13:55 +08:00
takatost b7c6cba23f add workflow models 2024-03-15 18:13:55 +08:00
takatost d430136f65 lint 2024-03-15 18:13:55 +08:00
takatost 381b3d5016 optimize get app model to wraps 2024-03-15 18:13:55 +08:00
Joel e3f1e143e5 feat: llm context type limit 2024-03-15 18:03:01 +08:00
Joel 9f1cbb2ee7 feat: answer node input limit 2024-03-15 18:03:01 +08:00
StyleZhang d0ef9e672f llm mode 2024-03-15 17:57:46 +08:00
Joel b5c212f575 feat: parse to right datatype and show parse json error 2024-03-15 17:42:00 +08:00
Joel ff5ab43f9c feat: check before run 2024-03-15 17:42:00 +08:00
StyleZhang 68f947c7e0 stop workflow run 2024-03-15 17:24:40 +08:00
StyleZhang e98456b025 store 2024-03-15 16:58:48 +08:00
Joel 75b332695b feat: support string num seletor to single run debug 2024-03-15 16:37:58 +08:00
jyong 3e4bb695e4 dataset retrival 2024-03-15 16:14:32 +08:00
Joel 7ba1b37a5a feat: show assigner panel 2024-03-15 15:23:27 +08:00
Joel 2886255c8b fix: can not get first var type 2024-03-15 15:10:41 +08:00
Joel f7a9564e11 feat: can noe choose selected nodes 2024-03-15 14:44:48 +08:00
jyong c1b0f115d0 dataset retrival 2024-03-15 14:40:53 +08:00
StyleZhang 2203d9a138 available nodes 2024-03-15 14:40:44 +08:00
Joel 5adf94bd7d feat: support filter obj select type 2024-03-15 14:01:25 +08:00
StyleZhang 5fbf8ee6c6 available nodes 2024-03-15 13:24:29 +08:00
Joel 8d9c86ac4c fix: advance setting error 2024-03-15 11:47:53 +08:00
Joel 946ef4c685 chore: remove uselsee lang 2024-03-15 11:31:48 +08:00
Joel c3773bc2d1 chore: add language placeholder 2024-03-15 11:30:39 +08:00
Joel 1b8c8b0a43 feat: node before and after run 2024-03-15 11:26:19 +08:00
StyleZhang 86d2c1184c Merge branch 'main' into feat/workflow 2024-03-15 11:17:18 +08:00
StyleZhang 817aea9f05 fix 2024-03-15 11:04:34 +08:00
StyleZhang 985c07b25b fix 2024-03-15 11:01:47 +08:00
StyleZhang 05ac27dfa8 fix 2024-03-14 21:07:59 +08:00
JzoNg bcce53a929 web app support workflow 2024-03-14 21:02:15 +08:00
JzoNg 58922ba40b add route for workflow app 2024-03-14 21:02:15 +08:00
takatost e6b8b13f2e answer stream output support 2024-03-14 20:50:03 +08:00
Joel ac675c4443 feat: add checkvalid empty fn 2024-03-14 20:44:51 +08:00
Joel ae6a558662 feat: add prev and next nodes 2024-03-14 20:29:47 +08:00
Joel 64e44d1709 chore: direct answer to answer 2024-03-14 19:58:17 +08:00
Yeuoly f35ae2355f fix: code default output 2024-03-14 19:17:27 +08:00
Joel 3a857c83e6 chore: only show has value node in end 2024-03-14 18:46:30 +08:00
Joel d9edcb2250 feat: change to new end node 2024-03-14 18:43:04 +08:00
StyleZhang d129d7951c fix 2024-03-14 18:27:58 +08:00
Joel 5c246285da feat: support node type filter 2024-03-14 17:58:26 +08:00
StyleZhang 19c1722032 node default value 2024-03-14 17:27:42 +08:00
Joel cd9a58231b fix: tool show 2024-03-14 16:40:21 +08:00
Yeuoly d85b5b9134 fix: tool 2024-03-14 16:38:22 +08:00
Joel 8bd74d5abf feat: var picker support choose type 2024-03-14 16:04:15 +08:00
StyleZhang 2af2e2be67 node add 2024-03-14 15:14:31 +08:00
Joel 43a3b827a3 chore: stringify output 2024-03-14 13:43:13 +08:00
Joel 3c6de0bf3e feat: tool default value 2024-03-14 13:43:13 +08:00
Yeuoly 13a724864d fix: conversation_id equals to none 2024-03-14 13:24:48 +08:00
Yeuoly baf536eb2b fix: linter 2024-03-14 12:57:14 +08:00
Yeuoly 5200668336 fix: null conversation id 2024-03-14 12:57:14 +08:00
JzoNg 7eeffb16e2 fix url of webapp 2024-03-14 12:35:12 +08:00
JzoNg 300909341e use app store in overview 2024-03-14 12:27:54 +08:00
JzoNg 277d21cccb fix webapp url 2024-03-14 12:22:08 +08:00
takatost de184051f0 add advanced chat apis support 2024-03-14 12:17:15 +08:00
takatost 95ee72556f fix default configs 2024-03-14 12:12:38 +08:00
Yeuoly f48364914b fix: linter 2024-03-14 11:59:43 +08:00
Yeuoly 19df70efad fix: node type 2024-03-14 11:59:43 +08:00
StyleZhang 9813609645 publish 2024-03-14 11:48:58 +08:00
takatost 975d0a1651 fix publish route 2024-03-14 11:39:18 +08:00
Yeuoly 3c3571713e fix: http 2024-03-14 11:35:51 +08:00
JzoNg aa6254a3b4 add doc for workflow app 2024-03-14 11:31:31 +08:00
JzoNg 0b05d2939a add doc for workflow 2024-03-14 11:31:31 +08:00
JzoNg 6f33163f88 fix app siderbar hook 2024-03-14 11:31:31 +08:00
JzoNg 93101b4d9a add running state for step run 2024-03-14 11:31:31 +08:00
JzoNg d8222a15ca remove useless comments 2024-03-14 11:31:31 +08:00
JzoNg 1728513634 fix sequence number and tokens in result panel 2024-03-14 11:31:31 +08:00
Joel 68fa81ec82 chore: change tool input types 2024-03-14 11:25:27 +08:00
Joel c051c89176 chore: fix http i18n 2024-03-14 11:25:27 +08:00
StyleZhang 8b2a63e545 fix 2024-03-14 11:19:50 +08:00
takatost fcd470fcac add answer output parse 2024-03-13 23:00:28 +08:00
takatost fd8fe15d28 use answer node instead of end in advanced chatbot 2024-03-13 20:54:23 +08:00
Yeuoly e80315f504 fix: allow None AuthorizationConfig 2024-03-13 20:40:37 +08:00
Joel ae9e7acd77 feat: other node run 2024-03-13 18:49:22 +08:00
Joel 149eb38e84 feat: tool single run 2024-03-13 18:43:43 +08:00
Joel d777184fd5 feat: http run 2024-03-13 18:33:08 +08:00
Joel 1653e5eebe feat: template transform 2024-03-13 18:05:17 +08:00
takatost 1f4826ca01 fix err typo 2024-03-13 18:02:19 +08:00
Yeuoly ef700b2688 enhance: sandbox-docker-compose 2024-03-13 17:46:42 +08:00
Joel cedc1bada2 fix: temple transform query selec can not choose var 2024-03-13 17:17:28 +08:00
takatost 0c709afe5c add if-else node 2024-03-13 17:10:51 +08:00
StyleZhang 1c5d07871f hooks 2024-03-13 17:07:03 +08:00
StyleZhang e11fc8c131 init 2024-03-13 17:07:03 +08:00
Joel 2edef89a8d feat: handle system var 2024-03-13 16:38:24 +08:00
StyleZhang cbe7de58ab backup draft 2024-03-13 16:27:04 +08:00
Joel 801160c430 feat: tool output vars 2024-03-13 16:18:46 +08:00
Joel cb2a814296 feat: assign output 2024-03-13 15:58:03 +08:00
Joel db78b91ec2 feat: http output 2024-03-13 15:58:02 +08:00
Joel 25a11c5bb7 feat: question classify output 2024-03-13 15:58:02 +08:00
StyleZhang 1f41521c21 workflow run 2024-03-13 15:38:56 +08:00
Joel e686d42262 feat: support template transform output var 2024-03-13 15:21:51 +08:00
Joel 9bca3f8fd7 feat: code support output var list 2024-03-13 15:17:03 +08:00
takatost 6ef3542c6c fix value type 2024-03-13 15:08:15 +08:00
takatost db299a876e add sequence_number for workflow_started event 2024-03-13 15:01:02 +08:00
takatost 737d04361b record inputs and process data when node failed 2024-03-13 14:55:56 +08:00
Joel 0d2366b432 feat: knowledge output var 2024-03-13 14:52:32 +08:00
Joel b13345ceb2 chore: remove useless and node filter 2024-03-13 14:41:11 +08:00
Joel f15dce9ee3 feat: llm output and var type 2024-03-13 14:37:58 +08:00
StyleZhang b718e66b26 fix: drag stop & click 2024-03-13 13:59:57 +08:00
StyleZhang a55a7603dd split hooks 2024-03-13 11:53:49 +08:00
Joel 64fa343d16 chore: remove log 2024-03-13 11:24:20 +08:00
Joel 6b02eebe36 feat: support start node vars 2024-03-13 11:22:59 +08:00
Joel d0f5318b75 feat: code node can run 2024-03-13 10:43:18 +08:00
takatost 5fe0d50cee add deduct quota for llm node 2024-03-13 00:08:13 +08:00
takatost 4d7caa3458 add llm node test 2024-03-12 23:08:23 +08:00
Yeuoly 856466320d fix: linter 2024-03-12 22:42:28 +08:00
Yeuoly 3bd53556ca feat: javascript code 2024-03-12 22:41:59 +08:00
JzoNg c74854aec0 icon fix 2024-03-12 22:24:23 +08:00
JzoNg 294128d43a fix tracing 2024-03-12 22:21:45 +08:00
takatost 3f59a579d7 add llm node 2024-03-12 22:12:03 +08:00
JzoNg e5cf4ea60e fix result panel 2024-03-12 21:40:41 +08:00
JzoNg 768ca2d3f0 add panel of result 2024-03-12 21:05:15 +08:00
JzoNg 92e9b1bbb1 update style of app list 2024-03-12 21:05:15 +08:00
JzoNg 446932e076 update style of app creation 2024-03-12 21:05:15 +08:00
StyleZhang 0469edcc0c fix 2024-03-12 21:03:45 +08:00
Joel 3823ae5890 chore: prompt to promt template 2024-03-12 20:05:42 +08:00
Joel 14d71fb598 feat: var picker get vars 2024-03-12 20:03:35 +08:00
Joel a031507443 feat: code show result 2024-03-12 19:45:45 +08:00
takatost 4f5c052dc8 fix single step run error 2024-03-12 19:15:11 +08:00
StyleZhang 90e013554c fix 2024-03-12 18:47:24 +08:00
Joel 30ea3cb702 feat: can run code node 2024-03-12 17:59:14 +08:00
StyleZhang a5147a382d fix 2024-03-12 17:44:45 +08:00
Joel 74bf6cd186 feat: add single run api 2024-03-12 16:26:30 +08:00
Yeuoly 15ddbb5e6f fix: remove answer 2024-03-12 16:25:07 +08:00
StyleZhang 547df0b5fe fix 2024-03-12 15:04:52 +08:00
StyleZhang 8ae46a8a14 fix 2024-03-12 13:25:57 +08:00
StyleZhang 9753077661 fix 2024-03-12 13:03:39 +08:00
StyleZhang 22e7393b9d fix 2024-03-12 11:56:15 +08:00
Yeuoly 943c676768 feat: sandbox 2024-03-11 22:14:28 +08:00
Yeuoly 4ecfe1fec5 feat: docker-compose 2024-03-11 22:12:13 +08:00
Yeuoly 5fac4f8737 fix: forward-ref 2024-03-11 21:58:54 +08:00
Yeuoly a5394fa2ce test: template transform 2024-03-11 21:53:08 +08:00
Yeuoly 8dc4d122b9 test: tool 2024-03-11 21:53:08 +08:00
StyleZhang 0eb482f35b chat workflow run 2024-03-11 21:05:54 +08:00
StyleZhang bd52937c88 chat workflow run 2024-03-11 20:54:29 +08:00
jyong d5b321af3f Merge remote-tracking branch 'origin/feat/workflow-backend' into feat/workflow-backend 2024-03-11 20:06:49 +08:00
jyong f3b46bf7e2 knowledge node 2024-03-11 20:06:38 +08:00
Yeuoly 2008986f83 feat 2024-03-11 19:51:31 +08:00
Yeuoly 1a57951d72 feat: http 2024-03-11 19:51:06 +08:00
StyleZhang 7655d7f662 run 2024-03-11 19:35:06 +08:00
takatost 373857d0f2 remove unused params in workflow_run_for_list_fields 2024-03-11 19:04:48 +08:00
takatost 6719af9ba9 add debug code 2024-03-11 18:52:24 +08:00
takatost 19c9091d5b add single step run 2024-03-11 18:49:58 +08:00
StyleZhang 84e2071a32 run 2024-03-11 18:11:01 +08:00
Joel b3b9e1dabb feat: tools support run 2024-03-11 17:33:17 +08:00
Yeuoly 91a35ded18 fix: typing 2024-03-11 16:51:27 +08:00
Yeuoly 2d68594a86 feat: add variable selector mapping 2024-03-11 16:48:28 +08:00
Yeuoly f3d19f9691 feat: add user uid 2024-03-11 16:46:11 +08:00
Yeuoly 94047de8b4 fix: linter 2024-03-11 16:44:36 +08:00
Yeuoly 1c450e27d3 feat: support empty code output children 2024-03-11 16:44:22 +08:00
Joel c0ccffa1c3 chore: no var not show var group 2024-03-11 16:43:13 +08:00
takatost bbc76cb833 add user for node 2024-03-11 16:31:43 +08:00
Yeuoly 94f3cf1a4c feat: tool entity 2024-03-11 16:13:52 +08:00
Joel 2aa8847b78 mrege main 2024-03-11 14:54:29 +08:00
StyleZhang 049e858ef7 run 2024-03-11 14:43:50 +08:00
Yeuoly 8e491ace5c feat: tool node 2024-03-11 13:54:11 +08:00
Yeuoly dcf9d85e8d fix: linter 2024-03-10 21:12:07 +08:00
Yeuoly 460c0da176 feat: jinja2 2024-03-10 20:24:16 +08:00
takatost 295a248561 add tenant_id / app_id / workflow_id for nodes 2024-03-10 20:15:49 +08:00
takatost 4630f9c746 add workflow_app_log codes 2024-03-10 20:02:19 +08:00
Yeuoly ba66beb487 refactor: github actions 2024-03-10 18:41:49 +08:00
Yeuoly b5cb38641a feat: workflow mock test 2024-03-10 18:41:25 +08:00
takatost 4b37d30c0d modify readme 2024-03-10 18:02:05 +08:00
Yeuoly 59ba7917c4 fix: code node dose not work as expected 2024-03-10 17:55:24 +08:00
takatost 8d0ff01a59 add readme for db connection management in App Runner and Task Pipeline 2024-03-10 17:11:39 +08:00
takatost 100fb0c5d6 optimize workflow db connections 2024-03-10 16:59:17 +08:00
takatost b75cd2514e optimize db connections 2024-03-10 16:29:55 +08:00
takatost 7693ba8797 optimize db connections 2024-03-10 15:55:14 +08:00
takatost 3d6b06696e optimize db connections 2024-03-10 15:55:14 +08:00
Yeuolyandtakatost 0386061fdf fix: linter 2024-03-10 15:55:14 +08:00
Yeuolyandtakatost 3407b4d8dd feat: template transform 2024-03-10 15:55:14 +08:00
Yeuolyandtakatost 71ff2a8356 fix: missing _extract_variable_selector_to_variable_mapping 2024-03-10 15:55:14 +08:00
Yeuolyandtakatost 8b809b8004 feat: http reqeust 2024-03-10 15:55:14 +08:00
Yeuolyandtakatost 707a3a0a66 feat: http request 2024-03-10 15:55:14 +08:00
Yeuolyandtakatost b798aa915c feat: mapping variables 2024-03-10 15:55:14 +08:00
takatost 2db67c4101 refactor pipeline and remove node run run_args 2024-03-10 15:55:14 +08:00
Yeuolyandtakatost 80b4db08dc fix: transform 2024-03-10 15:55:14 +08:00
takatost 37cdee5101 fix generate bug 2024-03-10 15:55:14 +08:00
Yeuolyandtakatost b5366cba03 fix: add max number array length 2024-03-10 15:55:14 +08:00
takatost 6cfda369ef refactor workflow runner 2024-03-10 15:55:14 +08:00
Yeuolyandtakatost 5a57ed2536 fix: linter 2024-03-10 15:55:14 +08:00
Yeuolyandtakatost 13937fc103 feat: code 2024-03-10 15:55:14 +08:00
Yeuolyandtakatost 17cd512284 fix: bugs 2024-03-10 15:55:14 +08:00
takatost 97398ff209 fix workflow app bugs 2024-03-10 15:55:14 +08:00
takatost 2ffb63ff0c fix stream bugs 2024-03-10 15:55:14 +08:00
takatost 90bcb241cc fix bugs 2024-03-10 15:55:14 +08:00
takatost f4f7cfd45a fix bugs 2024-03-10 15:55:14 +08:00
takatost d214c047e9 fix bug 2024-03-10 15:55:14 +08:00
takatost fee8a86880 modify migrations 2024-03-10 15:55:14 +08:00
takatost ea883b5e48 add start, end, direct answer node 2024-03-10 15:55:14 +08:00
takatost 46296d777c move funcs 2024-03-10 15:55:14 +08:00
takatost 79f0e894e9 use callback to filter workflow stream output 2024-03-10 15:55:14 +08:00
takatost 6372183471 refactor workflow generate pipeline 2024-03-10 15:55:14 +08:00
takatost 5963e7d1c5 completed workflow engine main logic 2024-03-10 15:55:14 +08:00
takatost c7618fc377 fix audio voice arg 2024-03-10 15:55:14 +08:00
takatost 3fc932b041 add updated_at to sync workflow api 2024-03-10 15:55:14 +08:00
takatost 97cdc96f7c update ruff check 2024-03-10 15:55:14 +08:00
takatost 892fe927c2 lint fix 2024-03-10 15:55:14 +08:00
takatost d51d456d80 add few workflow run codes 2024-03-10 15:55:14 +08:00
takatost 836376c6c8 lint fix 2024-03-10 15:55:14 +08:00
takatost fa29eadb7a lint fix 2024-03-10 15:55:14 +08:00
takatost 0cc0065f8c fix workflow api return 2024-03-10 15:55:14 +08:00
takatost c3eac450ce fix typo 2024-03-10 15:55:14 +08:00
takatost 7b738e045e fix typo 2024-03-10 15:55:14 +08:00
takatost 3f6c17247f lint fix 2024-03-10 15:55:14 +08:00
takatost 0551a9bfcd add get default node config 2024-03-10 15:55:14 +08:00
takatost 7c149ebf4f replace block type to node type 2024-03-10 15:55:14 +08:00
takatost 37b70eb73e use enum instead 2024-03-10 15:55:14 +08:00
takatost 451ea5308f lint fix 2024-03-10 15:55:14 +08:00
takatost a4d6954d4f add AdvancedChatAppGenerateTaskPipeline 2024-03-10 15:55:14 +08:00
takatost c786533f22 lint fix 2024-03-10 15:55:13 +08:00
takatost 406a625c98 refactor app generate 2024-03-10 15:55:13 +08:00
takatost 171b2bdc20 add app copy api 2024-03-10 15:55:13 +08:00
takatost 4266ce73cb update app import response 2024-03-10 15:55:13 +08:00
takatost afa920cc94 lint fix 2024-03-10 15:55:13 +08:00
takatost 701f116be3 lint fix 2024-03-10 15:55:13 +08:00
takatost 5c7ea08bdf refactor apps 2024-03-10 15:55:12 +08:00
takatost 5e38996222 lint fix 2024-03-10 15:54:10 +08:00
takatost 18febeabd1 support workflow features 2024-03-10 15:54:10 +08:00
takatost be1500bf7d lint fix 2024-03-10 15:54:10 +08:00
takatost fea549679a add features structure validate 2024-03-10 15:54:10 +08:00
takatost 11e1b569ea move workflow_id to app 2024-03-10 15:54:10 +08:00
takatost 2bbf96d762 lint fix 2024-03-10 15:54:10 +08:00
takatost 70394bae52 refactor app 2024-03-10 15:54:08 +08:00
takatost 0c9e112f41 fix import problem 2024-03-10 15:52:45 +08:00
takatost 607b84d929 fix: wrong default model parameters when creating app 2024-03-10 15:52:45 +08:00
takatost 7a13cd1530 lint 2024-03-10 15:52:45 +08:00
takatost 9b1afb68eb add features update api
refactor app model config validation
2024-03-10 15:52:45 +08:00
takatost cf9d2965bf lint fix 2024-03-10 15:52:45 +08:00
takatost b1328c193b optimize default model exceptions 2024-03-10 15:52:45 +08:00
takatost 3d222caaae lint fix 2024-03-10 15:52:45 +08:00
takatost 77ac6fa356 add app description
add update app api
2024-03-10 15:52:45 +08:00
takatost a3b46006a8 lint fix 2024-03-10 15:52:45 +08:00
takatost ea4716d039 add workflow runs & workflow node executions api 2024-03-10 15:52:45 +08:00
takatost db9e7a53f8 lint fix 2024-03-10 15:52:45 +08:00
takatost 4432e055be add workflow app log api 2024-03-10 15:52:45 +08:00
takatost 403c2f436d remove publish workflow when app import 2024-03-10 15:52:45 +08:00
takatost 594de43dec lint fix 2024-03-10 15:52:45 +08:00
takatost 2e68c3fc11 trigger app_model_config_was_updated when app import 2024-03-10 15:52:45 +08:00
takatost 2187f6f62e lint fix 2024-03-10 15:52:45 +08:00
takatost 9249c38bf9 refactor app api 2024-03-10 15:52:44 +08:00
takatost 67e0ba5167 site init move to event handler 2024-03-10 15:52:10 +08:00
takatost 9004d8c3cd fix agent app converter command 2024-03-10 15:52:10 +08:00
takatost 4df424438d lint fix 2024-03-10 15:52:10 +08:00
takatost 6e3cd62e31 refactor app mode
add app import and export
2024-03-10 15:52:09 +08:00
takatost 61b4bedc16 lint fix 2024-03-10 15:51:36 +08:00
takatost 4e5de036c6 make recommended app list api public 2024-03-10 15:51:36 +08:00
takatost 8e54b2e3f2 fix bugs 2024-03-10 15:51:36 +08:00
takatost d39a51c134 fix bugs 2024-03-10 15:51:36 +08:00
takatost 6efc3d4913 lint fix 2024-03-10 15:51:35 +08:00
takatost 55c31eec31 restore completion app 2024-03-10 15:51:35 +08:00
takatost 9820dcb201 lint fix 2024-03-10 15:51:35 +08:00
takatost 9f29ce9591 add manual convert logic 2024-03-10 15:51:35 +08:00
takatost afb0ff37bd add expert mode of chatapp convert command 2024-03-10 15:51:35 +08:00
takatost 67b6f08d89 add agent app convert command 2024-03-10 15:51:35 +08:00
takatost 892036bd7d add more tests 2024-03-10 15:51:35 +08:00
takatost d123ddedc8 add to http request node convert tests 2024-03-10 15:51:35 +08:00
takatost fc243982e5 add api extension to http request node convert 2024-03-10 15:51:35 +08:00
takatost df66cd2205 fix prompt transform bugs 2024-03-10 15:51:35 +08:00
takatost a44d3c3eda fix bugs and add unit tests 2024-03-10 15:51:35 +08:00
takatost 297b33aa41 lint 2024-03-10 15:51:35 +08:00
takatost 0d858cc036 add app convert codes 2024-03-10 15:51:35 +08:00
takatost f067947266 add workflow logics 2024-03-10 15:51:35 +08:00
takatost 9ad6bd78f5 lint 2024-03-10 15:51:35 +08:00
takatost b1e220f2d2 add workflow models 2024-03-10 15:51:35 +08:00
takatost 200dc56c37 lint 2024-03-10 15:51:35 +08:00
takatost 49992925e2 optimize get app model to wraps 2024-03-10 15:51:33 +08:00
JzoNg 405e99d27f fix api url of workflow run 2024-03-09 13:03:22 +08:00
JzoNg 90ee7fe201 tracing 2024-03-09 12:48:14 +08:00
JzoNg bc90fc885f tracing node style update 2024-03-09 11:06:25 +08:00
JzoNg 5afa5fb085 app switch 2024-03-09 10:30:26 +08:00
JzoNg 93e2dc4f5f workflow log result 2024-03-08 21:10:11 +08:00
StyleZhang 08d2a4279f cache toolsmap 2024-03-08 18:36:48 +08:00
StyleZhang d79b686992 block selector 2024-03-08 18:10:30 +08:00
Joel 1adec7ab51 feat: tool auth 2024-03-08 17:13:24 +08:00
Joel 3b029f2387 feat: tool auth 2024-03-08 17:13:24 +08:00
JzoNg 6d6afe8f52 fix app mode in logs 2024-03-08 17:11:33 +08:00
StyleZhang e307947dd8 node control 2024-03-08 17:02:02 +08:00
JzoNg 04ad1eef79 workflow logs 2024-03-08 16:43:41 +08:00
StyleZhang 2b475b7916 help line 2024-03-08 16:02:28 +08:00
Joel f51f4a5843 feat: tool inputs 2024-03-08 15:43:11 +08:00
JzoNg b5f3bbead2 update cache in appNav after app info updated 2024-03-08 14:48:10 +08:00
Joel a192ae9314 feat: remove useless file 2024-03-08 14:37:29 +08:00
Joel 7a07d8c2bc feat: tool params 2024-03-08 14:32:33 +08:00
StyleZhang 17a67e7922 remove annatation 2024-03-08 13:46:14 +08:00
StyleZhang 328a3e2e6b node about author 2024-03-08 13:24:59 +08:00
JzoNg 597053c30e fix style of app info 2024-03-08 11:46:25 +08:00
JzoNg 29bef1e3ab app sidebar auto collapse 2024-03-08 11:46:25 +08:00
JzoNg e36d62f08c hide switch modal 2024-03-08 11:46:25 +08:00
JzoNg 50b4c7fa18 switch app 2024-03-08 11:46:25 +08:00
JzoNg d86ef15d9a add tip for switch 2024-03-08 11:46:25 +08:00
JzoNg fa3eb11b6a old app do not support duplicate and export dsl 2024-03-08 11:46:25 +08:00
JzoNg beff31b003 update style app config 2024-03-08 11:46:25 +08:00
StyleZhang 2360fb293b update data 2024-03-08 11:27:05 +08:00
Joel 1c82e3870a feat: not choose model hide in node 2024-03-08 11:06:32 +08:00
Joel 49ce9d2200 feat: http support debug and remove mock init debug data 2024-03-08 10:59:49 +08:00
Joel c20c9b53e1 feat: template tranform support debug 2024-03-08 10:40:12 +08:00
Joel 89fc90ac80 chore: code support debug 2024-03-08 10:36:57 +08:00
StyleZhang 072f5caa06 init 2024-03-07 19:43:11 +08:00
Joel 783f7a9b13 feat: question classifer support run 2024-03-07 18:43:19 +08:00
Joel 425e162a91 feat: knowledge support single run 2024-03-07 18:36:45 +08:00
Joel 55b5d76e0b chore: move node run data to node hooks 2024-03-07 18:13:56 +08:00
Joel 9693d014ba feat: add llm debug 2024-03-07 17:48:18 +08:00
StyleZhang 16abcf082c node control 2024-03-07 17:09:04 +08:00
StyleZhang 173336f256 node handle 2024-03-07 15:58:46 +08:00
Joel f37316f2a0 feat: single run modal 2024-03-07 15:15:39 +08:00
StyleZhang e044e8efaa chat mode 2024-03-07 14:35:13 +08:00
StyleZhang af99a55552 chat mode 2024-03-07 14:24:27 +08:00
StyleZhang 8f3d9d0149 panel 2024-03-07 13:54:02 +08:00
StyleZhang 344e30bef4 node 2024-03-07 12:15:51 +08:00
StyleZhang 45ef4059f0 block-icon 2024-03-07 11:48:42 +08:00
StyleZhang 13174aac18 debug and preview 2024-03-07 11:21:59 +08:00
StyleZhang 74f02363f4 record 2024-03-07 10:48:11 +08:00
Joel 10c421a94c Merge branch 'main' into feat/workflow 2024-03-07 10:35:05 +08:00
StyleZhang 3162227b54 features 2024-03-06 19:43:47 +08:00
JzoNg 7e647cc6e7 fix page title update 2024-03-06 19:14:25 +08:00
StyleZhang ec710d7ffd Merge branch 'main' into feat/workflow 2024-03-06 19:05:21 +08:00
StyleZhang 36718c39dc features 2024-03-06 19:04:06 +08:00
JzoNg fca9753140 fix app detail update 2024-03-06 18:42:37 +08:00
Joel 0529c3d5d2 feat: add role tooltip and fix add prompt error 2024-03-06 18:36:35 +08:00
Joel 5a27a95f8d feat: llm support type select 2024-03-06 18:11:14 +08:00
Joel 5ec3a967b5 feat: all other code expand 2024-03-06 17:59:58 +08:00
StyleZhang a45ec15a56 features 2024-03-06 17:48:01 +08:00
StyleZhang 0164dec438 features 2024-03-06 17:46:42 +08:00
JzoNg 4edaa95cbf app menu 2024-03-06 17:39:27 +08:00
JzoNg 067e6b5ae7 app detail redirection 2024-03-06 17:39:27 +08:00
Joel 6adb986167 feat: expend toggle 2024-03-06 16:56:18 +08:00
Joel cc4ca942c9 feat: prompt editor blur and focus ui 2024-03-06 15:38:45 +08:00
Joel 3202f12cb8 feat: config prompt 2024-03-06 15:17:51 +08:00
StyleZhang 6448d71ca6 draft updated at 2024-03-06 14:35:47 +08:00
StyleZhang e3a3e07eef tool 2024-03-06 14:04:15 +08:00
Joel 8a906e2959 fix: http nodes update error and support json 2024-03-06 11:34:07 +08:00
Joel 9839b5cb53 fix: enchance code editor syle 2024-03-06 11:23:42 +08:00
StyleZhang 430569d486 app detail 2024-03-05 17:38:32 +08:00
Joel d3dfadbd9b feat: add code editor 2024-03-05 17:37:20 +08:00
StyleZhang e474e02a50 sync workflow draft 2024-03-05 17:11:54 +08:00
StyleZhang 54d9cdaabf sync workflow draft 2024-03-05 17:11:54 +08:00
Joel 76fe3c1d76 fix: question classifer can not edit 2024-03-05 16:13:24 +08:00
StyleZhang 261e56e61d single run 2024-03-05 15:57:10 +08:00
StyleZhang ede0bb5396 control run 2024-03-05 15:28:28 +08:00
JzoNg 186b85cd62 add store of app detail 2024-03-05 15:27:52 +08:00
Joel eab405af5b chore: node add memo 2024-03-05 15:26:28 +08:00
Joel 93999cec56 chore: panel memo 2024-03-05 14:54:59 +08:00
StyleZhang acacc0a4cb service 2024-03-05 14:44:13 +08:00
Joel b2ae7089dc fix: var assigner 2024-03-05 14:40:21 +08:00
Joel d4ab6b294a fix: llm default 2024-03-05 14:35:12 +08:00
Joel e6d89f6756 fix: start node add 2024-03-05 14:27:52 +08:00
Joel 7ec29bbee7 feat: node add default value 2024-03-05 14:27:52 +08:00
StyleZhang f1d44a4c87 zoom in out 2024-03-05 14:15:05 +08:00
StyleZhang 466f16eb1d node name 2024-03-05 13:05:36 +08:00
StyleZhang 04d54c0319 fix 2024-03-05 12:40:56 +08:00
StyleZhang 0367a2148a bg 2024-03-05 12:36:59 +08:00
Joel 57e9e229de temp 2024-03-05 12:35:36 +08:00
StyleZhang 90c8d9d27b service 2024-03-05 11:57:51 +08:00
Joel a30b6acc52 fix: start node 2024-03-05 11:30:45 +08:00
Joel 0ee7f952ef fix: start node 2024-03-05 11:27:24 +08:00
Joel 86656de971 feat: classify data panel node sync 2024-03-05 11:06:35 +08:00
JzoNg 2e649c3329 add icon of yaml 2024-03-05 09:03:52 +08:00
StyleZhang e868e44025 help line 2024-03-04 20:35:01 +08:00
Joel 4376813951 feat: get and set data use context 2024-03-04 20:14:18 +08:00
StyleZhang ccd3e519ea edges change 2024-03-04 19:01:38 +08:00
StyleZhang c4ca3bd34d rename data 2024-03-04 18:18:47 +08:00
StyleZhang 081baae883 operator 2024-03-04 17:45:41 +08:00
StyleZhang a3d4befad4 service 2024-03-04 17:45:41 +08:00
Joel 2f13d2775f Merge branch 'main' into feat/workflow 2024-03-04 17:40:52 +08:00
Joel a36a2a1080 feat: handleupdate logic 2024-03-04 17:04:53 +08:00
Joel 474c7865d7 feat: get and set value from store 2024-03-04 15:51:05 +08:00
StyleZhang bd205f63cc fix: workflow route 2024-03-04 14:53:48 +08:00
Joel ac40eb8d87 chore: add missing jp files 2024-03-04 10:44:34 +08:00
Joel 3ea06d286a merge main 2024-03-04 10:41:33 +08:00
JzoNg 8d6984e286 create app by import yaml 2024-03-03 15:37:47 +08:00
JzoNg cd773b8cc9 app import supported 2024-03-03 14:25:50 +08:00
JzoNg 9bca69ebfb app DSL export supported 2024-03-03 14:10:11 +08:00
JzoNg b33da6a09c duplicate app supported 2024-03-03 13:41:14 +08:00
JzoNg 7ae23d5567 add redirection 2024-03-03 13:24:58 +08:00
JzoNg 569315ee3e add tip for chatbot orchestrate 2024-03-03 12:39:07 +08:00
JzoNg 4c7941adef app creation 2024-03-02 16:47:43 +08:00
JzoNg 93d116a9d0 add tracing panel 2024-03-02 14:05:05 +08:00
JzoNg 7b2499c292 add meta data of run log 2024-03-02 11:16:23 +08:00
JzoNg 2be2bc5877 add run log status 2024-03-02 09:59:31 +08:00
JzoNg cfb853efbf log detail panel 2024-03-01 20:32:22 +08:00
JzoNg 2691164fc4 workflow log list 2024-03-01 20:32:22 +08:00
StyleZhang b113711a86 hooks 2024-03-01 20:22:06 +08:00
StyleZhang 68e9530507 run by single 2024-03-01 19:09:27 +08:00
StyleZhang 0ca23bb840 features 2024-03-01 18:20:49 +08:00
StyleZhang 6e3d6c4269 features 2024-03-01 18:20:49 +08:00
Joel c2eaa32036 temp 2024-03-01 17:09:53 +08:00
Joel 604930db64 feat: support detect when to show vision config 2024-03-01 16:43:56 +08:00
Joel c3f99779f2 feat: vision config 2024-03-01 16:30:24 +08:00
Joel 0518da1e49 feat: handle llm memory 2024-03-01 15:07:29 +08:00
Joel 6f6f032244 feat: choose context var 2024-03-01 14:35:37 +08:00
StyleZhang 0acb2db9b6 layout 2024-03-01 14:29:02 +08:00
Joel 74d26764f8 feat: knowledge retrieval dataset setting 2024-03-01 13:56:52 +08:00
Joel cf77a89123 feat: dasetitem ui 2024-03-01 11:38:24 +08:00
StyleZhang 1b73632f77 utils 2024-03-01 11:27:30 +08:00
Joel 0a7cbf6fde feat: dataset list struct 2024-02-29 20:26:51 +08:00
Joel e4701e26c8 feat: add datasets 2024-02-29 20:03:26 +08:00
Joel 045156985a fix: not show rerank modal picker 2024-02-29 19:39:27 +08:00
Joel 257e795ca9 feat: retrieval config 2024-02-29 18:24:15 +08:00
StyleZhang bafdc510d6 record panel 2024-02-29 17:33:49 +08:00
StyleZhang 1840d05a37 record panel 2024-02-29 17:27:08 +08:00
Joel 6d5618447e feat: knowledge retirveval output 2024-02-29 16:39:36 +08:00
Joel b2de27b7be feat: knowledge query var 2024-02-29 15:48:48 +08:00
Joel 9c0d44fa09 feat: llm node support config memroy 2024-02-29 15:36:25 +08:00
Joel f95eb2df0d feat: filed fold 2024-02-29 15:26:06 +08:00
Joel cbb298ccb6 feat: config conversation role name 2024-02-29 15:17:20 +08:00
Joel 9e6940ed3e feat: mermory size config 2024-02-29 14:50:36 +08:00
Joel fbcc769d4e feat: instructions 2024-02-29 11:50:46 +08:00
Joel 65f0378e43 feat: classlist crud 2024-02-29 11:37:53 +08:00
Joel f7a90f2660 merge main 2024-02-29 10:59:21 +08:00
StyleZhang 3d825dcb3e add features 2024-02-28 20:58:00 +08:00
StyleZhang 2094a554f6 multiple edge 2024-02-28 20:58:00 +08:00
Joel 4837ae4958 feat: question add class 2024-02-28 20:49:12 +08:00
Joel 6da9950b72 feat: workflow to auth 2024-02-28 20:19:22 +08:00
StyleZhang e8921787b3 hooks 2024-02-28 20:11:24 +08:00
StyleZhang d2d6904c9b panel-operator 2024-02-28 20:11:23 +08:00
Joel 510f0593e9 chore: question classify 2024-02-28 19:54:20 +08:00
Joel 7a438f8999 chore: assign var 2024-02-28 19:49:01 +08:00
Joel 113af85c3c chore: add requierd 2024-02-28 18:32:36 +08:00
Joel 916bacb60e chore: remove auto show modal 2024-02-28 18:17:39 +08:00
Joel a98b5ca97e chore: auth i18n 2024-02-28 18:11:09 +08:00
Joel 076fe8ca3a feat: auth struct 2024-02-28 17:37:31 +08:00
Joel b08327cb4b feat: edit body 2024-02-28 16:25:09 +08:00
StyleZhang f1b868d5d9 next step 2024-02-28 16:19:57 +08:00
Joel 76ff004ea5 feat: bulk edit 2024-02-28 15:01:58 +08:00
Joel df173764d2 chore: replace remove btn 2024-02-28 13:54:11 +08:00
Joel 7fa25934af feat: key value input 2024-02-28 11:30:28 +08:00
Joel 649c3d0732 feat: key value struct 2024-02-27 18:48:01 +08:00
Joel 35c56237a0 feat: url selector 2024-02-27 18:34:54 +08:00
StyleZhang 236cc6f526 hooks 2024-02-27 18:20:32 +08:00
StyleZhang a311f88c99 compute node position 2024-02-27 18:02:49 +08:00
Joel e92bc25216 fix: if node condition operation i18n 2024-02-27 17:10:52 +08:00
Joel 0c06d84e22 chore: add spacing and hover 2024-02-27 16:22:47 +08:00
Joel 77c8261fca chore: if not align 2024-02-27 16:19:29 +08:00
Joel 91a2e71fff feat: if comparasion 2024-02-27 15:52:07 +08:00
Joel 0fb47fed9e feat: add adn update condition 2024-02-27 15:20:04 +08:00
Joel 4519c6ab29 feat: conditions struct 2024-02-27 11:50:56 +08:00
Joel 32c6431dbc feat: assign node no var list tip 2024-02-27 10:58:46 +08:00
Joel 925964ac28 feat: add default and utils 2024-02-27 10:43:11 +08:00
Joel 4d4d3bb965 feat: add default values and utils and fix ts 2024-02-27 10:34:13 +08:00
StyleZhang 3d526b3a87 handleAddNextNode 2024-02-26 19:03:04 +08:00
StyleZhang f91582e060 publish button 2024-02-26 18:43:33 +08:00
Joel dec60fdd4c feat: fin var assigner 2024-02-26 18:19:01 +08:00
Joel 31930159b8 feat: var assigner data logic 2024-02-26 18:19:01 +08:00
StyleZhang 6e2611c86c node title desc 2024-02-26 17:10:18 +08:00
StyleZhang 7574107d8c add run-history 2024-02-26 15:38:49 +08:00
StyleZhang 58d8b0dd01 node handle connection line 2024-02-26 14:33:31 +08:00
JzoNg 49f78bacef update icons of app menu 2024-02-25 14:06:07 +08:00
JzoNg 3b190467c1 update i18n and style of creatioin from app template 2024-02-24 14:58:00 +08:00
JzoNg 804a090457 app templates 2024-02-24 14:21:42 +08:00
JzoNg 14cfb310e3 app creation 2024-02-24 12:45:58 +08:00
JzoNg f607a334ac create from DSL 2024-02-24 12:45:58 +08:00
JzoNg 117b84116e app list modification 2024-02-24 12:45:58 +08:00
StyleZhang 171dd5c737 node-handle 2024-02-23 19:26:56 +08:00
Joel b5ed4af25a feat: var assigner node 2024-02-23 18:26:42 +08:00
StyleZhang b6c683a1b8 next step 2024-02-23 17:20:06 +08:00
Joel 5200ec0b9a feat: end node panle 2024-02-23 17:01:48 +08:00
Joel 307cbf1d9f feat: input no var tip 2024-02-23 16:15:45 +08:00
StyleZhang e7ecdb01a6 block-selector 2024-02-23 15:20:04 +08:00
Joel 383bfd7583 feat: merge i18n 2024-02-23 15:18:48 +08:00
Joel 508ea8bc0a feat: add number type var 2024-02-23 15:02:00 +08:00
Joel 077de17cd5 feat: support config modal edit 2024-02-23 14:25:08 +08:00
StyleZhang f6c07c996b workflow store 2024-02-23 14:16:19 +08:00
Joel 7ba0bfffa2 fix: debug set var value error 2024-02-23 11:58:28 +08:00
StyleZhang 9b577fa32c chore 2024-02-23 11:31:46 +08:00
StyleZhang 94cda3e837 chore 2024-02-22 20:10:58 +08:00
Joel f09f91e25a hide debug 2024-02-22 18:51:25 +08:00
Joel 235bec6481 feat: new var input editor 2024-02-22 18:49:32 +08:00
StyleZhang ee616ee6dd header 2024-02-22 16:35:54 +08:00
Joel 5153068a64 feat: start var list 2024-02-22 16:17:38 +08:00
StyleZhang 701e441349 panel 2024-02-22 15:37:33 +08:00
Joel 5817a035f9 feat: start build in vars show 2024-02-22 15:06:27 +08:00
StyleZhang ea76f46223 block-selector 2024-02-22 15:02:02 +08:00
Joel 0759b29ca2 feat: retrial node 2024-02-22 14:40:16 +08:00
Joel db6074e035 feat: tool node 2024-02-22 14:06:34 +08:00
Joel 6057ba0988 feat: var assigner node struct 2024-02-22 11:42:20 +08:00
Joel 2fdcf1756e feat: end node 2024-02-22 11:04:14 +08:00
StyleZhang f489736e06 add debug-and-preview 2024-02-21 20:23:03 +08:00
StyleZhang 15f13209cf node handle 2024-02-21 19:02:58 +08:00
Joel dbf3b7ad6d feat: end node typs and mock 2024-02-21 18:38:52 +08:00
Joel 3341077587 feat: start node 2024-02-21 18:31:45 +08:00
Joel e39d7021e0 feat: if else node 2024-02-21 17:45:52 +08:00
Joel cffaf30760 feat: if types 2024-02-21 16:34:38 +08:00
Joel bc60cf0a35 feat: http node content 2024-02-21 16:00:14 +08:00
Joel 9bb9807252 feat: http node struct 2024-02-21 15:50:36 +08:00
Joel 8b8fdb48bb feat: output var 2024-02-21 14:56:10 +08:00
Joel b4437ccd2b chore: output lines 2024-02-21 14:11:51 +08:00
Joel 65ac4dedcc feat: template transform code tooltip 2024-02-21 13:55:17 +08:00
StyleZhang 671654da71 add node 2024-02-21 12:28:10 +08:00
Joel 31490417d1 Merge branch 'main' into feat/workflow 2024-02-21 12:05:22 +08:00
Joel 17e8c91267 feat: template transform panel content 2024-02-21 11:48:34 +08:00
Joel db7dccf349 feat: type selector 2024-02-21 11:33:25 +08:00
Joel 71d3f71e22 feat: code editor base 2024-02-21 11:04:37 +08:00
StyleZhang 13a54c3f56 block-selector edit 2024-02-20 20:12:41 +08:00
Joel d58a1b1359 feat: code support vars 2024-02-20 18:42:21 +08:00
Joel bb87a350ac feat: question classify panel 2024-02-20 17:39:09 +08:00
Joel c441a848e7 feat: question classify node 2024-02-20 17:29:06 +08:00
StyleZhang f14a5c7346 add node-control 2024-02-20 16:58:29 +08:00
Joel 92219b5aad feat: prompt ide and fin direct ansewer node 2024-02-20 16:52:22 +08:00
Joel 291201db1c chore: llm use config 2024-02-20 15:34:44 +08:00
Joel c8ea6d7bfb feat: direct answer node 2024-02-20 15:21:35 +08:00
Joel 9c70befaf6 chore: move node type to self struct 2024-02-20 14:59:03 +08:00
Joel fcadb807f6 feat: llm node content 2024-02-20 14:51:19 +08:00
Joel 4364775dcb feat: output vars 2024-02-20 14:27:40 +08:00
Joel 2a196e91a6 feat: default set var name 2024-02-20 14:04:24 +08:00
Joel 7a0358827a feat: finish choose var 2024-02-20 14:01:20 +08:00
Joel 62e2deafca feat: infinite choose var 2024-02-20 11:23:23 +08:00
StyleZhang 25b4e68fbb delete 2024-02-19 19:58:49 +08:00
StyleZhang c909319413 base-node base-panel 2024-02-19 19:44:48 +08:00
StyleZhang c7ee8ac1c7 add app-info-panel 2024-02-19 19:06:42 +08:00
Joel 2386eed703 chore: new block enum 2024-02-19 18:46:21 +08:00
Joel ada558bedc feat: add picker shower 2024-02-19 18:33:12 +08:00
StyleZhang 6caca3aaf7 base panel 2024-02-19 17:58:54 +08:00
StyleZhang 3d3bc4c512 initial node data 2024-02-19 17:45:36 +08:00
Joel 044ed624eb feat: var picker trigger 2024-02-19 16:36:53 +08:00
Joel 4dff0c5dff feat: to not ignore var 2024-02-19 16:01:12 +08:00
StyleZhang 59d8f926c8 block-selector 2024-02-19 15:54:41 +08:00
Joel c6f1900a93 chore: merge main 2024-02-19 15:52:51 +08:00
Joel d94a9cd864 feat: add node icons 2024-02-19 15:44:52 +08:00
Joel 21db8e3be4 feat: add var struct 2024-02-19 11:26:25 +08:00
Joel e05bbec879 chore: model and params select 2024-02-19 10:35:11 +08:00
StyleZhang 240e0dfa6f next-step 2024-02-18 20:26:16 +08:00
Joel ab6a01b476 chore: handle llm model type 2024-02-18 18:31:04 +08:00
StyleZhang dce01cf002 header 2024-02-18 17:56:00 +08:00
StyleZhang da84ba06c7 add block-icon 2024-02-18 17:36:34 +08:00
Joel 45ba3ca07b feat: add model selector 2024-02-18 17:26:52 +08:00
StyleZhang 56407a910d add block-selector 2024-02-18 16:14:21 +08:00
StyleZhang e624c33d51 node props 2024-02-18 16:14:21 +08:00
Joel 3666462076 feat: llm input struct 2024-02-18 14:33:44 +08:00
Joel da0d9aab39 chore: remove node code to panel 2024-02-18 14:08:08 +08:00
Joel ace04b3ef4 feat: filed and var 2024-02-18 14:01:22 +08:00
Joel 1a4c2e77c4 feat: nodes placeholder 2024-02-06 17:49:07 +08:00
StyleZhang f3c78fe73d init 2024-02-06 17:17:29 +08:00
StyleZhang a17c0e5bf6 init 2024-02-06 17:05:26 +08:00
StyleZhang 20d5fdea2c init 2024-02-06 12:41:34 +08:00
380 changed files with 2125 additions and 45696 deletions
-2
View File
@@ -8,8 +8,6 @@ body:
label: Self Checks
description: "To make sure we get to you in time, please check the following :)"
options:
- label: This is only for bug report, if you would like to ask a quesion, please head to [Discussions](https://github.com/langgenius/dify/discussions/categories/general).
required: true
- 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)).
+6 -3
View File
@@ -1,5 +1,8 @@
blank_issues_enabled: false
contact_links:
- name: "\U0001F4E7 Discussions"
url: https://github.com/langgenius/dify/discussions/categories/general
about: General discussions and request help from the community
- name: "\U0001F4DA Dify user documentation"
url: https://docs.dify.ai/getting-started/readme
about: Documentation for users of Dify
- name: "\U0001F4DA Dify dev documentation"
url: https://docs.dify.ai/getting-started/install-self-hosted
about: Documentation for people interested in developing and contributing for Dify
+22
View File
@@ -0,0 +1,22 @@
name: "🤝 Help Wanted"
description: "Request help from the community [please use English :]"
labels:
- help-wanted
body:
- type: checkboxes
attributes:
label: Self Checks
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: "Pleas do not modify this template :) and fill in all the required fields."
required: true
- type: textarea
attributes:
label: Provide a description of the help you need
placeholder: Briefly describe what you need help with.
validations:
required: true
@@ -26,7 +26,6 @@ jobs:
HUGGINGFACE_TEXT2TEXT_GEN_ENDPOINT_URL: b
HUGGINGFACE_EMBEDDINGS_ENDPOINT_URL: c
MOCK_SWITCH: true
CODE_MAX_STRING_LENGTH: 80000
steps:
- name: Checkout code
@@ -42,11 +41,5 @@ jobs:
- name: Install dependencies
run: pip install -r ./api/requirements.txt
- name: Run ModelRuntime
- name: Run pytest
run: pytest api/tests/integration_tests/model_runtime/anthropic api/tests/integration_tests/model_runtime/azure_openai api/tests/integration_tests/model_runtime/openai api/tests/integration_tests/model_runtime/chatglm api/tests/integration_tests/model_runtime/google api/tests/integration_tests/model_runtime/xinference api/tests/integration_tests/model_runtime/huggingface_hub/test_llm.py
- name: Run Tool
run: pytest api/tests/integration_tests/tools/test_all_provider.py
- name: Run Workflow
run: pytest api/tests/integration_tests/workflow
+26
View File
@@ -0,0 +1,26 @@
name: Run Tool Pytest
on:
pull_request:
branches:
- main
jobs:
test:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.10'
cache: 'pip'
cache-dependency-path: ./api/requirements.txt
- name: Install dependencies
run: pip install -r ./api/requirements.txt
- name: Run pytest
run: pytest ./api/tests/integration_tests/tools/test_all_provider.py
+31
View File
@@ -0,0 +1,31 @@
name: Run Pytest
on:
pull_request:
branches:
- main
- deploy/dev
jobs:
test:
runs-on: ubuntu-latest
env:
MOCK_SWITCH: true
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.10'
cache: 'pip'
cache-dependency-path: ./api/requirements.txt
- name: Install dependencies
run: pip install -r ./api/requirements.txt
- name: Run pytest
run: pytest api/tests/integration_tests/workflow
+2 -1
View File
@@ -5,6 +5,7 @@ on:
branches:
- "main"
- "deploy/dev"
- "feat/workflow"
release:
types: [published]
@@ -46,7 +47,7 @@ jobs:
with:
images: ${{ env[matrix.image_name_env] }}
tags: |
type=raw,value=latest,enable=${{ startsWith(github.ref, 'refs/tags/') }}
type=raw,value=latest,enable=${{ github.ref == 'refs/heads/main' && startsWith(github.ref, 'refs/tags/') }}
type=ref,event=branch
type=sha,enable=true,priority=100,prefix=,suffix=,format=long
type=raw,value=${{ github.ref_name }},enable=${{ startsWith(github.ref, 'refs/tags/') }}
+1 -1
View File
@@ -36,7 +36,7 @@ In terms of licensing, please take a minute to read our short [License and Contr
| Feature Type | Priority |
| ------------------------------------------------------------ | --------------- |
| High-Priority Features as being labeled by a team member | High Priority |
| Popular feature requests from our [community feedback board](https://github.com/langgenius/dify/discussions/categories/feedbacks) | Medium Priority |
| Popular feature requests from our [community feedback board](https://feedback.dify.ai/) | Medium Priority |
| Non-core features and minor enhancements | Low Priority |
| Valuable but not immediate | Future-Feature |
+1 -1
View File
@@ -34,7 +34,7 @@
| Feature Type | Priority |
| ------------------------------------------------------------ | --------------- |
| High-Priority Features as being labeled by a team member | High Priority |
| Popular feature requests from our [community feedback board](https://github.com/langgenius/dify/discussions/categories/feedbacks) | Medium Priority |
| Popular feature requests from our [community feedback board](https://feedback.dify.ai/) | Medium Priority |
| Non-core features and minor enhancements | Low Priority |
| Valuable but not immediate | Future-Feature |
+30 -28
View File
@@ -1,4 +1,4 @@
[![](./images/GitHub_README_cover.png)](https://dify.ai)
[![](./images/describe.png)](https://dify.ai)
<p align="center">
<a href="./README.md">English</a> |
<a href="./README_CN.md">简体中文</a> |
@@ -29,35 +29,16 @@
**Dify** is an open-source LLM app development platform. Dify's intuitive interface combines a RAG pipeline, AI workflow orchestration, agent capabilities, model management, observability features and more, letting you quickly go from prototype to production.
https://github.com/langgenius/dify/assets/13230914/979e7a68-f067-4bbc-b38e-2deb2cc2bbb5
![](./images/demo.png)
## Using Dify Cloud
You can try out [Dify Cloud](https://dify.ai) now. It provides all the capabilities of the self-deployed version, and includes 200 free GPT-4 calls.
## Using our Cloud Services
## Dify for Enterprise / Organizations
[Schedule a meeting with us](#Direct-Meetings) or [send us an email](mailto:business@dify.ai?subject=[GitHub]Business%20License%20Inquiry) to discuss enterprise needs.
For startups and small businesses using AWS, check out [Dify Premium on AWS Marketplace](https://aws.amazon.com/marketplace/pp/prodview-t22mebxzwjhu6) and deploy it to your own AWS VPC with one-click. It's an affordable AMI offering with the option to create apps with custom logo and branding.
## Features
![](./images/models.png)
**1. Workflow**: Create and test complex AI workflows on a visual canvas, with pre-built nodes taking advantage of the power of all the following features and beyond.
**2. Extensive LLM support**: Seamless integration with hundreds of proprietary / open-source LLMs and dozens of inference providers, including GPT, Mistral, Llama2, and OpenAI API-compatible models. A full list of supported model providers is kept [here](https://docs.dify.ai/getting-started/readme/model-providers).
**3. Prompt IDE**: Visual orchestration of applications and services based on any LLMs. Easily share with your team.
**4. RAG Engine**: Includes various RAG capabilities based on full-text indexing or vector database embeddings, allowing direct upload of PDFs, TXTs, and other text formats.
**5. AI Agent**: Based on Function Calling and ReAct, the Agent inference framework allows users to customize tools, what you see is what you get. Dify provides more than a dozen built-in tools for AI agents, such as Google Search, DELL·E, Stable Diffusion, WolframAlpha, etc.
**6. LLMOps**: Monitor and analyze application logs and performance, continuously improving Prompts, datasets, or models based on production data.
You can try out [Dify.AI Cloud](https://dify.ai) now. It provides all the capabilities of the self-deployed version, and includes 200 free requests to OpenAI GPT-3.5.
### Looking to purchase via AWS?
Check out [Dify Premium on AWS](https://aws.amazon.com/marketplace/pp/prodview-t22mebxzwjhu6) and deploy it to your own AWS VPC with one-click.
## Dify vs. LangChain vs. Assistants API
@@ -71,10 +52,28 @@ For startups and small businesses using AWS, check out [Dify Premium on AWS Mark
| **Local Deployment** | Supported | Not Supported | Not Applicable |
## Features
![](./images/models.png)
**1. LLM Support**: Integration with OpenAI's GPT family of models, or the open-source Llama2 family models. In fact, Dify supports mainstream commercial models and open-source models (locally deployed or based on MaaS).
**2. Prompt IDE**: Visual orchestration of applications and services based on LLMs with your team.
**3. RAG Engine**: Includes various RAG capabilities based on full-text indexing or vector database embeddings, allowing direct upload of PDFs, TXTs, and other text formats.
**4. AI Agent**: Based on Function Calling and ReAct, the Agent inference framework allows users to customize tools, what you see is what you get. Dify provides more than a dozen built-in tool calling capabilities, such as Google Search, DELL·E, Stable Diffusion, WolframAlpha, etc.
**5. Continuous Operations**: Monitor and analyze application logs and performance, continuously improving Prompts, datasets, or models using production data.
## Before You Start
**Star us on GitHub, and be instantly notified for new releases!**
![star-us](https://github.com/langgenius/dify/assets/100913391/95f37259-7370-4456-a9f0-0bc01ef8642f)
- [Website](https://dify.ai)
- [Docs](https://docs.dify.ai)
- [Deployment Docs](https://docs.dify.ai/getting-started/install-self-hosted)
@@ -139,18 +138,21 @@ We are looking for contributors to help with translating Dify to languages other
## Community & Support
* [Github Discussion](https://github.com/langgenius/dify/discussions). Best for: sharing feedback and asking questions.
* [Canny](https://feedback.dify.ai/). Best for: sharing feedback and checking out our feature roadmap.
* [GitHub Issues](https://github.com/langgenius/dify/issues). Best for: bugs you encounter using Dify.AI, and feature proposals. See our [Contribution Guide](https://github.com/langgenius/dify/blob/main/CONTRIBUTING.md).
* [Email Support](mailto:hello@dify.ai?subject=[GitHub]Questions%20About%20Dify). Best for: questions you have about using Dify.AI.
* [Discord](https://discord.gg/FngNHpbcY7). Best for: sharing your applications and hanging out with the community.
* [Twitter](https://twitter.com/dify_ai). Best for: sharing your applications and hanging out with the community.
* [Business Contact](mailto:business@dify.ai?subject=[GitHub]Business%20License%20Inquiry). Best for: business inquiries of licensing Dify.AI for commercial use.
### Direct Meetings
**Help us make Dify better. Reach out directly to us**.
| Point of Contact | Purpose |
| :----------------------------------------------------------: | :----------------------------------------------------------: |
| <a href='https://cal.com/guchenhe/15min' target='_blank'><img src='https://i.postimg.cc/fWBqSmjP/Git-Hub-README-Button-3x.png' border='0' alt='Git-Hub-README-Button-3x' height="60" width="214"/></a> | Business enquiries & product feedback. |
| <a href='https://cal.com/pinkbanana' target='_blank'><img src='https://i.postimg.cc/LsRTh87D/Git-Hub-README-Button-2x.png' border='0' alt='Git-Hub-README-Button-2x' height="60" width="225"/></a> | Contributions, issues & feature requests |
| <a href='https://cal.com/guchenhe/15min' target='_blank'><img src='https://i.postimg.cc/fWBqSmjP/Git-Hub-README-Button-3x.png' border='0' alt='Git-Hub-README-Button-3x' height="60" width="214"/></a> | Product design feedback, user experience discussions, feature planning and roadmaps. |
| <a href='https://cal.com/pinkbanana' target='_blank'><img src='https://i.postimg.cc/LsRTh87D/Git-Hub-README-Button-2x.png' border='0' alt='Git-Hub-README-Button-2x' height="60" width="225"/></a> | Technical support, issues, or feature requests |
## Security Disclosure
-1
View File
@@ -114,7 +114,6 @@ docker compose up -d
我们欢迎您为 Dify 做出贡献,以帮助改善 Dify。包括:提交代码、问题、新想法,或分享您基于 Dify 创建的有趣且有用的 AI 应用程序。同时,我们也欢迎您在不同的活动、会议和社交媒体上分享 Dify。
- [Github Discussion](https://github.com/langgenius/dify/discussions). 👉:分享您的应用程序并与社区交流。
- [GitHub Issues](https://github.com/langgenius/dify/issues)。👉:使用 Dify.AI 时遇到的错误和问题,请参阅[贡献指南](CONTRIBUTING.md)。
- [电子邮件支持](mailto:hello@dify.ai?subject=[GitHub]Questions%20About%20Dify)。👉:关于使用 Dify.AI 的问题。
- [Discord](https://discord.gg/FngNHpbcY7)。👉:分享您的应用程序并与社区交流。
-1
View File
@@ -115,7 +115,6 @@ docker compose up -d
Difyに貢献していただき、コードの提出、問題の報告、新しいアイデアの提供、またはDifyを基に作成した興味深く有用なAIアプリケーションの共有により、Difyをより良いものにするお手伝いを歓迎します。同時に、さまざまなイベント、会議、ソーシャルメディアでDifyを共有することも歓迎します。
- [Github Discussion](https://github.com/langgenius/dify/discussions). 👉:アプリを共有し、コミュニティとコミュニケーション。
- [GitHub Issues](https://github.com/langgenius/dify/issues)。最適な使用法:Dify.AIの使用中に遭遇するバグやエラー、[貢献ガイド](CONTRIBUTING.md)を参照。
- [Email サポート](mailto:hello@dify.ai?subject=[GitHub]Questions%20About%20Dify)。最適な使用法:Dify.AIの使用に関する質問。
- [Discord](https://discord.gg/FngNHpbcY7)。最適な使用法:アプリケーションの共有とコミュニティとの交流。
+2 -2
View File
@@ -6,7 +6,7 @@
"configurations": [
{
"name": "Python: Celery",
"type": "debugpy",
"type": "python",
"request": "launch",
"module": "celery",
"justMyCode": true,
@@ -21,7 +21,7 @@
},
{
"name": "Python: Flask",
"type": "debugpy",
"type": "python",
"request": "launch",
"module": "flask",
"env": {
+6 -8
View File
@@ -17,16 +17,16 @@
```bash
sed -i "/^SECRET_KEY=/c\SECRET_KEY=$(openssl rand -base64 42)" .env
```
4. If you use Anaconda, create a new environment and activate it
3.5 If you use annaconda, create a new environment and activate it
```bash
conda create --name dify python=3.10
conda activate dify
```
5. Install dependencies
4. Install dependencies
```bash
pip install -r requirements.txt
```
6. Run migrate
5. Run migrate
Before the first launch, migrate the database to the latest version.
@@ -47,11 +47,9 @@
pip install -r requirements.txt --upgrade --force-reinstall
```
7. Start backend:
6. Start backend:
```bash
flask run --host 0.0.0.0 --port=5001 --debug
```
8. Setup your application by visiting http://localhost:5001/console/api/setup or other apis...
9. If you need to debug local async processing, please start the worker service by running
`celery -A app.celery worker -P gevent -c 1 --loglevel INFO -Q dataset,generation,mail`.
The started celery app handles the async tasks, e.g. dataset importing and documents indexing.
7. Setup your application by visiting http://localhost:5001/console/api/setup or other apis...
8. If you need to debug local async processing, you can run `celery -A app.celery worker -P gevent -c 1 --loglevel INFO -Q dataset,generation,mail`, celery can do dataset importing and other async tasks.
+1 -3
View File
@@ -67,7 +67,6 @@ DEFAULTS = {
'CODE_EXECUTION_ENDPOINT': '',
'CODE_EXECUTION_API_KEY': '',
'TOOL_ICON_CACHE_MAX_AGE': 3600,
'MILVUS_DATABASE': 'default',
'KEYWORD_DATA_SOURCE_TYPE': 'database',
}
@@ -99,7 +98,7 @@ class Config:
# ------------------------
# General Configurations.
# ------------------------
self.CURRENT_VERSION = "0.6.1"
self.CURRENT_VERSION = "0.6.0-preview-workflow.2"
self.COMMIT_SHA = get_env('COMMIT_SHA')
self.EDITION = "SELF_HOSTED"
self.DEPLOY_ENV = get_env('DEPLOY_ENV')
@@ -213,7 +212,6 @@ class Config:
self.MILVUS_USER = get_env('MILVUS_USER')
self.MILVUS_PASSWORD = get_env('MILVUS_PASSWORD')
self.MILVUS_SECURE = get_env('MILVUS_SECURE')
self.MILVUS_DATABASE = get_env('MILVUS_DATABASE')
# weaviate settings
self.WEAVIATE_ENDPOINT = get_env('WEAVIATE_ENDPOINT')
+1 -2
View File
@@ -12,7 +12,6 @@ from controllers.console import api
from controllers.console.app.wraps import get_app_model
from controllers.console.setup import setup_required
from controllers.console.wraps import account_initialization_required
from core.app.entities.app_invoke_entities import InvokeFrom
from extensions.ext_database import db
from fields.conversation_fields import (
conversation_detail_fields,
@@ -203,7 +202,7 @@ class ChatConversationApi(Resource):
)
if app_model.mode == AppMode.ADVANCED_CHAT.value:
query = query.where(Conversation.invoke_from != InvokeFrom.DEBUGGER.value)
query = query.where(Conversation.override_model_configs.is_(None))
query = query.order_by(Conversation.created_at.desc())
@@ -6,7 +6,6 @@ from werkzeug.exceptions import NotFound
from controllers.console import api
from controllers.console.explore.error import NotChatAppError
from controllers.console.explore.wraps import InstalledAppResource
from core.app.entities.app_invoke_entities import InvokeFrom
from fields.conversation_fields import conversation_infinite_scroll_pagination_fields, simple_conversation_fields
from libs.helper import uuid_value
from models.model import AppMode
@@ -40,8 +39,8 @@ class ConversationListApi(InstalledAppResource):
user=current_user,
last_id=args['last_id'],
limit=args['limit'],
invoke_from=InvokeFrom.EXPLORE,
pinned=pinned,
exclude_debug_conversation=True
)
except LastConversationNotExistsError:
raise NotFound("Last Conversation Not Exists.")
@@ -6,7 +6,6 @@ import services
from controllers.service_api import api
from controllers.service_api.app.error import NotChatAppError
from controllers.service_api.wraps import FetchUserArg, WhereisUserArg, validate_app_token
from core.app.entities.app_invoke_entities import InvokeFrom
from fields.conversation_fields import conversation_infinite_scroll_pagination_fields, simple_conversation_fields
from libs.helper import uuid_value
from models.model import App, AppMode, EndUser
@@ -28,13 +27,7 @@ class ConversationApi(Resource):
args = parser.parse_args()
try:
return ConversationService.pagination_by_last_id(
app_model=app_model,
user=end_user,
last_id=args['last_id'],
limit=args['limit'],
invoke_from=InvokeFrom.SERVICE_API
)
return ConversationService.pagination_by_last_id(app_model, end_user, args['last_id'], args['limit'])
except services.errors.conversation.LastConversationNotExistsError:
raise NotFound("Last Conversation Not Exists.")
+1 -3
View File
@@ -5,7 +5,6 @@ from werkzeug.exceptions import NotFound
from controllers.web import api
from controllers.web.error import NotChatAppError
from controllers.web.wraps import WebApiResource
from core.app.entities.app_invoke_entities import InvokeFrom
from fields.conversation_fields import conversation_infinite_scroll_pagination_fields, simple_conversation_fields
from libs.helper import uuid_value
from models.model import AppMode
@@ -38,8 +37,7 @@ class ConversationListApi(WebApiResource):
user=end_user,
last_id=args['last_id'],
limit=args['limit'],
invoke_from=InvokeFrom.WEB_APP,
pinned=pinned,
pinned=pinned
)
except LastConversationNotExistsError:
raise NotFound("Last Conversation Not Exists.")
+1 -1
View File
@@ -687,4 +687,4 @@ class CotAgentRunner(BaseAgentRunner):
try:
return json.dumps(tools, ensure_ascii=False)
except json.JSONDecodeError:
return json.dumps(tools)
return json.dumps(tools)
+12 -12
View File
@@ -207,25 +207,19 @@ class FunctionCallAgentRunner(BaseAgentRunner):
)
)
assistant_message = AssistantPromptMessage(
content='',
tool_calls=[]
)
if tool_calls:
assistant_message.tool_calls=[
AssistantPromptMessage.ToolCall(
prompt_messages.append(AssistantPromptMessage(
content='',
name='',
tool_calls=[AssistantPromptMessage.ToolCall(
id=tool_call[0],
type='function',
function=AssistantPromptMessage.ToolCall.ToolCallFunction(
name=tool_call[1],
arguments=json.dumps(tool_call[2], ensure_ascii=False)
)
) for tool_call in tool_calls
]
else:
assistant_message.content = response
prompt_messages.append(assistant_message)
) for tool_call in tool_calls]
))
# save thought
self.save_agent_thought(
@@ -245,6 +239,12 @@ class FunctionCallAgentRunner(BaseAgentRunner):
final_answer += response + '\n'
# update prompt messages
if response.strip():
prompt_messages.append(AssistantPromptMessage(
content=response,
))
# call tools
tool_responses = []
for tool_call_id, tool_call_name, tool_call_args in tool_calls:
@@ -215,16 +215,16 @@ class AdvancedChatAppGenerateTaskPipeline(BasedGenerateTaskPipeline, WorkflowCyc
elif isinstance(event, QueueStopEvent | QueueWorkflowSucceededEvent | QueueWorkflowFailedEvent):
workflow_run = self._handle_workflow_finished(event)
if workflow_run:
yield self._workflow_finish_to_stream_response(
task_id=self._application_generate_entity.task_id,
workflow_run=workflow_run
)
if workflow_run.status == WorkflowRunStatus.FAILED.value:
err_event = QueueErrorEvent(error=ValueError(f'Run failed: {workflow_run.error}'))
yield self._error_to_stream_response(self._handle_error(err_event, self._message))
break
yield self._workflow_finish_to_stream_response(
task_id=self._application_generate_entity.task_id,
workflow_run=workflow_run
)
if isinstance(event, QueueStopEvent):
# Save message
self._save_message()
+1 -1
View File
@@ -122,7 +122,7 @@ class MessageEndStreamResponse(StreamResponse):
"""
event: StreamEvent = StreamEvent.MESSAGE_END
id: str
metadata: dict = {}
metadata: Optional[dict] = None
class MessageFileStreamResponse(StreamResponse):
@@ -1,32 +1,12 @@
import os
from typing import Any, Optional, TextIO, Union
from typing import Any, Optional, Union
from langchain.callbacks.base import BaseCallbackHandler
from langchain.input import print_text
from pydantic import BaseModel
_TEXT_COLOR_MAPPING = {
"blue": "36;1",
"yellow": "33;1",
"pink": "38;5;200",
"green": "32;1",
"red": "31;1",
}
def get_colored_text(text: str, color: str) -> str:
"""Get colored text."""
color_str = _TEXT_COLOR_MAPPING[color]
return f"\u001b[{color_str}m\033[1;3m{text}\u001b[0m"
def print_text(
text: str, color: Optional[str] = None, end: str = "", file: Optional[TextIO] = None
) -> None:
"""Print text with highlighting and no end characters."""
text_to_print = get_colored_text(text, color) if color else text
print(text_to_print, end=end, file=file)
if file:
file.flush() # ensure all printed content are written to file
class DifyAgentCallbackHandler(BaseModel):
class DifyAgentCallbackHandler(BaseCallbackHandler, BaseModel):
"""Callback Handler that prints to std out."""
color: Optional[str] = ''
current_loop = 1
+10 -17
View File
@@ -41,8 +41,7 @@ class CacheEmbedding(Embeddings):
embedding_queue_embeddings = []
try:
model_type_instance = cast(TextEmbeddingModel, self._model_instance.model_type_instance)
model_schema = model_type_instance.get_model_schema(self._model_instance.model,
self._model_instance.credentials)
model_schema = model_type_instance.get_model_schema(self._model_instance.model, self._model_instance.credentials)
max_chunks = model_schema.model_properties[ModelPropertyKey.MAX_CHUNKS] \
if model_schema and ModelPropertyKey.MAX_CHUNKS in model_schema.model_properties else 1
for i in range(0, len(embedding_queue_texts), max_chunks):
@@ -61,21 +60,15 @@ class CacheEmbedding(Embeddings):
db.session.rollback()
except Exception as e:
logging.exception('Failed transform embedding: ', e)
cache_embeddings = []
try:
for i, embedding in zip(embedding_queue_indices, embedding_queue_embeddings):
text_embeddings[i] = embedding
hash = helper.generate_text_hash(texts[i])
if hash not in cache_embeddings:
embedding_cache = Embedding(model_name=self._model_instance.model,
hash=hash,
provider_name=self._model_instance.provider)
embedding_cache.set_embedding(embedding)
db.session.add(embedding_cache)
cache_embeddings.append(hash)
db.session.commit()
except IntegrityError:
db.session.rollback()
for i, embedding in zip(embedding_queue_indices, embedding_queue_embeddings):
text_embeddings[i] = embedding
hash = helper.generate_text_hash(texts[i])
embedding_cache = Embedding(model_name=self._model_instance.model,
hash=hash,
provider_name=self._model_instance.provider)
embedding_cache.set_embedding(embedding)
db.session.add(embedding_cache)
db.session.commit()
except Exception as ex:
db.session.rollback()
logger.error('Failed to embed documents: ', ex)
@@ -47,7 +47,7 @@ class CodeExecutor:
else:
raise CodeExecutionException('Unsupported language')
runner, preload = template_transformer.transform_caller(code, inputs)
runner = template_transformer.transform_caller(code, inputs)
url = URL(CODE_EXECUTION_ENDPOINT) / 'v1' / 'sandbox' / 'run'
headers = {
'X-Api-Key': CODE_EXECUTION_API_KEY
@@ -57,7 +57,6 @@ class CodeExecutor:
'nodejs' if language == 'javascript' else
'python3' if language == 'python3' else None,
'code': runner,
'preload': preload
}
try:
@@ -18,27 +18,26 @@ result = `<<RESULT>>${output}<<RESULT>>`
console.log(result)
"""
NODEJS_PRELOAD = """"""
class NodeJsTemplateTransformer(TemplateTransformer):
@classmethod
def transform_caller(cls, code: str, inputs: dict) -> tuple[str, str]:
def transform_caller(cls, code: str, inputs: dict) -> str:
"""
Transform code to python runner
:param code: code
:param inputs: inputs
:return:
"""
# transform inputs to json string
inputs_str = json.dumps(inputs, indent=4, ensure_ascii=False)
inputs_str = json.dumps(inputs, indent=4)
# replace code and inputs
runner = NODEJS_RUNNER.replace('{{code}}', code)
runner = runner.replace('{{inputs}}', inputs_str)
return runner, NODEJS_PRELOAD
return runner
@classmethod
def transform_response(cls, response: str) -> dict:
"""
@@ -20,39 +20,9 @@ print(result)
"""
JINJA2_PRELOAD_TEMPLATE = """{% set fruits = ['Apple'] %}
{{ 'a' }}
{% for fruit in fruits %}
<li>{{ fruit }}</li>
{% endfor %}
{% if fruits|length > 1 %}
1
{% endif %}
{% for i in range(5) %}
{% if i == 3 %}{{ i }}{% else %}{% endif %}
{% endfor %}
{% for i in range(3) %}
{{ i + 1 }}
{% endfor %}
{% macro say_hello() %}a{{ 'b' }}{% endmacro %}
{{ s }}{{ say_hello() }}"""
JINJA2_PRELOAD = f"""
import jinja2
def _jinja2_preload_():
# prepare jinja2 environment, load template and render before to avoid sandbox issue
template = jinja2.Template('''{JINJA2_PRELOAD_TEMPLATE}''')
template.render(s='a')
if __name__ == '__main__':
_jinja2_preload_()
"""
class Jinja2TemplateTransformer(TemplateTransformer):
@classmethod
def transform_caller(cls, code: str, inputs: dict) -> tuple[str, str]:
def transform_caller(cls, code: str, inputs: dict) -> str:
"""
Transform code to python runner
:param code: code
@@ -62,10 +32,10 @@ class Jinja2TemplateTransformer(TemplateTransformer):
# transform jinja2 template to python code
runner = PYTHON_RUNNER.replace('{{code}}', code)
runner = runner.replace('{{inputs}}', json.dumps(inputs, indent=4, ensure_ascii=False))
return runner, JINJA2_PRELOAD
runner = runner.replace('{{inputs}}', json.dumps(inputs, indent=4))
return runner
@classmethod
def transform_response(cls, response: str) -> dict:
"""
@@ -81,4 +51,4 @@ class Jinja2TemplateTransformer(TemplateTransformer):
return {
'result': result
}
}
@@ -20,12 +20,10 @@ result = f'''<<RESULT>>
print(result)
"""
PYTHON_PRELOAD = """"""
class PythonTemplateTransformer(TemplateTransformer):
@classmethod
def transform_caller(cls, code: str, inputs: dict) -> tuple[str, str]:
def transform_caller(cls, code: str, inputs: dict) -> str:
"""
Transform code to python runner
:param code: code
@@ -34,13 +32,13 @@ class PythonTemplateTransformer(TemplateTransformer):
"""
# transform inputs to json string
inputs_str = json.dumps(inputs, indent=4, ensure_ascii=False)
inputs_str = json.dumps(inputs, indent=4)
# replace code and inputs
runner = PYTHON_RUNNER.replace('{{code}}', code)
runner = runner.replace('{{inputs}}', inputs_str)
return runner, PYTHON_PRELOAD
return runner
@classmethod
def transform_response(cls, response: str) -> dict:
@@ -4,12 +4,12 @@ from abc import ABC, abstractmethod
class TemplateTransformer(ABC):
@classmethod
@abstractmethod
def transform_caller(cls, code: str, inputs: dict) -> tuple[str, str]:
def transform_caller(cls, code: str, inputs: dict) -> str:
"""
Transform code to python runner
:param code: code
:param inputs: inputs
:return: runner, preload
:return:
"""
pass
+11 -40
View File
@@ -19,7 +19,6 @@ from core.model_manager import ModelInstance, ModelManager
from core.model_runtime.entities.model_entities import ModelType, PriceType
from core.model_runtime.model_providers.__base.large_language_model import LargeLanguageModel
from core.model_runtime.model_providers.__base.text_embedding_model import TextEmbeddingModel
from core.rag.datasource.keyword.keyword_factory import Keyword
from core.rag.extractor.entity.extract_setting import ExtractSetting
from core.rag.index_processor.index_processor_base import BaseIndexProcessor
from core.rag.index_processor.index_processor_factory import IndexProcessorFactory
@@ -658,25 +657,18 @@ class IndexingRunner:
if embedding_model_instance:
embedding_model_type_instance = embedding_model_instance.model_type_instance
embedding_model_type_instance = cast(TextEmbeddingModel, embedding_model_type_instance)
# create keyword index
create_keyword_thread = threading.Thread(target=self._process_keyword_index,
args=(current_app._get_current_object(),
dataset.id, dataset_document.id, documents))
create_keyword_thread.start()
if dataset.indexing_technique == 'high_quality':
with concurrent.futures.ThreadPoolExecutor(max_workers=10) as executor:
futures = []
for i in range(0, len(documents), chunk_size):
chunk_documents = documents[i:i + chunk_size]
futures.append(executor.submit(self._process_chunk, current_app._get_current_object(), index_processor,
chunk_documents, dataset,
dataset_document, embedding_model_instance,
embedding_model_type_instance))
with concurrent.futures.ThreadPoolExecutor(max_workers=10) as executor:
futures = []
for i in range(0, len(documents), chunk_size):
chunk_documents = documents[i:i + chunk_size]
futures.append(executor.submit(self._process_chunk, current_app._get_current_object(), index_processor,
chunk_documents, dataset,
dataset_document, embedding_model_instance,
embedding_model_type_instance))
for future in futures:
tokens += future.result()
for future in futures:
tokens += future.result()
create_keyword_thread.join()
indexing_end_at = time.perf_counter()
# update document status to completed
@@ -690,27 +682,6 @@ class IndexingRunner:
}
)
def _process_keyword_index(self, flask_app, dataset_id, document_id, documents):
with flask_app.app_context():
dataset = Dataset.query.filter_by(id=dataset_id).first()
if not dataset:
raise ValueError("no dataset found")
keyword = Keyword(dataset)
keyword.create(documents)
if dataset.indexing_technique != 'high_quality':
document_ids = [document.metadata['doc_id'] for document in documents]
db.session.query(DocumentSegment).filter(
DocumentSegment.document_id == document_id,
DocumentSegment.index_node_id.in_(document_ids),
DocumentSegment.status == "indexing"
).update({
DocumentSegment.status: "completed",
DocumentSegment.enabled: True,
DocumentSegment.completed_at: datetime.datetime.utcnow()
})
db.session.commit()
def _process_chunk(self, flask_app, index_processor, chunk_documents, dataset, dataset_document,
embedding_model_instance, embedding_model_type_instance):
with flask_app.app_context():
@@ -729,7 +700,7 @@ class IndexingRunner:
)
# load index
index_processor.load(dataset, chunk_documents, with_keywords=False)
index_processor.load(dataset, chunk_documents)
document_ids = [document.metadata['doc_id'] for document in chunk_documents]
db.session.query(DocumentSegment).filter(
-1
View File
@@ -166,7 +166,6 @@ class LLMGenerator:
response = model_instance.invoke_llm(
prompt_messages=prompt_messages,
model_parameters={
'temperature': 0.01,
"max_tokens": 2000
},
stream=False
+4 -6
View File
@@ -69,15 +69,13 @@ SUGGESTED_QUESTIONS_AFTER_ANSWER_INSTRUCTION_PROMPT = (
)
GENERATOR_QA_PROMPT = (
'<Task> The user will send a long text. Generate a Question and Answer pairs only using the knowledge in the long text. Please think step by step.'
'The user will send a long text. Please think step by step.'
'Step 1: Understand and summarize the main content of this text.\n'
'Step 2: What key information or concepts are mentioned in this text?\n'
'Step 3: Decompose or combine multiple pieces of information and concepts.\n'
'Step 4: Generate questions and answers based on these key information and concepts.\n'
'<Constraints> The questions should be clear and detailed, and the answers should be detailed and complete. '
'You must answer in {language}, in a style that is clear and detailed in {language}. No language other than {language} should be used. \n'
'<Format> Use the following format: Q1:\nA1:\nQ2:\nA2:...\n'
'<QA Pairs>'
'Step 4: Generate 20 questions and answers based on these key information and concepts.'
'The questions should be clear and detailed, and the answers should be detailed and complete.\n'
"Answer MUST according to the the language:{language} and in the following format: Q1:\nA1:\nQ2:\nA2:...\n"
)
RULE_CONFIG_GENERATE_TEMPLATE = """Given MY INTENDED AUDIENCES and HOPING TO SOLVE using a language model, please select \
+2 -13
View File
@@ -3,7 +3,6 @@ from core.file.message_file_parser import MessageFileParser
from core.model_manager import ModelInstance
from core.model_runtime.entities.message_entities import (
AssistantPromptMessage,
ImagePromptMessageContent,
PromptMessage,
PromptMessageRole,
TextPromptMessageContent,
@@ -125,17 +124,7 @@ class TokenBufferMemory:
else:
continue
if isinstance(m.content, list):
inner_msg = ""
for content in m.content:
if isinstance(content, TextPromptMessageContent):
inner_msg += f"{content.data}\n"
elif isinstance(content, ImagePromptMessageContent):
inner_msg += "[image]\n"
string_messages.append(f"{role}: {inner_msg.strip()}")
else:
message = f"{role}: {m.content}"
string_messages.append(message)
message = f"{role}: {m.content}"
string_messages.append(message)
return "\n".join(string_messages)
@@ -5,7 +5,6 @@ model_type: llm
features:
- agent-thought
- vision
- tool-call
model_properties:
mode: chat
context_size: 200000
@@ -5,7 +5,6 @@ model_type: llm
features:
- agent-thought
- vision
- tool-call
model_properties:
mode: chat
context_size: 200000
@@ -5,7 +5,6 @@ model_type: llm
features:
- agent-thought
- vision
- tool-call
model_properties:
mode: chat
context_size: 200000
@@ -1,5 +1,4 @@
import base64
import json
import mimetypes
from collections.abc import Generator
from typing import Optional, Union, cast
@@ -16,7 +15,6 @@ from anthropic.types import (
MessageStreamEvent,
completion_create_params,
)
from anthropic.types.beta.tools import ToolsBetaMessage
from httpx import Timeout
from core.model_runtime.callbacks.base_callback import Callback
@@ -29,7 +27,6 @@ from core.model_runtime.entities.message_entities import (
PromptMessageTool,
SystemPromptMessage,
TextPromptMessageContent,
ToolPromptMessage,
UserPromptMessage,
)
from core.model_runtime.errors.invoke import (
@@ -73,11 +70,10 @@ class AnthropicLargeLanguageModel(LargeLanguageModel):
:return: full response or stream response chunk generator result
"""
# invoke model
return self._chat_generate(model, credentials, prompt_messages, model_parameters, tools, stop, stream, user)
return self._chat_generate(model, credentials, prompt_messages, model_parameters, stop, stream, user)
def _chat_generate(self, model: str, credentials: dict,
prompt_messages: list[PromptMessage], model_parameters: dict,
tools: Optional[list[PromptMessageTool]] = None, stop: Optional[list[str]] = None,
prompt_messages: list[PromptMessage], model_parameters: dict, stop: Optional[list[str]] = None,
stream: bool = True, user: Optional[str] = None) -> Union[LLMResult, Generator]:
"""
Invoke llm chat model
@@ -113,26 +109,14 @@ class AnthropicLargeLanguageModel(LargeLanguageModel):
if system:
extra_model_kwargs['system'] = system
if tools:
extra_model_kwargs['tools'] = [
self._transform_tool_prompt(tool) for tool in tools
]
response = client.beta.tools.messages.create(
model=model,
messages=prompt_message_dicts,
stream=stream,
**model_parameters,
**extra_model_kwargs
)
else:
# chat model
response = client.messages.create(
model=model,
messages=prompt_message_dicts,
stream=stream,
**model_parameters,
**extra_model_kwargs
)
# chat model
response = client.messages.create(
model=model,
messages=prompt_message_dicts,
stream=stream,
**model_parameters,
**extra_model_kwargs
)
if stream:
return self._handle_chat_generate_stream_response(model, credentials, response, prompt_messages)
@@ -164,13 +148,6 @@ class AnthropicLargeLanguageModel(LargeLanguageModel):
return self._invoke(model, credentials, prompt_messages, model_parameters, tools, stop, stream, user)
def _transform_tool_prompt(self, tool: PromptMessageTool) -> dict:
return {
'name': tool.name,
'description': tool.description,
'input_schema': tool.parameters
}
def _transform_chat_json_prompts(self, model: str, credentials: dict,
prompt_messages: list[PromptMessage], model_parameters: dict,
tools: list[PromptMessageTool] | None = None, stop: list[str] | None = None,
@@ -216,18 +193,7 @@ class AnthropicLargeLanguageModel(LargeLanguageModel):
prompt = self._convert_messages_to_prompt_anthropic(prompt_messages)
client = Anthropic(api_key="")
tokens = client.count_tokens(prompt)
tool_call_inner_prompts_tokens_map = {
'claude-3-opus-20240229': 395,
'claude-3-haiku-20240307': 264,
'claude-3-sonnet-20240229': 159
}
if model in tool_call_inner_prompts_tokens_map and tools:
tokens += tool_call_inner_prompts_tokens_map[model]
return tokens
return client.count_tokens(prompt)
def validate_credentials(self, model: str, credentials: dict) -> None:
"""
@@ -253,7 +219,7 @@ class AnthropicLargeLanguageModel(LargeLanguageModel):
except Exception as ex:
raise CredentialsValidateFailedError(str(ex))
def _handle_chat_generate_response(self, model: str, credentials: dict, response: Union[Message, ToolsBetaMessage],
def _handle_chat_generate_response(self, model: str, credentials: dict, response: Message,
prompt_messages: list[PromptMessage]) -> LLMResult:
"""
Handle llm chat response
@@ -266,24 +232,9 @@ class AnthropicLargeLanguageModel(LargeLanguageModel):
"""
# transform assistant message to prompt message
assistant_prompt_message = AssistantPromptMessage(
content='',
tool_calls=[]
content=response.content[0].text
)
for content in response.content:
if content.type == 'text':
assistant_prompt_message.content += content.text
elif content.type == 'tool_use':
tool_call = AssistantPromptMessage.ToolCall(
id=content.id,
type='function',
function=AssistantPromptMessage.ToolCall.ToolCallFunction(
name=content.name,
arguments=json.dumps(content.input)
)
)
assistant_prompt_message.tool_calls.append(tool_call)
# calculate num tokens
if response.usage:
# transform usage
@@ -405,90 +356,69 @@ class AnthropicLargeLanguageModel(LargeLanguageModel):
prompt_message_dicts = []
for message in prompt_messages:
if not isinstance(message, SystemPromptMessage):
if isinstance(message, UserPromptMessage):
message = cast(UserPromptMessage, message)
if isinstance(message.content, str):
message_dict = {"role": "user", "content": message.content}
prompt_message_dicts.append(message_dict)
else:
sub_messages = []
for message_content in message.content:
if message_content.type == PromptMessageContentType.TEXT:
message_content = cast(TextPromptMessageContent, message_content)
sub_message_dict = {
"type": "text",
"text": message_content.data
}
sub_messages.append(sub_message_dict)
elif message_content.type == PromptMessageContentType.IMAGE:
message_content = cast(ImagePromptMessageContent, message_content)
if not message_content.data.startswith("data:"):
# fetch image data from url
try:
image_content = requests.get(message_content.data).content
mime_type, _ = mimetypes.guess_type(message_content.data)
base64_data = base64.b64encode(image_content).decode('utf-8')
except Exception as ex:
raise ValueError(f"Failed to fetch image data from url {message_content.data}, {ex}")
else:
data_split = message_content.data.split(";base64,")
mime_type = data_split[0].replace("data:", "")
base64_data = data_split[1]
if mime_type not in ["image/jpeg", "image/png", "image/gif", "image/webp"]:
raise ValueError(f"Unsupported image type {mime_type}, "
f"only support image/jpeg, image/png, image/gif, and image/webp")
sub_message_dict = {
"type": "image",
"source": {
"type": "base64",
"media_type": mime_type,
"data": base64_data
}
}
sub_messages.append(sub_message_dict)
prompt_message_dicts.append({"role": "user", "content": sub_messages})
elif isinstance(message, AssistantPromptMessage):
message = cast(AssistantPromptMessage, message)
content = []
if message.tool_calls:
for tool_call in message.tool_calls:
content.append({
"type": "tool_use",
"id": tool_call.id,
"name": tool_call.function.name,
"input": json.loads(tool_call.function.arguments)
})
if message.content:
content.append({
"type": "text",
"text": message.content
})
if prompt_message_dicts[-1]["role"] == "assistant":
prompt_message_dicts[-1]["content"].extend(content)
else:
prompt_message_dicts.append({
"role": "assistant",
"content": content
})
elif isinstance(message, ToolPromptMessage):
message = cast(ToolPromptMessage, message)
message_dict = {
"role": "user",
"content": [{
"type": "tool_result",
"tool_use_id": message.tool_call_id,
"content": message.content
}]
}
prompt_message_dicts.append(message_dict)
else:
raise ValueError(f"Got unknown type {message}")
prompt_message_dicts.append(self._convert_prompt_message_to_dict(message))
return system, prompt_message_dicts
def _convert_prompt_message_to_dict(self, message: PromptMessage) -> dict:
"""
Convert PromptMessage to dict
"""
if isinstance(message, UserPromptMessage):
message = cast(UserPromptMessage, message)
if isinstance(message.content, str):
message_dict = {"role": "user", "content": message.content}
else:
sub_messages = []
for message_content in message.content:
if message_content.type == PromptMessageContentType.TEXT:
message_content = cast(TextPromptMessageContent, message_content)
sub_message_dict = {
"type": "text",
"text": message_content.data
}
sub_messages.append(sub_message_dict)
elif message_content.type == PromptMessageContentType.IMAGE:
message_content = cast(ImagePromptMessageContent, message_content)
if not message_content.data.startswith("data:"):
# fetch image data from url
try:
image_content = requests.get(message_content.data).content
mime_type, _ = mimetypes.guess_type(message_content.data)
base64_data = base64.b64encode(image_content).decode('utf-8')
except Exception as ex:
raise ValueError(f"Failed to fetch image data from url {message_content.data}, {ex}")
else:
data_split = message_content.data.split(";base64,")
mime_type = data_split[0].replace("data:", "")
base64_data = data_split[1]
if mime_type not in ["image/jpeg", "image/png", "image/gif", "image/webp"]:
raise ValueError(f"Unsupported image type {mime_type}, "
f"only support image/jpeg, image/png, image/gif, and image/webp")
sub_message_dict = {
"type": "image",
"source": {
"type": "base64",
"media_type": mime_type,
"data": base64_data
}
}
sub_messages.append(sub_message_dict)
message_dict = {"role": "user", "content": sub_messages}
elif isinstance(message, AssistantPromptMessage):
message = cast(AssistantPromptMessage, message)
message_dict = {"role": "assistant", "content": message.content}
elif isinstance(message, SystemPromptMessage):
message = cast(SystemPromptMessage, message)
message_dict = {"role": "system", "content": message.content}
else:
raise ValueError(f"Got unknown type {message}")
return message_dict
def _convert_one_message_to_text(self, message: PromptMessage) -> str:
"""
Convert a single message to a string.
@@ -523,8 +453,6 @@ class AnthropicLargeLanguageModel(LargeLanguageModel):
message_text += f"{ai_prompt} [IMAGE]"
elif isinstance(message, SystemPromptMessage):
message_text = content
elif isinstance(message, ToolPromptMessage):
message_text = f"{human_prompt} {message.content}"
else:
raise ValueError(f"Got unknown type {message}")
@@ -74,7 +74,7 @@ provider_credential_schema:
label:
en_US: Available Model Name
zh_Hans: 可用模型名称
type: text-input
type: secret-input
placeholder:
en_US: A model you have access to (e.g. amazon.titan-text-lite-v1) for validation.
zh_Hans: 为了进行验证,请输入一个您可用的模型名称 (例如:amazon.titan-text-lite-v1)
@@ -402,25 +402,25 @@ class BedrockLargeLanguageModel(LargeLanguageModel):
:param credentials: model credentials
:return:
"""
required_params = {}
if "anthropic" in model:
required_params = {
"max_tokens": 32,
}
elif "ai21" in model:
# ValidationException: Malformed input request: #/temperature: expected type: Number, found: Null#/maxTokens: expected type: Integer, found: Null#/topP: expected type: Number, found: Null, please reformat your input and try again.
required_params = {
"temperature": 0.7,
"topP": 0.9,
"maxTokens": 32,
}
if "anthropic.claude-3" in model:
try:
self._invoke_claude(model=model,
credentials=credentials,
prompt_messages=[{"role": "user", "content": "ping"}],
model_parameters={},
stop=None,
stream=False)
except Exception as ex:
raise CredentialsValidateFailedError(str(ex))
try:
ping_message = UserPromptMessage(content="ping")
self._invoke(model=model,
self._generate(model=model,
credentials=credentials,
prompt_messages=[ping_message],
model_parameters=required_params,
model_parameters={},
stream=False)
except ClientError as ex:
@@ -297,6 +297,7 @@ class CohereLargeLanguageModel(LargeLanguageModel):
chat_history=chat_histories,
model=real_model,
stream=stream,
return_preamble=True,
**model_parameters,
)
@@ -1,31 +1,8 @@
import json
from collections.abc import Generator
from typing import Optional, Union, cast
from typing import Optional, Union
import requests
from core.model_runtime.entities.common_entities import I18nObject
from core.model_runtime.entities.llm_entities import LLMMode, LLMResult, LLMResultChunk, LLMResultChunkDelta
from core.model_runtime.entities.message_entities import (
AssistantPromptMessage,
ImagePromptMessageContent,
PromptMessage,
PromptMessageContent,
PromptMessageContentType,
PromptMessageTool,
SystemPromptMessage,
ToolPromptMessage,
UserPromptMessage,
)
from core.model_runtime.entities.model_entities import (
AIModelEntity,
FetchFrom,
ModelFeature,
ModelPropertyKey,
ModelType,
ParameterRule,
ParameterType,
)
from core.model_runtime.entities.llm_entities import LLMResult
from core.model_runtime.entities.message_entities import PromptMessage, PromptMessageTool
from core.model_runtime.model_providers.openai_api_compatible.llm.llm import OAIAPICompatLargeLanguageModel
@@ -36,7 +13,6 @@ class MoonshotLargeLanguageModel(OAIAPICompatLargeLanguageModel):
stream: bool = True, user: Optional[str] = None) \
-> Union[LLMResult, Generator]:
self._add_custom_parameters(credentials)
self._add_function_call(model, credentials)
user = user[:32] if user else None
return super()._invoke(model, credentials, prompt_messages, model_parameters, tools, stop, stream, user)
@@ -44,293 +20,7 @@ class MoonshotLargeLanguageModel(OAIAPICompatLargeLanguageModel):
self._add_custom_parameters(credentials)
super().validate_credentials(model, credentials)
def get_customizable_model_schema(self, model: str, credentials: dict) -> AIModelEntity | None:
return AIModelEntity(
model=model,
label=I18nObject(en_US=model, zh_Hans=model),
model_type=ModelType.LLM,
features=[ModelFeature.TOOL_CALL, ModelFeature.MULTI_TOOL_CALL, ModelFeature.STREAM_TOOL_CALL]
if credentials.get('function_calling_type') == 'tool_call'
else [],
fetch_from=FetchFrom.CUSTOMIZABLE_MODEL,
model_properties={
ModelPropertyKey.CONTEXT_SIZE: int(credentials.get('context_size', 4096)),
ModelPropertyKey.MODE: LLMMode.CHAT.value,
},
parameter_rules=[
ParameterRule(
name='temperature',
use_template='temperature',
label=I18nObject(en_US='Temperature', zh_Hans='温度'),
type=ParameterType.FLOAT,
),
ParameterRule(
name='max_tokens',
use_template='max_tokens',
default=512,
min=1,
max=int(credentials.get('max_tokens', 4096)),
label=I18nObject(en_US='Max Tokens', zh_Hans='最大标记'),
type=ParameterType.INT,
),
ParameterRule(
name='top_p',
use_template='top_p',
label=I18nObject(en_US='Top P', zh_Hans='Top P'),
type=ParameterType.FLOAT,
),
]
)
def _add_custom_parameters(self, credentials: dict) -> None:
@staticmethod
def _add_custom_parameters(credentials: dict) -> None:
credentials['mode'] = 'chat'
credentials['endpoint_url'] = 'https://api.moonshot.cn/v1'
def _add_function_call(self, model: str, credentials: dict) -> None:
model_schema = self.get_model_schema(model, credentials)
if model_schema and set([
ModelFeature.TOOL_CALL, ModelFeature.MULTI_TOOL_CALL
]).intersection(model_schema.features or []):
credentials['function_calling_type'] = 'tool_call'
def _convert_prompt_message_to_dict(self, message: PromptMessage) -> dict:
"""
Convert PromptMessage to dict for OpenAI API format
"""
if isinstance(message, UserPromptMessage):
message = cast(UserPromptMessage, message)
if isinstance(message.content, str):
message_dict = {"role": "user", "content": message.content}
else:
sub_messages = []
for message_content in message.content:
if message_content.type == PromptMessageContentType.TEXT:
message_content = cast(PromptMessageContent, message_content)
sub_message_dict = {
"type": "text",
"text": message_content.data
}
sub_messages.append(sub_message_dict)
elif message_content.type == PromptMessageContentType.IMAGE:
message_content = cast(ImagePromptMessageContent, message_content)
sub_message_dict = {
"type": "image_url",
"image_url": {
"url": message_content.data,
"detail": message_content.detail.value
}
}
sub_messages.append(sub_message_dict)
message_dict = {"role": "user", "content": sub_messages}
elif isinstance(message, AssistantPromptMessage):
message = cast(AssistantPromptMessage, message)
message_dict = {"role": "assistant", "content": message.content}
if message.tool_calls:
message_dict["tool_calls"] = []
for function_call in message.tool_calls:
message_dict["tool_calls"].append({
"id": function_call.id,
"type": function_call.type,
"function": {
"name": f"functions.{function_call.function.name}",
"arguments": function_call.function.arguments
}
})
elif isinstance(message, ToolPromptMessage):
message = cast(ToolPromptMessage, message)
message_dict = {"role": "tool", "content": message.content, "tool_call_id": message.tool_call_id}
if not message.name.startswith("functions."):
message.name = f"functions.{message.name}"
elif isinstance(message, SystemPromptMessage):
message = cast(SystemPromptMessage, message)
message_dict = {"role": "system", "content": message.content}
else:
raise ValueError(f"Got unknown type {message}")
if message.name:
message_dict["name"] = message.name
return message_dict
def _extract_response_tool_calls(self, response_tool_calls: list[dict]) -> list[AssistantPromptMessage.ToolCall]:
"""
Extract tool calls from response
:param response_tool_calls: response tool calls
:return: list of tool calls
"""
tool_calls = []
if response_tool_calls:
for response_tool_call in response_tool_calls:
function = AssistantPromptMessage.ToolCall.ToolCallFunction(
name=response_tool_call["function"]["name"] if response_tool_call.get("function", {}).get("name") else "",
arguments=response_tool_call["function"]["arguments"] if response_tool_call.get("function", {}).get("arguments") else ""
)
tool_call = AssistantPromptMessage.ToolCall(
id=response_tool_call["id"] if response_tool_call.get("id") else "",
type=response_tool_call["type"] if response_tool_call.get("type") else "",
function=function
)
tool_calls.append(tool_call)
return tool_calls
def _handle_generate_stream_response(self, model: str, credentials: dict, response: requests.Response,
prompt_messages: list[PromptMessage]) -> Generator:
"""
Handle llm stream response
:param model: model name
:param credentials: model credentials
:param response: streamed response
:param prompt_messages: prompt messages
:return: llm response chunk generator
"""
full_assistant_content = ''
chunk_index = 0
def create_final_llm_result_chunk(index: int, message: AssistantPromptMessage, finish_reason: str) \
-> LLMResultChunk:
# calculate num tokens
prompt_tokens = self._num_tokens_from_string(model, prompt_messages[0].content)
completion_tokens = self._num_tokens_from_string(model, full_assistant_content)
# transform usage
usage = self._calc_response_usage(model, credentials, prompt_tokens, completion_tokens)
return LLMResultChunk(
model=model,
prompt_messages=prompt_messages,
delta=LLMResultChunkDelta(
index=index,
message=message,
finish_reason=finish_reason,
usage=usage
)
)
tools_calls: list[AssistantPromptMessage.ToolCall] = []
finish_reason = "Unknown"
def increase_tool_call(new_tool_calls: list[AssistantPromptMessage.ToolCall]):
def get_tool_call(tool_name: str):
if not tool_name:
return tools_calls[-1]
tool_call = next((tool_call for tool_call in tools_calls if tool_call.function.name == tool_name), None)
if tool_call is None:
tool_call = AssistantPromptMessage.ToolCall(
id='',
type='',
function=AssistantPromptMessage.ToolCall.ToolCallFunction(name=tool_name, arguments="")
)
tools_calls.append(tool_call)
return tool_call
for new_tool_call in new_tool_calls:
# get tool call
tool_call = get_tool_call(new_tool_call.function.name)
# update tool call
if new_tool_call.id:
tool_call.id = new_tool_call.id
if new_tool_call.type:
tool_call.type = new_tool_call.type
if new_tool_call.function.name:
# remove the functions. prefix
if new_tool_call.function.name.startswith('functions.'):
parts = new_tool_call.function.name.split('functions.')
if len(parts) > 1:
new_tool_call.function.name = parts[1]
tool_call.function.name = new_tool_call.function.name
if new_tool_call.function.arguments:
tool_call.function.arguments += new_tool_call.function.arguments
for chunk in response.iter_lines(decode_unicode=True, delimiter="\n\n"):
if chunk:
# ignore sse comments
if chunk.startswith(':'):
continue
decoded_chunk = chunk.strip().lstrip('data: ').lstrip()
chunk_json = None
try:
chunk_json = json.loads(decoded_chunk)
# stream ended
except json.JSONDecodeError as e:
yield create_final_llm_result_chunk(
index=chunk_index + 1,
message=AssistantPromptMessage(content=""),
finish_reason="Non-JSON encountered."
)
break
if not chunk_json or len(chunk_json['choices']) == 0:
continue
choice = chunk_json['choices'][0]
finish_reason = chunk_json['choices'][0].get('finish_reason')
chunk_index += 1
if 'delta' in choice:
delta = choice['delta']
delta_content = delta.get('content')
assistant_message_tool_calls = delta.get('tool_calls', None)
# assistant_message_function_call = delta.delta.function_call
# extract tool calls from response
if assistant_message_tool_calls:
tool_calls = self._extract_response_tool_calls(assistant_message_tool_calls)
increase_tool_call(tool_calls)
if delta_content is None or delta_content == '':
continue
# transform assistant message to prompt message
assistant_prompt_message = AssistantPromptMessage(
content=delta_content,
tool_calls=tool_calls if assistant_message_tool_calls else []
)
full_assistant_content += delta_content
elif 'text' in choice:
choice_text = choice.get('text', '')
if choice_text == '':
continue
# transform assistant message to prompt message
assistant_prompt_message = AssistantPromptMessage(content=choice_text)
full_assistant_content += choice_text
else:
continue
# check payload indicator for completion
yield LLMResultChunk(
model=model,
prompt_messages=prompt_messages,
delta=LLMResultChunkDelta(
index=chunk_index,
message=assistant_prompt_message,
)
)
chunk_index += 1
if tools_calls:
yield LLMResultChunk(
model=model,
prompt_messages=prompt_messages,
delta=LLMResultChunkDelta(
index=chunk_index,
message=AssistantPromptMessage(
tool_calls=tools_calls,
content=""
),
)
)
yield create_final_llm_result_chunk(
index=chunk_index,
message=AssistantPromptMessage(content=""),
finish_reason=finish_reason
)
@@ -20,7 +20,6 @@ supported_model_types:
- llm
configurate_methods:
- predefined-model
- customizable-model
provider_credential_schema:
credential_form_schemas:
- variable: api_key
@@ -31,51 +30,3 @@ provider_credential_schema:
placeholder:
zh_Hans: 在此输入您的 API Key
en_US: Enter your API Key
model_credential_schema:
model:
label:
en_US: Model Name
zh_Hans: 模型名称
placeholder:
en_US: Enter your model name
zh_Hans: 输入模型名称
credential_form_schemas:
- variable: api_key
label:
en_US: API Key
type: secret-input
required: true
placeholder:
zh_Hans: 在此输入您的 API Key
en_US: Enter your API Key
- variable: context_size
label:
zh_Hans: 模型上下文长度
en_US: Model context size
required: true
type: text-input
default: '4096'
placeholder:
zh_Hans: 在此输入您的模型上下文长度
en_US: Enter your Model context size
- variable: max_tokens
label:
zh_Hans: 最大 token 上限
en_US: Upper bound for max tokens
default: '4096'
type: text-input
- variable: function_calling_type
label:
en_US: Function calling
type: select
required: false
default: no_call
options:
- value: no_call
label:
en_US: Not supported
zh_Hans: 不支持
- value: tool_call
label:
en_US: Tool Call
zh_Hans: Tool Call
@@ -378,34 +378,6 @@ class OAIAPICompatLargeLanguageModel(_CommonOAI_API_Compat, LargeLanguageModel):
delimiter = credentials.get("stream_mode_delimiter", "\n\n")
delimiter = codecs.decode(delimiter, "unicode_escape")
tools_calls: list[AssistantPromptMessage.ToolCall] = []
def increase_tool_call(new_tool_calls: list[AssistantPromptMessage.ToolCall]):
def get_tool_call(tool_call_id: str):
tool_call = next(
(tool_call for tool_call in tools_calls if tool_call.id == tool_call_id), None
)
if tool_call is None:
tool_call = AssistantPromptMessage.ToolCall(
id='',
type='function',
function=AssistantPromptMessage.ToolCall.ToolCallFunction(
name='',
arguments=''
)
)
tools_calls.append(tool_call)
return tool_call
for new_tool_call in new_tool_calls:
# get tool call
tool_call = get_tool_call(new_tool_call.id)
# update tool call
tool_call.id = new_tool_call.id
tool_call.type = new_tool_call.type
tool_call.function.name = new_tool_call.function.name
tool_call.function.arguments += new_tool_call.function.arguments
for chunk in response.iter_lines(decode_unicode=True, delimiter=delimiter):
if chunk:
# ignore sse comments
@@ -433,6 +405,8 @@ class OAIAPICompatLargeLanguageModel(_CommonOAI_API_Compat, LargeLanguageModel):
if 'delta' in choice:
delta = choice['delta']
delta_content = delta.get('content')
if delta_content is None or delta_content == '':
continue
assistant_message_tool_calls = delta.get('tool_calls', None)
# assistant_message_function_call = delta.delta.function_call
@@ -440,11 +414,6 @@ class OAIAPICompatLargeLanguageModel(_CommonOAI_API_Compat, LargeLanguageModel):
# extract tool calls from response
if assistant_message_tool_calls:
tool_calls = self._extract_response_tool_calls(assistant_message_tool_calls)
increase_tool_call(tool_calls)
if delta_content is None or delta_content == '':
continue
# function_call = self._extract_response_function_call(assistant_message_function_call)
# tool_calls = [function_call] if function_call else []
@@ -468,18 +437,6 @@ class OAIAPICompatLargeLanguageModel(_CommonOAI_API_Compat, LargeLanguageModel):
# check payload indicator for completion
if finish_reason is not None:
yield LLMResultChunk(
model=model,
prompt_messages=prompt_messages,
delta=LLMResultChunkDelta(
index=chunk_index,
message=AssistantPromptMessage(
tool_calls=tools_calls,
),
finish_reason=finish_reason
)
)
yield create_final_llm_result_chunk(
index=chunk_index,
message=assistant_prompt_message,
@@ -778,4 +735,4 @@ class OAIAPICompatLargeLanguageModel(_CommonOAI_API_Compat, LargeLanguageModel):
function=function
)
return tool_call
return tool_call
@@ -1,6 +1,6 @@
model: ernie-3.5-4k-0205
model: ernie-3.5-8k
label:
en_US: Ernie-3.5-4k-0205
en_US: Ernie-3.5-8K
model_type: llm
features:
- agent-thought
+65 -73
View File
@@ -24,64 +24,56 @@ class Jieba(BaseKeyword):
self._config = KeywordTableConfig()
def create(self, texts: list[Document], **kwargs) -> BaseKeyword:
lock_name = 'keyword_indexing_lock_{}'.format(self.dataset.id)
with redis_client.lock(lock_name, timeout=600):
keyword_table_handler = JiebaKeywordTableHandler()
keyword_table = self._get_dataset_keyword_table()
for text in texts:
keywords = keyword_table_handler.extract_keywords(text.page_content, self._config.max_keywords_per_chunk)
self._update_segment_keywords(self.dataset.id, text.metadata['doc_id'], list(keywords))
keyword_table = self._add_text_to_keyword_table(keyword_table, text.metadata['doc_id'], list(keywords))
keyword_table_handler = JiebaKeywordTableHandler()
keyword_table = self._get_dataset_keyword_table()
for text in texts:
keywords = keyword_table_handler.extract_keywords(text.page_content, self._config.max_keywords_per_chunk)
self._update_segment_keywords(self.dataset.id, text.metadata['doc_id'], list(keywords))
keyword_table = self._add_text_to_keyword_table(keyword_table, text.metadata['doc_id'], list(keywords))
self._save_dataset_keyword_table(keyword_table)
self._save_dataset_keyword_table(keyword_table)
return self
return self
def add_texts(self, texts: list[Document], **kwargs):
lock_name = 'keyword_indexing_lock_{}'.format(self.dataset.id)
with redis_client.lock(lock_name, timeout=600):
keyword_table_handler = JiebaKeywordTableHandler()
keyword_table_handler = JiebaKeywordTableHandler()
keyword_table = self._get_dataset_keyword_table()
keywords_list = kwargs.get('keywords_list', None)
for i in range(len(texts)):
text = texts[i]
if keywords_list:
keywords = keywords_list[i]
else:
keywords = keyword_table_handler.extract_keywords(text.page_content, self._config.max_keywords_per_chunk)
self._update_segment_keywords(self.dataset.id, text.metadata['doc_id'], list(keywords))
keyword_table = self._add_text_to_keyword_table(keyword_table, text.metadata['doc_id'], list(keywords))
keyword_table = self._get_dataset_keyword_table()
keywords_list = kwargs.get('keywords_list', None)
for i in range(len(texts)):
text = texts[i]
if keywords_list:
keywords = keywords_list[i]
else:
keywords = keyword_table_handler.extract_keywords(text.page_content, self._config.max_keywords_per_chunk)
self._update_segment_keywords(self.dataset.id, text.metadata['doc_id'], list(keywords))
keyword_table = self._add_text_to_keyword_table(keyword_table, text.metadata['doc_id'], list(keywords))
self._save_dataset_keyword_table(keyword_table)
self._save_dataset_keyword_table(keyword_table)
def text_exists(self, id: str) -> bool:
keyword_table = self._get_dataset_keyword_table()
return id in set.union(*keyword_table.values())
def delete_by_ids(self, ids: list[str]) -> None:
lock_name = 'keyword_indexing_lock_{}'.format(self.dataset.id)
with redis_client.lock(lock_name, timeout=600):
keyword_table = self._get_dataset_keyword_table()
keyword_table = self._delete_ids_from_keyword_table(keyword_table, ids)
keyword_table = self._get_dataset_keyword_table()
keyword_table = self._delete_ids_from_keyword_table(keyword_table, ids)
self._save_dataset_keyword_table(keyword_table)
self._save_dataset_keyword_table(keyword_table)
def delete_by_document_id(self, document_id: str):
lock_name = 'keyword_indexing_lock_{}'.format(self.dataset.id)
with redis_client.lock(lock_name, timeout=600):
# get segment ids by document_id
segments = db.session.query(DocumentSegment).filter(
DocumentSegment.dataset_id == self.dataset.id,
DocumentSegment.document_id == document_id
).all()
# get segment ids by document_id
segments = db.session.query(DocumentSegment).filter(
DocumentSegment.dataset_id == self.dataset.id,
DocumentSegment.document_id == document_id
).all()
ids = [segment.index_node_id for segment in segments]
ids = [segment.index_node_id for segment in segments]
keyword_table = self._get_dataset_keyword_table()
keyword_table = self._delete_ids_from_keyword_table(keyword_table, ids)
keyword_table = self._get_dataset_keyword_table()
keyword_table = self._delete_ids_from_keyword_table(keyword_table, ids)
self._save_dataset_keyword_table(keyword_table)
self._save_dataset_keyword_table(keyword_table)
def search(
self, query: str,
@@ -114,15 +106,13 @@ class Jieba(BaseKeyword):
return documents
def delete(self) -> None:
lock_name = 'keyword_indexing_lock_{}'.format(self.dataset.id)
with redis_client.lock(lock_name, timeout=600):
dataset_keyword_table = self.dataset.dataset_keyword_table
if dataset_keyword_table:
db.session.delete(dataset_keyword_table)
db.session.commit()
if dataset_keyword_table.data_source_type != 'database':
file_key = 'keyword_files/' + self.dataset.tenant_id + '/' + self.dataset.id + '.txt'
storage.delete(file_key)
dataset_keyword_table = self.dataset.dataset_keyword_table
if dataset_keyword_table:
db.session.delete(dataset_keyword_table)
db.session.commit()
if dataset_keyword_table.data_source_type != 'database':
file_key = 'keyword_files/' + self.dataset.tenant_id + '/' + self.dataset.id + '.txt'
storage.delete(file_key)
def _save_dataset_keyword_table(self, keyword_table):
keyword_table_dict = {
@@ -145,31 +135,33 @@ class Jieba(BaseKeyword):
storage.save(file_key, json.dumps(keyword_table_dict, cls=SetEncoder).encode('utf-8'))
def _get_dataset_keyword_table(self) -> Optional[dict]:
dataset_keyword_table = self.dataset.dataset_keyword_table
if dataset_keyword_table:
keyword_table_dict = dataset_keyword_table.keyword_table_dict
if keyword_table_dict:
return keyword_table_dict['__data__']['table']
else:
keyword_data_source_type = current_app.config['KEYWORD_DATA_SOURCE_TYPE']
dataset_keyword_table = DatasetKeywordTable(
dataset_id=self.dataset.id,
keyword_table='',
data_source_type=keyword_data_source_type,
)
if keyword_data_source_type == 'database':
dataset_keyword_table.keyword_table = json.dumps({
'__type__': 'keyword_table',
'__data__': {
"index_id": self.dataset.id,
"summary": None,
"table": {}
}
}, cls=SetEncoder)
db.session.add(dataset_keyword_table)
db.session.commit()
lock_name = 'keyword_indexing_lock_{}'.format(self.dataset.id)
with redis_client.lock(lock_name, timeout=20):
dataset_keyword_table = self.dataset.dataset_keyword_table
if dataset_keyword_table:
keyword_table_dict = dataset_keyword_table.keyword_table_dict
if keyword_table_dict:
return keyword_table_dict['__data__']['table']
else:
keyword_data_source_type = current_app.config['KEYWORD_DATA_SOURCE_TYPE']
dataset_keyword_table = DatasetKeywordTable(
dataset_id=self.dataset.id,
keyword_table='',
data_source_type=keyword_data_source_type,
)
if keyword_data_source_type == 'database':
dataset_keyword_table.keyword_table = json.dumps({
'__type__': 'keyword_table',
'__data__': {
"index_id": self.dataset.id,
"summary": None,
"table": {}
}
}, cls=SetEncoder)
db.session.add(dataset_keyword_table)
db.session.commit()
return {}
return {}
def _add_text_to_keyword_table(self, keyword_table: dict, id: str, keywords: list[str]) -> dict:
for keyword in keywords:
@@ -20,17 +20,16 @@ class MilvusConfig(BaseModel):
password: str
secure: bool = False
batch_size: int = 100
database: str = "default"
@root_validator()
def validate_config(cls, values: dict) -> dict:
if not values.get('host'):
if not values['host']:
raise ValueError("config MILVUS_HOST is required")
if not values.get('port'):
if not values['port']:
raise ValueError("config MILVUS_PORT is required")
if not values.get('user'):
if not values['user']:
raise ValueError("config MILVUS_USER is required")
if not values.get('password'):
if not values['password']:
raise ValueError("config MILVUS_PASSWORD is required")
return values
@@ -40,8 +39,7 @@ class MilvusConfig(BaseModel):
'port': self.port,
'user': self.user,
'password': self.password,
'secure': self.secure,
'db_name': self.database,
'secure': self.secure
}
@@ -130,8 +128,7 @@ class MilvusVector(BaseVector):
uri = "https://" + str(self._client_config.host) + ":" + str(self._client_config.port)
else:
uri = "http://" + str(self._client_config.host) + ":" + str(self._client_config.port)
connections.connect(alias=alias, uri=uri, user=self._client_config.user, password=self._client_config.password,
db_name=self._client_config.database)
connections.connect(alias=alias, uri=uri, user=self._client_config.user, password=self._client_config.password)
from pymilvus import utility
if utility.has_collection(self._collection_name, using=alias):
@@ -143,8 +140,7 @@ class MilvusVector(BaseVector):
uri = "https://" + str(self._client_config.host) + ":" + str(self._client_config.port)
else:
uri = "http://" + str(self._client_config.host) + ":" + str(self._client_config.port)
connections.connect(alias=alias, uri=uri, user=self._client_config.user, password=self._client_config.password,
db_name=self._client_config.database)
connections.connect(alias=alias, uri=uri, user=self._client_config.user, password=self._client_config.password)
from pymilvus import utility
if not utility.has_collection(self._collection_name, using=alias):
@@ -196,7 +192,7 @@ class MilvusVector(BaseVector):
else:
uri = "http://" + str(self._client_config.host) + ":" + str(self._client_config.port)
connections.connect(alias=alias, uri=uri, user=self._client_config.user,
password=self._client_config.password, db_name=self._client_config.database)
password=self._client_config.password)
if not utility.has_collection(self._collection_name, using=alias):
from pymilvus import CollectionSchema, DataType, FieldSchema
from pymilvus.orm.types import infer_dtype_bydata
@@ -110,7 +110,6 @@ class Vector:
user=config.get('MILVUS_USER'),
password=config.get('MILVUS_PASSWORD'),
secure=config.get('MILVUS_SECURE'),
database=config.get('MILVUS_DATABASE'),
)
)
else:
+16 -20
View File
@@ -2,8 +2,6 @@
import csv
from typing import Optional
import pandas as pd
from core.rag.extractor.extractor_base import BaseExtractor
from core.rag.extractor.helpers import detect_file_encodings
from core.rag.models.document import Document
@@ -54,23 +52,21 @@ class CSVExtractor(BaseExtractor):
def _read_from_file(self, csvfile) -> list[Document]:
docs = []
try:
# load csv file into pandas dataframe
df = pd.read_csv(csvfile, error_bad_lines=False, **self.csv_args)
# check source column exists
if self.source_column and self.source_column not in df.columns:
raise ValueError(f"Source column '{self.source_column}' not found in CSV file.")
# create document objects
for i, row in df.iterrows():
content = ";".join(f"{col.strip()}: {str(row[col]).strip()}" for col in df.columns)
source = row[self.source_column] if self.source_column else ''
metadata = {"source": source, "row": i}
doc = Document(page_content=content, metadata=metadata)
docs.append(doc)
except csv.Error as e:
raise e
csv_reader = csv.DictReader(csvfile, **self.csv_args) # type: ignore
for i, row in enumerate(csv_reader):
content = "\n".join(f"{k.strip()}: {v.strip()}" for k, v in row.items())
try:
source = (
row[self.source_column]
if self.source_column is not None
else ''
)
except KeyError:
raise ValueError(
f"Source column '{self.source_column}' not found in CSV file."
)
metadata = {"source": source, "row": i}
doc = Document(page_content=content, metadata=metadata)
docs.append(doc)
return docs
+19 -16
View File
@@ -1,7 +1,7 @@
"""Abstract interface for document loader implementations."""
from typing import Optional
import pandas as pd
from openpyxl.reader.excel import load_workbook
from core.rag.extractor.extractor_base import BaseExtractor
from core.rag.models.document import Document
@@ -27,21 +27,24 @@ class ExcelExtractor(BaseExtractor):
self._autodetect_encoding = autodetect_encoding
def extract(self) -> list[Document]:
"""Load from file path using Pandas."""
"""Load from file path."""
data = []
# 使用 Pandas 读取 Excel 文件的每个工作表
xls = pd.ExcelFile(self._file_path)
for sheet_name in xls.sheet_names:
df = pd.read_excel(xls, sheet_name=sheet_name)
# filter out rows with all NaN values
df.dropna(how='all', inplace=True)
# transform each row into a Document
for _, row in df.iterrows():
item = ';'.join(f'{k}:{v}' for k, v in row.items() if pd.notna(v))
document = Document(page_content=item, metadata={'source': self._file_path})
data.append(document)
wb = load_workbook(filename=self._file_path, read_only=True)
# loop over all sheets
for sheet in wb:
keys = []
if 'A1:A1' == sheet.calculate_dimension():
sheet.reset_dimensions()
for row in sheet.iter_rows(values_only=True):
if all(v is None for v in row):
continue
if keys == []:
keys = list(map(str, row))
else:
row_dict = dict(zip(keys, list(map(str, row))))
row_dict = {k: v for k, v in row_dict.items() if v}
item = ''.join(f'{k}:{v};' for k, v in row_dict.items())
document = Document(page_content=item, metadata={'source': self._file_path})
data.append(document)
return data
@@ -26,7 +26,7 @@ class UnstructuredEmailExtractor(BaseExtractor):
def extract(self) -> list[Document]:
from unstructured.partition.email import partition_email
elements = partition_email(filename=self._file_path)
elements = partition_email(filename=self._file_path, api_url=self._api_url)
# noinspection PyBroadException
try:
@@ -36,7 +36,7 @@ class UnstructuredMarkdownExtractor(BaseExtractor):
def extract(self) -> list[Document]:
from unstructured.partition.md import partition_md
elements = partition_md(filename=self._file_path)
elements = partition_md(filename=self._file_path, api_url=self._api_url)
from unstructured.chunking.title import chunk_by_title
chunks = chunk_by_title(elements, max_characters=2000, combine_text_under_n_chars=2000)
documents = []
@@ -26,7 +26,7 @@ class UnstructuredMsgExtractor(BaseExtractor):
def extract(self) -> list[Document]:
from unstructured.partition.msg import partition_msg
elements = partition_msg(filename=self._file_path)
elements = partition_msg(filename=self._file_path, api_url=self._api_url)
from unstructured.chunking.title import chunk_by_title
chunks = chunk_by_title(elements, max_characters=2000, combine_text_under_n_chars=2000)
documents = []
@@ -24,9 +24,9 @@ class UnstructuredPPTExtractor(BaseExtractor):
self._api_url = api_url
def extract(self) -> list[Document]:
from unstructured.partition.api import partition_via_api
from unstructured.partition.ppt import partition_ppt
elements = partition_via_api(filename=self._file_path, api_url=self._api_url)
elements = partition_ppt(filename=self._file_path, api_url=self._api_url)
text_by_page = {}
for element in elements:
page = element.metadata.page_number
@@ -26,7 +26,7 @@ class UnstructuredPPTXExtractor(BaseExtractor):
def extract(self) -> list[Document]:
from unstructured.partition.pptx import partition_pptx
elements = partition_pptx(filename=self._file_path)
elements = partition_pptx(filename=self._file_path, api_url=self._api_url)
text_by_page = {}
for element in elements:
page = element.metadata.page_number
@@ -26,7 +26,7 @@ class UnstructuredTextExtractor(BaseExtractor):
def extract(self) -> list[Document]:
from unstructured.partition.text import partition_text
elements = partition_text(filename=self._file_path)
elements = partition_text(filename=self._file_path, api_url=self._api_url)
from unstructured.chunking.title import chunk_by_title
chunks = chunk_by_title(elements, max_characters=2000, combine_text_under_n_chars=2000)
documents = []
@@ -26,7 +26,7 @@ class UnstructuredXmlExtractor(BaseExtractor):
def extract(self) -> list[Document]:
from unstructured.partition.xml import partition_xml
elements = partition_xml(filename=self._file_path, xml_keep_tags=True)
elements = partition_xml(filename=self._file_path, xml_keep_tags=True, api_url=self._api_url)
from unstructured.chunking.title import chunk_by_title
chunks = chunk_by_title(elements, max_characters=2000, combine_text_under_n_chars=2000)
documents = []
+1 -1
View File
@@ -94,7 +94,7 @@ class ApiBasedToolProviderController(ToolProviderController):
'icon': db_provider.icon,
},
'credentials_schema': credentials_schema,
'provider_id': db_provider.id or '',
'provider_id': db_provider.id,
})
@property
@@ -1,92 +1,11 @@
import logging
from typing import Any, Optional
from typing import Any
import arxiv
from langchain.utilities import ArxivAPIWrapper
from pydantic import BaseModel, Field
from core.tools.entities.tool_entities import ToolInvokeMessage
from core.tools.tool.builtin_tool import BuiltinTool
logger = logging.getLogger(__name__)
class ArxivAPIWrapper(BaseModel):
"""Wrapper around ArxivAPI.
To use, you should have the ``arxiv`` python package installed.
https://lukasschwab.me/arxiv.py/index.html
This wrapper will use the Arxiv API to conduct searches and
fetch document summaries. By default, it will return the document summaries
of the top-k results.
It limits the Document content by doc_content_chars_max.
Set doc_content_chars_max=None if you don't want to limit the content size.
Args:
top_k_results: number of the top-scored document used for the arxiv tool
ARXIV_MAX_QUERY_LENGTH: the cut limit on the query used for the arxiv tool.
load_max_docs: a limit to the number of loaded documents
load_all_available_meta:
if True: the `metadata` of the loaded Documents contains all available
meta info (see https://lukasschwab.me/arxiv.py/index.html#Result),
if False: the `metadata` contains only the published date, title,
authors and summary.
doc_content_chars_max: an optional cut limit for the length of a document's
content
Example:
.. code-block:: python
arxiv = ArxivAPIWrapper(
top_k_results = 3,
ARXIV_MAX_QUERY_LENGTH = 300,
load_max_docs = 3,
load_all_available_meta = False,
doc_content_chars_max = 40000
)
arxiv.run("tree of thought llm)
"""
arxiv_search = arxiv.Search #: :meta private:
arxiv_exceptions = (
arxiv.ArxivError,
arxiv.UnexpectedEmptyPageError,
arxiv.HTTPError,
) # :meta private:
top_k_results: int = 3
ARXIV_MAX_QUERY_LENGTH = 300
load_max_docs: int = 100
load_all_available_meta: bool = False
doc_content_chars_max: Optional[int] = 4000
def run(self, query: str) -> str:
"""
Performs an arxiv search and A single string
with the publish date, title, authors, and summary
for each article separated by two newlines.
If an error occurs or no documents found, error text
is returned instead. Wrapper for
https://lukasschwab.me/arxiv.py/index.html#Search
Args:
query: a plaintext search query
""" # noqa: E501
try:
results = self.arxiv_search( # type: ignore
query[: self.ARXIV_MAX_QUERY_LENGTH], max_results=self.top_k_results
).results()
except self.arxiv_exceptions as ex:
return f"Arxiv exception: {ex}"
docs = [
f"Published: {result.updated.date()}\n"
f"Title: {result.title}\n"
f"Authors: {', '.join(a.name for a in result.authors)}\n"
f"Summary: {result.summary}"
for result in results
]
if docs:
return "\n\n".join(docs)[: self.doc_content_chars_max]
else:
return "No good Arxiv Result was found"
class ArxivSearchInput(BaseModel):
query: str = Field(..., description="Search query.")
@@ -1,95 +1,11 @@
import json
from typing import Any, Optional
from typing import Any
import requests
from pydantic import BaseModel, Field
from langchain.tools import BraveSearch
from core.tools.entities.tool_entities import ToolInvokeMessage
from core.tools.tool.builtin_tool import BuiltinTool
class BraveSearchWrapper(BaseModel):
"""Wrapper around the Brave search engine."""
api_key: str
"""The API key to use for the Brave search engine."""
search_kwargs: dict = Field(default_factory=dict)
"""Additional keyword arguments to pass to the search request."""
base_url = "https://api.search.brave.com/res/v1/web/search"
"""The base URL for the Brave search engine."""
def run(self, query: str) -> str:
"""Query the Brave search engine and return the results as a JSON string.
Args:
query: The query to search for.
Returns: The results as a JSON string.
"""
web_search_results = self._search_request(query=query)
final_results = [
{
"title": item.get("title"),
"link": item.get("url"),
"snippet": item.get("description"),
}
for item in web_search_results
]
return json.dumps(final_results)
def _search_request(self, query: str) -> list[dict]:
headers = {
"X-Subscription-Token": self.api_key,
"Accept": "application/json",
}
req = requests.PreparedRequest()
params = {**self.search_kwargs, **{"q": query}}
req.prepare_url(self.base_url, params)
if req.url is None:
raise ValueError("prepared url is None, this should not happen")
response = requests.get(req.url, headers=headers)
if not response.ok:
raise Exception(f"HTTP error {response.status_code}")
return response.json().get("web", {}).get("results", [])
class BraveSearch(BaseModel):
"""Tool that queries the BraveSearch."""
name = "brave_search"
description = (
"a search engine. "
"useful for when you need to answer questions about current events."
" input should be a search query."
)
search_wrapper: BraveSearchWrapper
@classmethod
def from_api_key(
cls, api_key: str, search_kwargs: Optional[dict] = None, **kwargs: Any
) -> "BraveSearch":
"""Create a tool from an api key.
Args:
api_key: The api key to use.
search_kwargs: Any additional kwargs to pass to the search wrapper.
**kwargs: Any additional kwargs to pass to the tool.
Returns:
A tool.
"""
wrapper = BraveSearchWrapper(api_key=api_key, search_kwargs=search_kwargs or {})
return cls(search_wrapper=wrapper, **kwargs)
def _run(
self,
query: str,
) -> str:
"""Use the tool."""
return self.search_wrapper.run(query)
class BraveSearchTool(BuiltinTool):
"""
Tool for performing a search using Brave search engine.
@@ -115,7 +31,7 @@ class BraveSearchTool(BuiltinTool):
tool = BraveSearch.from_api_key(api_key=api_key, search_kwargs={"count": count})
results = tool._run(query)
results = tool.run(query)
if not results:
return self.create_text_message(f"No results found for '{query}' in Tavily")
@@ -1,147 +1,16 @@
from typing import Any, Optional
from typing import Any
from langchain.tools import DuckDuckGoSearchRun
from pydantic import BaseModel, Field
from core.tools.entities.tool_entities import ToolInvokeMessage
from core.tools.tool.builtin_tool import BuiltinTool
class DuckDuckGoSearchAPIWrapper(BaseModel):
"""Wrapper for DuckDuckGo Search API.
Free and does not require any setup.
"""
region: Optional[str] = "wt-wt"
safesearch: str = "moderate"
time: Optional[str] = "y"
max_results: int = 5
def get_snippets(self, query: str) -> list[str]:
"""Run query through DuckDuckGo and return concatenated results."""
from duckduckgo_search import DDGS
with DDGS() as ddgs:
results = ddgs.text(
query,
region=self.region,
safesearch=self.safesearch,
timelimit=self.time,
)
if results is None:
return ["No good DuckDuckGo Search Result was found"]
snippets = []
for i, res in enumerate(results, 1):
if res is not None:
snippets.append(res["body"])
if len(snippets) == self.max_results:
break
return snippets
def run(self, query: str) -> str:
snippets = self.get_snippets(query)
return " ".join(snippets)
def results(
self, query: str, num_results: int, backend: str = "api"
) -> list[dict[str, str]]:
"""Run query through DuckDuckGo and return metadata.
Args:
query: The query to search for.
num_results: The number of results to return.
Returns:
A list of dictionaries with the following keys:
snippet - The description of the result.
title - The title of the result.
link - The link to the result.
"""
from duckduckgo_search import DDGS
with DDGS() as ddgs:
results = ddgs.text(
query,
region=self.region,
safesearch=self.safesearch,
timelimit=self.time,
backend=backend,
)
if results is None:
return [{"Result": "No good DuckDuckGo Search Result was found"}]
def to_metadata(result: dict) -> dict[str, str]:
if backend == "news":
return {
"date": result["date"],
"title": result["title"],
"snippet": result["body"],
"source": result["source"],
"link": result["url"],
}
return {
"snippet": result["body"],
"title": result["title"],
"link": result["href"],
}
formatted_results = []
for i, res in enumerate(results, 1):
if res is not None:
formatted_results.append(to_metadata(res))
if len(formatted_results) == num_results:
break
return formatted_results
class DuckDuckGoSearchRun(BaseModel):
"""Tool that queries the DuckDuckGo search API."""
name = "duckduckgo_search"
description = (
"A wrapper around DuckDuckGo Search. "
"Useful for when you need to answer questions about current events. "
"Input should be a search query."
)
api_wrapper: DuckDuckGoSearchAPIWrapper = Field(
default_factory=DuckDuckGoSearchAPIWrapper
)
def _run(
self,
query: str,
) -> str:
"""Use the tool."""
return self.api_wrapper.run(query)
class DuckDuckGoSearchResults(BaseModel):
"""Tool that queries the DuckDuckGo search API and gets back json."""
name = "DuckDuckGo Results JSON"
description = (
"A wrapper around Duck Duck Go Search. "
"Useful for when you need to answer questions about current events. "
"Input should be a search query. Output is a JSON array of the query results"
)
num_results: int = 4
api_wrapper: DuckDuckGoSearchAPIWrapper = Field(
default_factory=DuckDuckGoSearchAPIWrapper
)
backend: str = "api"
def _run(
self,
query: str,
) -> str:
"""Use the tool."""
res = self.api_wrapper.results(query, self.num_results, backend=self.backend)
res_strs = [", ".join([f"{k}: {v}" for k, v in d.items()]) for d in res]
return ", ".join([f"[{rs}]" for rs in res_strs])
class DuckDuckGoInput(BaseModel):
query: str = Field(..., description="Search query.")
class DuckDuckGoSearchTool(BuiltinTool):
"""
Tool for performing a search using DuckDuckGo search engine.
@@ -165,7 +34,7 @@ class DuckDuckGoSearchTool(BuiltinTool):
tool = DuckDuckGoSearchRun(args_schema=DuckDuckGoInput)
result = tool._run(query)
result = tool.run(query)
return self.create_text_message(self.summary(user_id=user_id, content=result))
@@ -70,44 +70,43 @@ class SerpAPI:
raise ValueError(f"Got error from SerpAPI: {res['error']}")
if typ == "text":
toret = ""
if "answer_box" in res.keys() and type(res["answer_box"]) == list:
res["answer_box"] = res["answer_box"][0] + "\n"
res["answer_box"] = res["answer_box"][0]
if "answer_box" in res.keys() and "answer" in res["answer_box"].keys():
toret += res["answer_box"]["answer"] + "\n"
if "answer_box" in res.keys() and "snippet" in res["answer_box"].keys():
toret += res["answer_box"]["snippet"] + "\n"
if (
toret = res["answer_box"]["answer"]
elif "answer_box" in res.keys() and "snippet" in res["answer_box"].keys():
toret = res["answer_box"]["snippet"]
elif (
"answer_box" in res.keys()
and "snippet_highlighted_words" in res["answer_box"].keys()
):
for item in res["answer_box"]["snippet_highlighted_words"]:
toret += item + "\n"
if (
toret = res["answer_box"]["snippet_highlighted_words"][0]
elif (
"sports_results" in res.keys()
and "game_spotlight" in res["sports_results"].keys()
):
toret += res["sports_results"]["game_spotlight"] + "\n"
if (
toret = res["sports_results"]["game_spotlight"]
elif (
"shopping_results" in res.keys()
and "title" in res["shopping_results"][0].keys()
):
toret += res["shopping_results"][:3] + "\n"
if (
toret = res["shopping_results"][:3]
elif (
"knowledge_graph" in res.keys()
and "description" in res["knowledge_graph"].keys()
):
toret = res["knowledge_graph"]["description"] + "\n"
if "snippet" in res["organic_results"][0].keys():
for item in res["organic_results"]:
toret += "content: " + item["snippet"] + "\n" + "link: " + item["link"] + "\n"
if (
toret = res["knowledge_graph"]["description"]
elif "snippet" in res["organic_results"][0].keys():
toret = res["organic_results"][0]["snippet"]
elif "link" in res["organic_results"][0].keys():
toret = res["organic_results"][0]["link"]
elif (
"images_results" in res.keys()
and "thumbnail" in res["images_results"][0].keys()
):
thumbnails = [item["thumbnail"] for item in res["images_results"][:10]]
toret = thumbnails
if toret == "":
else:
toret = "No good search result found"
elif typ == "link":
if "knowledge_graph" in res.keys() and "title" in res["knowledge_graph"].keys() \
@@ -1,187 +1,16 @@
import json
import time
import urllib.error
import urllib.parse
import urllib.request
from typing import Any
from langchain.tools import PubmedQueryRun
from pydantic import BaseModel, Field
from core.tools.entities.tool_entities import ToolInvokeMessage
from core.tools.tool.builtin_tool import BuiltinTool
class PubMedAPIWrapper(BaseModel):
"""
Wrapper around PubMed API.
This wrapper will use the PubMed API to conduct searches and fetch
document summaries. By default, it will return the document summaries
of the top-k results of an input search.
Parameters:
top_k_results: number of the top-scored document used for the PubMed tool
load_max_docs: a limit to the number of loaded documents
load_all_available_meta:
if True: the `metadata` of the loaded Documents gets all available meta info
(see https://www.ncbi.nlm.nih.gov/books/NBK25499/#chapter4.ESearch)
if False: the `metadata` gets only the most informative fields.
"""
base_url_esearch = "https://eutils.ncbi.nlm.nih.gov/entrez/eutils/esearch.fcgi?"
base_url_efetch = "https://eutils.ncbi.nlm.nih.gov/entrez/eutils/efetch.fcgi?"
max_retry = 5
sleep_time = 0.2
# Default values for the parameters
top_k_results: int = 3
load_max_docs: int = 25
ARXIV_MAX_QUERY_LENGTH = 300
doc_content_chars_max: int = 2000
load_all_available_meta: bool = False
email: str = "your_email@example.com"
def run(self, query: str) -> str:
"""
Run PubMed search and get the article meta information.
See https://www.ncbi.nlm.nih.gov/books/NBK25499/#chapter4.ESearch
It uses only the most informative fields of article meta information.
"""
try:
# Retrieve the top-k results for the query
docs = [
f"Published: {result['pub_date']}\nTitle: {result['title']}\n"
f"Summary: {result['summary']}"
for result in self.load(query[: self.ARXIV_MAX_QUERY_LENGTH])
]
# Join the results and limit the character count
return (
"\n\n".join(docs)[:self.doc_content_chars_max]
if docs
else "No good PubMed Result was found"
)
except Exception as ex:
return f"PubMed exception: {ex}"
def load(self, query: str) -> list[dict]:
"""
Search PubMed for documents matching the query.
Return a list of dictionaries containing the document metadata.
"""
url = (
self.base_url_esearch
+ "db=pubmed&term="
+ str({urllib.parse.quote(query)})
+ f"&retmode=json&retmax={self.top_k_results}&usehistory=y"
)
result = urllib.request.urlopen(url)
text = result.read().decode("utf-8")
json_text = json.loads(text)
articles = []
webenv = json_text["esearchresult"]["webenv"]
for uid in json_text["esearchresult"]["idlist"]:
article = self.retrieve_article(uid, webenv)
articles.append(article)
# Convert the list of articles to a JSON string
return articles
def retrieve_article(self, uid: str, webenv: str) -> dict:
url = (
self.base_url_efetch
+ "db=pubmed&retmode=xml&id="
+ uid
+ "&webenv="
+ webenv
)
retry = 0
while True:
try:
result = urllib.request.urlopen(url)
break
except urllib.error.HTTPError as e:
if e.code == 429 and retry < self.max_retry:
# Too Many Requests error
# wait for an exponentially increasing amount of time
print(
f"Too Many Requests, "
f"waiting for {self.sleep_time:.2f} seconds..."
)
time.sleep(self.sleep_time)
self.sleep_time *= 2
retry += 1
else:
raise e
xml_text = result.read().decode("utf-8")
# Get title
title = ""
if "<ArticleTitle>" in xml_text and "</ArticleTitle>" in xml_text:
start_tag = "<ArticleTitle>"
end_tag = "</ArticleTitle>"
title = xml_text[
xml_text.index(start_tag) + len(start_tag) : xml_text.index(end_tag)
]
# Get abstract
abstract = ""
if "<AbstractText>" in xml_text and "</AbstractText>" in xml_text:
start_tag = "<AbstractText>"
end_tag = "</AbstractText>"
abstract = xml_text[
xml_text.index(start_tag) + len(start_tag) : xml_text.index(end_tag)
]
# Get publication date
pub_date = ""
if "<PubDate>" in xml_text and "</PubDate>" in xml_text:
start_tag = "<PubDate>"
end_tag = "</PubDate>"
pub_date = xml_text[
xml_text.index(start_tag) + len(start_tag) : xml_text.index(end_tag)
]
# Return article as dictionary
article = {
"uid": uid,
"title": title,
"summary": abstract,
"pub_date": pub_date,
}
return article
class PubmedQueryRun(BaseModel):
"""Tool that searches the PubMed API."""
name = "PubMed"
description = (
"A wrapper around PubMed.org "
"Useful for when you need to answer questions about Physics, Mathematics, "
"Computer Science, Quantitative Biology, Quantitative Finance, Statistics, "
"Electrical Engineering, and Economics "
"from scientific articles on PubMed.org. "
"Input should be a search query."
)
api_wrapper: PubMedAPIWrapper = Field(default_factory=PubMedAPIWrapper)
def _run(
self,
query: str,
) -> str:
"""Use the Arxiv tool."""
return self.api_wrapper.run(query)
class PubMedInput(BaseModel):
query: str = Field(..., description="Search query.")
class PubMedSearchTool(BuiltinTool):
"""
Tool for performing a search using PubMed search engine.
@@ -205,7 +34,7 @@ class PubMedSearchTool(BuiltinTool):
tool = PubmedQueryRun(args_schema=PubMedInput)
result = tool._run(query)
result = tool.run(query)
return self.create_text_message(self.summary(user_id=user_id, content=result))
@@ -6,9 +6,9 @@ identity:
zh_Hans: 获取 Stack Exchange 答案
description:
human:
en_US: A tool for retrieving answers for a specific Stack Exchange question ID. Must be used with the searchStackExQuesID tool.
zh_Hans: 用于检索特定Stack Exchange问题ID的答案的工具。必须与searchStackExQuesID工具一起使用。
llm: A tool for retrieving answers for Stack Exchange question ID.
en_US: A tool for retrieving answers for a specific Stack Exchange question ID. Specify the question ID, Stack Exchange site, sorting order, number of results per page, and page number. Must be used with the searchStackExQuesID tool.
zh_Hans: 用于检索特定Stack Exchange问题ID的答案的工具。指定问题ID、Stack Exchange站点、排序顺序、每页结果数和页码。 必须与searchStackExQuesID工具一起使用。
llm: A tool for retrieving answers for a specific Stack Exchange question ID based on the provided parameters.
parameters:
- name: id
type: string
@@ -30,8 +30,108 @@ parameters:
human_description:
en_US: The Stack Exchange site the question is from, e.g. stackoverflow, unix, etc.
zh_Hans: 问题所在的Stack Exchange站点,例如stackoverflow、unix等。
llm_description: Stack Exchange site identifier - 'stackoverflow', 'serverfault', 'superuser', 'askubuntu', 'unix', 'cs', 'softwareengineering', 'codegolf', 'codereview', 'cstheory', 'security', 'cryptography', 'reverseengineering', 'datascience', 'devops', 'ux', 'dba', 'gis', 'webmasters', 'arduino', 'raspberrypi', 'networkengineering', 'iot', 'tor', 'sqa', 'mathoverflow', 'math', 'mathematica', 'dsp', 'gamedev', 'robotics', 'genai', 'computergraphics'.
form: llm
llm_description: The Stack Exchange site identifier.
options:
- value: stackoverflow
label:
en_US: stackoverflow
- value: serverfault
label:
en_US: serverfault
- value: superuser
label:
en_US: superuser
- value: askubuntu
label:
en_US: askubuntu
- value: unix
label:
en_US: unix
- value: cs
label:
en_US: cs
- value: softwareengineering
label:
en_US: softwareengineering
- value: codegolf
label:
en_US: codegolf
- value: codereview
label:
en_US: codereview
- value: cstheory
label:
en_US: cstheory
- value: security
label:
en_US: security
- value: cryptography
label:
en_US: cryptography
- value: reverseengineering
label:
en_US: reverseengineering
- value: datascience
label:
en_US: datascience
- value: devops
label:
en_US: devops
- value: ux
label:
en_US: ux
- value: dba
label:
en_US: dba
- value: gis
label:
en_US: gis
- value: webmasters
label:
en_US: webmasters
- value: arduino
label:
en_US: arduino
- value: raspberrypi
label:
en_US: raspberrypi
- value: networkengineering
label:
en_US: networkengineering
- value: iot
label:
en_US: iot
- value: tor
label:
en_US: tor
- value: sqa
label:
en_US: sqa
- value: mathoverflow
label:
en_US: mathoverflow
- value: math
label:
en_US: math
- value: mathematica
label:
en_US: mathematica
- value: dsp
label:
en_US: dsp
- value: gamedev
label:
en_US: gamedev
- value: robotics
label:
en_US: robotics
- value: genai
label:
en_US: genai
- value: computergraphics
label:
en_US: computergraphics
form: form
- name: filter
type: string
required: true
@@ -40,14 +140,9 @@ parameters:
zh_Hans: 过滤器
human_description:
en_US: This is required in order to actually get the body of the answer.
zh_Hans: 为了实际获取答案的正文是必需的。
options:
- value: "!nNPvSNdWme"
label:
en_US: Must Select
zh_Hans: 必须选择
form: form
default: "!nNPvSNdWme"
zh_Hans: 为了实际获取答案的正文,这是必需的。
llm_description: Required in order to actually get the body of the answer. Must be \"!nNPvSNdWme\".
form: llm
- name: order
type: string
required: true
@@ -57,17 +152,8 @@ parameters:
human_description:
en_US: The direction to sort the answers - ascending or descending.
zh_Hans: 答案的排序方向 - 升序或降序。
form: form
options:
- value: asc
label:
en_US: Ascending
zh_Hans: 升序
- value: desc
label:
en_US: Descending
zh_Hans: 降序
default: desc
llm_description: asc for ascending, desc for descending.
form: llm
- name: sort
type: string
required: true
@@ -88,10 +174,8 @@ parameters:
human_description:
en_US: The number of answers to return per page.
zh_Hans: 每页返回的答案数。
form: form
min: 1
max: 5
default: 1
llm_description: The number of answers per page.
form: llm
- name: page
type: number
required: true
@@ -101,7 +185,5 @@ parameters:
human_description:
en_US: The page number of answers to retrieve.
zh_Hans: 要检索的答案的页码。
form: form
min: 1
max: 5
default: 3
llm_description: The page number to retrieve.
form: llm
@@ -6,9 +6,9 @@ identity:
zh_Hans: 搜索Stack Exchange问题
description:
human:
en_US: A tool for searching questions on a Stack Exchange site.
zh_Hans: 在Stack Exchange站点上搜索问题的工具。
llm: A tool for searching questions on Stack Exchange site.
en_US: A tool for searching questions on a Stack Exchange site. Specify the search query, sorting order, tags to include or exclude, whether to search only for questions with accepted answers, the Stack Exchange site, and number of results per page.
zh_Hans: 在Stack Exchange站点上搜索问题的工具。指定搜索查询、排序顺序、要包含或排除的标签、是否仅搜索有已接受答案的问题、Stack Exchange站点以及每页结果数。
llm: A tool for searching questions on a Stack Exchange site based on the provided parameters.
parameters:
- name: intitle
type: string
@@ -19,7 +19,7 @@ parameters:
human_description:
en_US: The search query to use for finding questions.
zh_Hans: 用于查找问题的搜索查询。
llm_description: The search query.
llm_description: The search query to use.
form: llm
- name: sort
type: string
@@ -30,10 +30,10 @@ parameters:
human_description:
en_US: The sort order for the search results - relevance, activity, votes, or creation date.
zh_Hans: 搜索结果的排序顺序 - 相关性、活动、投票或创建日期。
llm_description: The sort order - 'relevance', 'activity', 'votes', or 'creation'.
llm_description: The sort order - relevance, activity, votes, or creation.
form: llm
- name: order
type: select
type: string
required: true
label:
en_US: Sort direction
@@ -41,17 +41,8 @@ parameters:
human_description:
en_US: The direction to sort - ascending or descending.
zh_Hans: 排序方向 - 升序或降序。
form: form
options:
- value: asc
label:
en_US: Ascending
zh_Hans: 升序
- value: desc
label:
en_US: Descending
zh_Hans: 降序
default: desc
llm_description: asc for ascending, desc for descending.
form: llm
- name: site
type: string
required: true
@@ -61,8 +52,108 @@ parameters:
human_description:
en_US: The Stack Exchange site to search, e.g. stackoverflow, unix, etc.
zh_Hans: 要搜索的Stack Exchange站点,例如stackoverflow、unix等。
llm_description: Stack Exchange site identifier - 'stackoverflow', 'serverfault', 'superuser', 'askubuntu', 'unix', 'cs', 'softwareengineering', 'codegolf', 'codereview', 'cstheory', 'security', 'cryptography', 'reverseengineering', 'datascience', 'devops', 'ux', 'dba', 'gis', 'webmasters', 'arduino', 'raspberrypi', 'networkengineering', 'iot', 'tor', 'sqa', 'mathoverflow', 'math', 'mathematica', 'dsp', 'gamedev', 'robotics', 'genai', 'computergraphics'.
form: llm
llm_description: The Stack Exchange site identifier.
options:
- value: stackoverflow
label:
en_US: stackoverflow
- value: serverfault
label:
en_US: serverfault
- value: superuser
label:
en_US: superuser
- value: askubuntu
label:
en_US: askubuntu
- value: unix
label:
en_US: unix
- value: cs
label:
en_US: cs
- value: softwareengineering
label:
en_US: softwareengineering
- value: codegolf
label:
en_US: codegolf
- value: codereview
label:
en_US: codereview
- value: cstheory
label:
en_US: cstheory
- value: security
label:
en_US: security
- value: cryptography
label:
en_US: cryptography
- value: reverseengineering
label:
en_US: reverseengineering
- value: datascience
label:
en_US: datascience
- value: devops
label:
en_US: devops
- value: ux
label:
en_US: ux
- value: dba
label:
en_US: dba
- value: gis
label:
en_US: gis
- value: webmasters
label:
en_US: webmasters
- value: arduino
label:
en_US: arduino
- value: raspberrypi
label:
en_US: raspberrypi
- value: networkengineering
label:
en_US: networkengineering
- value: iot
label:
en_US: iot
- value: tor
label:
en_US: tor
- value: sqa
label:
en_US: sqa
- value: mathoverflow
label:
en_US: mathoverflow
- value: math
label:
en_US: math
- value: mathematica
label:
en_US: mathematica
- value: dsp
label:
en_US: dsp
- value: gamedev
label:
en_US: gamedev
- value: robotics
label:
en_US: robotics
- value: genai
label:
en_US: genai
- value: computergraphics
label:
en_US: computergraphics
form: form
- name: tagged
type: string
required: false
@@ -94,17 +185,8 @@ parameters:
human_description:
en_US: Whether to limit to only questions that have an accepted answer.
zh_Hans: 是否限制为只有已接受答案的问题。
form: form
options:
- value: true
label:
en_US: Yes
zh_Hans:
- value: false
label:
en_US: No
zh_Hans:
default: true
llm_description: true to limit to only questions with accepted answers, false otherwise.
form: llm
- name: pagesize
type: number
required: true
@@ -115,7 +197,4 @@ parameters:
en_US: The number of results to return per page.
zh_Hans: 每页返回的结果数。
llm_description: The number of results per page.
form: form
min: 1
max: 50
default: 10
form: llm
@@ -1,81 +1,11 @@
from typing import Any, Optional, Union
from typing import Any, Union
from pydantic import BaseModel, validator
from langchain.utilities import TwilioAPIWrapper
from core.tools.entities.tool_entities import ToolInvokeMessage
from core.tools.tool.builtin_tool import BuiltinTool
class TwilioAPIWrapper(BaseModel):
"""Messaging Client using Twilio.
To use, you should have the ``twilio`` python package installed,
and the environment variables ``TWILIO_ACCOUNT_SID``, ``TWILIO_AUTH_TOKEN``, and
``TWILIO_FROM_NUMBER``, or pass `account_sid`, `auth_token`, and `from_number` as
named parameters to the constructor.
Example:
.. code-block:: python
from langchain.utilities.twilio import TwilioAPIWrapper
twilio = TwilioAPIWrapper(
account_sid="ACxxx",
auth_token="xxx",
from_number="+10123456789"
)
twilio.run('test', '+12484345508')
"""
client: Any #: :meta private:
account_sid: Optional[str] = None
"""Twilio account string identifier."""
auth_token: Optional[str] = None
"""Twilio auth token."""
from_number: Optional[str] = None
"""A Twilio phone number in [E.164](https://www.twilio.com/docs/glossary/what-e164)
format, an
[alphanumeric sender ID](https://www.twilio.com/docs/sms/send-messages#use-an-alphanumeric-sender-id),
or a [Channel Endpoint address](https://www.twilio.com/docs/sms/channels#channel-addresses)
that is enabled for the type of message you want to send. Phone numbers or
[short codes](https://www.twilio.com/docs/sms/api/short-code) purchased from
Twilio also work here. You cannot, for example, spoof messages from a private
cell phone number. If you are using `messaging_service_sid`, this parameter
must be empty.
""" # noqa: E501
@validator("client", pre=True, always=True)
def set_validator(cls, values: dict) -> dict:
"""Validate that api key and python package exists in environment."""
try:
from twilio.rest import Client
except ImportError:
raise ImportError(
"Could not import twilio python package. "
"Please install it with `pip install twilio`."
)
account_sid = values.get("account_sid")
auth_token = values.get("auth_token")
values["from_number"] = values.get("from_number")
values["client"] = Client(account_sid, auth_token)
return values
def run(self, body: str, to: str) -> str:
"""Run body through Twilio and respond with message sid.
Args:
body: The text of the message you want to send. Can be up to 1,600
characters in length.
to: The destination phone number in
[E.164](https://www.twilio.com/docs/glossary/what-e164) format for
SMS/MMS or
[Channel user address](https://www.twilio.com/docs/sms/channels#channel-addresses)
for other 3rd-party channels.
""" # noqa: E501
message = self.client.messages.create(to, from_=self.from_number, body=body)
return message.sid
class SendMessageTool(BuiltinTool):
"""
A tool for sending messages using Twilio API.
@@ -1,79 +1,16 @@
from typing import Any, Optional, Union
from typing import Any, Union
import wikipedia
from langchain import WikipediaAPIWrapper
from langchain.tools import WikipediaQueryRun
from pydantic import BaseModel, Field
from core.tools.entities.tool_entities import ToolInvokeMessage
from core.tools.tool.builtin_tool import BuiltinTool
WIKIPEDIA_MAX_QUERY_LENGTH = 300
class WikipediaAPIWrapper:
"""Wrapper around WikipediaAPI.
class WikipediaInput(BaseModel):
query: str = Field(..., description="search query.")
To use, you should have the ``wikipedia`` python package installed.
This wrapper will use the Wikipedia API to conduct searches and
fetch page summaries. By default, it will return the page summaries
of the top-k results.
It limits the Document content by doc_content_chars_max.
"""
top_k_results: int = 3
lang: str = "en"
load_all_available_meta: bool = False
doc_content_chars_max: int = 4000
def __init__(self, doc_content_chars_max: int = 4000):
self.doc_content_chars_max = doc_content_chars_max
def run(self, query: str) -> str:
wikipedia.set_lang(self.lang)
wiki_client = wikipedia
"""Run Wikipedia search and get page summaries."""
page_titles = wiki_client.search(query[:WIKIPEDIA_MAX_QUERY_LENGTH])
summaries = []
for page_title in page_titles[: self.top_k_results]:
if wiki_page := self._fetch_page(page_title):
if summary := self._formatted_page_summary(page_title, wiki_page):
summaries.append(summary)
if not summaries:
return "No good Wikipedia Search Result was found"
return "\n\n".join(summaries)[: self.doc_content_chars_max]
@staticmethod
def _formatted_page_summary(page_title: str, wiki_page: Any) -> Optional[str]:
return f"Page: {page_title}\nSummary: {wiki_page.summary}"
def _fetch_page(self, page: str) -> Optional[str]:
try:
return wikipedia.page(title=page, auto_suggest=False)
except (
wikipedia.exceptions.PageError,
wikipedia.exceptions.DisambiguationError,
):
return None
class WikipediaQueryRun:
"""Tool that searches the Wikipedia API."""
name = "Wikipedia"
description = (
"A wrapper around Wikipedia. "
"Useful for when you need to answer general questions about "
"people, places, companies, facts, historical events, or other subjects. "
"Input should be a search query."
)
api_wrapper: WikipediaAPIWrapper
def __init__(self, api_wrapper: WikipediaAPIWrapper):
self.api_wrapper = api_wrapper
def _run(
self,
query: str,
) -> str:
"""Use the Wikipedia tool."""
return self.api_wrapper.run(query)
class WikiPediaSearchTool(BuiltinTool):
def _invoke(self,
user_id: str,
@@ -87,10 +24,14 @@ class WikiPediaSearchTool(BuiltinTool):
return self.create_text_message('Please input query')
tool = WikipediaQueryRun(
name="wikipedia",
api_wrapper=WikipediaAPIWrapper(doc_content_chars_max=4000),
args_schema=WikipediaInput
)
result = tool._run(query)
result = tool.run(tool_input={
'query': query
})
return self.create_text_message(self.summary(user_id=user_id,content=result))
+1 -8
View File
@@ -2,7 +2,7 @@ from abc import ABC, abstractmethod
from enum import Enum
from typing import Any, Optional, Union
from pydantic import BaseModel, validator
from pydantic import BaseModel
from core.tools.entities.tool_entities import (
ToolDescription,
@@ -23,13 +23,6 @@ class Tool(BaseModel, ABC):
description: ToolDescription = None
is_team_authorization: bool = False
@validator('parameters', pre=True, always=True)
def set_parameters(cls, v, values):
if not v:
return []
return v
class Runtime(BaseModel):
"""
Meta data of a tool call processing
@@ -234,9 +234,6 @@ class CodeNode(BaseNode):
parameters_validated = {}
for output_name, output_config in output_schema.items():
dot = '.' if prefix else ''
if output_name not in result:
raise ValueError(f'Output {prefix}{dot}{output_name} is missing.')
if output_config.type == 'object':
# check if output is object
if not isinstance(result.get(output_name), dict):
@@ -242,10 +242,7 @@ class KnowledgeRetrievalNode(BaseNode):
# get top k
top_k = retrieval_model_config['top_k']
# get retrieval method
if dataset.indexing_technique == "economy":
retrival_method = 'keyword_search'
else:
retrival_method = retrieval_model_config['search_method']
retrival_method = retrieval_model_config['search_method']
# get reranking model
reranking_model=retrieval_model_config['reranking_model'] \
if retrieval_model_config['reranking_enable'] else None
@@ -1,5 +1,4 @@
import json
import logging
from typing import Optional, Union, cast
from core.app.entities.app_invoke_entities import ModelConfigWithCredentialsEntity
@@ -13,7 +12,7 @@ from core.prompt.entities.advanced_prompt_entities import ChatModelMessage, Comp
from core.prompt.simple_prompt_transform import ModelMode
from core.prompt.utils.prompt_message_util import PromptMessageUtil
from core.workflow.entities.base_node_data_entities import BaseNodeData
from core.workflow.entities.node_entities import NodeRunMetadataKey, NodeRunResult, NodeType
from core.workflow.entities.node_entities import NodeRunResult, NodeType
from core.workflow.entities.variable_pool import VariablePool
from core.workflow.nodes.llm.llm_node import LLMNode
from core.workflow.nodes.question_classifier.entities import QuestionClassifierNodeData
@@ -62,15 +61,9 @@ class QuestionClassifierNode(LLMNode):
prompt_messages=prompt_messages,
stop=stop
)
categories = [_class.name for _class in node_data.classes]
try:
result_text_json = json.loads(result_text.strip('```JSON\n'))
categories_result = result_text_json.get('categories', [])
if categories_result:
categories = categories_result
except Exception:
logging.error(f"Failed to parse result text: {result_text}")
try:
categories = result_text_json.get('categories', [])
process_data = {
'model_mode': model_config.mode,
'prompts': PromptMessageUtil.prompt_messages_to_prompt_for_saving(
@@ -91,24 +84,14 @@ class QuestionClassifierNode(LLMNode):
inputs=variables,
process_data=process_data,
outputs=outputs,
edge_source_handle=classes_map.get(categories[0], None),
metadata={
NodeRunMetadataKey.TOTAL_TOKENS: usage.total_tokens,
NodeRunMetadataKey.TOTAL_PRICE: usage.total_price,
NodeRunMetadataKey.CURRENCY: usage.currency
}
edge_source_handle=classes_map.get(categories[0], None)
)
except ValueError as e:
return NodeRunResult(
status=WorkflowNodeExecutionStatus.FAILED,
inputs=variables,
error=str(e),
metadata={
NodeRunMetadataKey.TOTAL_TOKENS: usage.total_tokens,
NodeRunMetadataKey.TOTAL_PRICE: usage.total_price,
NodeRunMetadataKey.CURRENCY: usage.currency
}
error=str(e)
)
@classmethod
@@ -14,26 +14,18 @@ class VariableAssignerNode(BaseNode):
def _run(self, variable_pool: VariablePool) -> NodeRunResult:
node_data: VariableAssignerNodeData = cast(self._node_data_cls, self.node_data)
# Get variables
outputs = {}
inputs = {}
for variable in node_data.variables:
value = variable_pool.get_variable_value(variable)
if value is not None:
outputs = {
"output": value
}
inputs = {
'.'.join(variable[1:]): value
}
break
return NodeRunResult(
status=WorkflowNodeExecutionStatus.SUCCEEDED,
outputs=outputs,
inputs=inputs
)
@classmethod
+4 -36
View File
@@ -1,10 +1,9 @@
import logging
import time
from typing import Optional, cast
from typing import Optional
from core.app.app_config.entities import FileExtraConfig
from core.app.apps.base_app_queue_manager import GenerateTaskStoppedException
from core.file.file_obj import FileTransferMethod, FileType, FileVar
from core.file.file_obj import FileVar
from core.workflow.callbacks.base_workflow_callback import BaseWorkflowCallback
from core.workflow.entities.node_entities import NodeRunMetadataKey, NodeRunResult, NodeType
from core.workflow.entities.variable_pool import VariablePool, VariableValue
@@ -17,7 +16,6 @@ from core.workflow.nodes.end.end_node import EndNode
from core.workflow.nodes.http_request.http_request_node import HttpRequestNode
from core.workflow.nodes.if_else.if_else_node import IfElseNode
from core.workflow.nodes.knowledge_retrieval.knowledge_retrieval_node import KnowledgeRetrievalNode
from core.workflow.nodes.llm.entities import LLMNodeData
from core.workflow.nodes.llm.llm_node import LLMNode
from core.workflow.nodes.question_classifier.question_classifier_node import QuestionClassifierNode
from core.workflow.nodes.start.start_node import StartNode
@@ -221,8 +219,7 @@ class WorkflowEngineManager:
raise ValueError('node id not found in workflow graph')
# Get node class
node_type = NodeType.value_of(node_config.get('data', {}).get('type'))
node_cls = node_classes.get(node_type)
node_cls = node_classes.get(NodeType.value_of(node_config.get('data', {}).get('type')))
# init workflow run state
node_instance = node_cls(
@@ -255,40 +252,11 @@ class WorkflowEngineManager:
variable_node_id = variable_selector[0]
variable_key_list = variable_selector[1:]
# get value
value = user_inputs.get(variable_key)
# temp fix for image type
if node_type == NodeType.LLM:
new_value = []
if isinstance(value, list):
node_data = node_instance.node_data
node_data = cast(LLMNodeData, node_data)
detail = node_data.vision.configs.detail if node_data.vision.configs else None
for item in value:
if isinstance(item, dict) and 'type' in item and item['type'] == 'image':
transfer_method = FileTransferMethod.value_of(item.get('transfer_method'))
file = FileVar(
tenant_id=workflow.tenant_id,
type=FileType.IMAGE,
transfer_method=transfer_method,
url=item.get('url') if transfer_method == FileTransferMethod.REMOTE_URL else None,
related_id=item.get(
'upload_file_id') if transfer_method == FileTransferMethod.LOCAL_FILE else None,
extra_config=FileExtraConfig(image_config={'detail': detail} if detail else None),
)
new_value.append(file)
if new_value:
value = new_value
# append variable and value to variable pool
variable_pool.append_variable(
node_id=variable_node_id,
variable_key_list=variable_key_list,
value=value
value=user_inputs.get(variable_key)
)
# run node
node_run_result = node_instance.run(
-1
View File
@@ -28,7 +28,6 @@ def init_app(app: Flask) -> Celery:
celery_app.conf.update(
result_backend=app.config["CELERY_RESULT_BACKEND"],
broker_connection_retry_on_startup=True,
)
if app.config["BROKER_USE_SSL"]:
-1
View File
@@ -72,7 +72,6 @@ message_detail_fields = {
'created_at': TimestampField,
'agent_thoughts': fields.List(fields.Nested(agent_thought_fields)),
'message_files': fields.List(fields.Nested(message_file_fields), attribute='files'),
'metadata': fields.Raw(attribute='message_metadata_dict'),
'status': fields.String,
'error': fields.String,
}
+1 -5
View File
@@ -751,10 +751,6 @@ class Message(db.Model):
def in_debug_mode(self):
return self.override_model_configs is not None
@property
def message_metadata_dict(self) -> dict:
return json.loads(self.message_metadata) if self.message_metadata else {}
@property
def agent_thoughts(self):
return db.session.query(MessageAgentThought).filter(MessageAgentThought.message_id == self.id) \
@@ -815,7 +811,7 @@ class Message(db.Model):
@property
def workflow_run(self):
if self.workflow_run_id:
from .workflow import WorkflowRun
from api.models.workflow import WorkflowRun
return db.session.query(WorkflowRun).filter(WorkflowRun.id == self.workflow_run_id).first()
return None
+1 -5
View File
@@ -120,7 +120,7 @@ class Workflow(db.Model):
@property
def updated_by_account(self):
return Account.query.get(self.updated_by) if self.updated_by else None
return Account.query.get(self.updated_by)
@property
def graph_dict(self):
@@ -299,10 +299,6 @@ class WorkflowRun(db.Model):
Message.workflow_run_id == self.id
).first()
@property
def workflow(self):
return db.session.query(Workflow).filter(Workflow.id == self.workflow_id).first()
class WorkflowNodeExecutionTriggeredFrom(Enum):
"""
+1 -2
View File
@@ -18,7 +18,6 @@ pycryptodome==3.19.1
python-dotenv==1.0.0
pytest~=7.3.1
pytest-mock~=3.11.1
pytest-benchmark~=4.0.0
Authlib==1.2.0
boto3==1.28.17
tenacity==8.2.2
@@ -37,7 +36,7 @@ python-docx~=1.1.0
pypdfium2==4.16.0
resend~=0.7.0
pyjwt~=2.8.0
anthropic~=0.23.1
anthropic~=0.20.0
newspaper3k==0.2.8
google-api-python-client==2.90.0
wikipedia==1.4.0
+14 -8
View File
@@ -221,18 +221,24 @@ class AppService:
"name": app.name,
"mode": app.mode,
"icon": app.icon,
"icon_background": app.icon_background,
"description": app.description
"icon_background": app.icon_background
}
}
if app_mode in [AppMode.ADVANCED_CHAT, AppMode.WORKFLOW]:
workflow_service = WorkflowService()
workflow = workflow_service.get_draft_workflow(app)
export_data['workflow'] = {
"graph": workflow.graph_dict,
"features": workflow.features_dict
}
if app.workflow_id:
workflow = app.workflow
export_data['workflow'] = {
"graph": workflow.graph_dict,
"features": workflow.features_dict
}
else:
workflow_service = WorkflowService()
workflow = workflow_service.get_draft_workflow(app)
export_data['workflow'] = {
"graph": workflow.graph_dict,
"features": workflow.features_dict
}
else:
app_model_config = app.app_model_config
+5 -7
View File
@@ -1,8 +1,5 @@
from typing import Optional, Union
from sqlalchemy import or_
from core.app.entities.app_invoke_entities import InvokeFrom
from core.llm_generator.llm_generator import LLMGenerator
from extensions.ext_database import db
from libs.infinite_scroll_pagination import InfiniteScrollPagination
@@ -16,9 +13,8 @@ class ConversationService:
@classmethod
def pagination_by_last_id(cls, app_model: App, user: Optional[Union[Account, EndUser]],
last_id: Optional[str], limit: int,
invoke_from: InvokeFrom,
include_ids: Optional[list] = None,
exclude_ids: Optional[list] = None) -> InfiniteScrollPagination:
include_ids: Optional[list] = None, exclude_ids: Optional[list] = None,
exclude_debug_conversation: bool = False) -> InfiniteScrollPagination:
if not user:
return InfiniteScrollPagination(data=[], limit=limit, has_more=False)
@@ -28,7 +24,6 @@ class ConversationService:
Conversation.from_source == ('api' if isinstance(user, EndUser) else 'console'),
Conversation.from_end_user_id == (user.id if isinstance(user, EndUser) else None),
Conversation.from_account_id == (user.id if isinstance(user, Account) else None),
or_(Conversation.invoke_from.is_(None), Conversation.invoke_from == invoke_from.value)
)
if include_ids is not None:
@@ -37,6 +32,9 @@ class ConversationService:
if exclude_ids is not None:
base_query = base_query.filter(~Conversation.id.in_(exclude_ids))
if exclude_debug_conversation:
base_query = base_query.filter(Conversation.override_model_configs == None)
if last_id:
last_conversation = base_query.filter(
Conversation.id == last_id,
+3 -4
View File
@@ -1,6 +1,5 @@
from typing import Optional, Union
from core.app.entities.app_invoke_entities import InvokeFrom
from extensions.ext_database import db
from libs.infinite_scroll_pagination import InfiniteScrollPagination
from models.account import Account
@@ -12,8 +11,8 @@ from services.conversation_service import ConversationService
class WebConversationService:
@classmethod
def pagination_by_last_id(cls, app_model: App, user: Optional[Union[Account, EndUser]],
last_id: Optional[str], limit: int, invoke_from: InvokeFrom,
pinned: Optional[bool] = None) -> InfiniteScrollPagination:
last_id: Optional[str], limit: int, pinned: Optional[bool] = None,
exclude_debug_conversation: bool = False) -> InfiniteScrollPagination:
include_ids = None
exclude_ids = None
if pinned is not None:
@@ -33,9 +32,9 @@ class WebConversationService:
user=user,
last_id=last_id,
limit=limit,
invoke_from=invoke_from,
include_ids=include_ids,
exclude_ids=exclude_ids,
exclude_debug_conversation=exclude_debug_conversation
)
@classmethod
@@ -6,10 +6,6 @@ from core.workflow.nodes.code.code_node import CodeNode
from models.workflow import WorkflowNodeExecutionStatus
from tests.integration_tests.workflow.nodes.__mock.code_executor import setup_code_executor_mock
from os import getenv
CODE_MAX_STRING_LENGTH = int(getenv('CODE_MAX_STRING_LENGTH', '10000'))
@pytest.mark.parametrize('setup_code_executor_mock', [['none']], indirect=True)
def test_execute_code(setup_code_executor_mock):
code = '''
@@ -231,7 +227,7 @@ def test_execute_code_output_validator_depth():
# construct result
result = {
"number_validator": 1,
"string_validator": (CODE_MAX_STRING_LENGTH + 1) * "1",
"string_validator": "1" * 6000,
"number_array_validator": [1, 2, 3, 3.333],
"string_array_validator": ["1", "2", "3"],
"object_validator": {
-24
View File
@@ -1,24 +0,0 @@
import pytest
from pydantic.error_wrappers import ValidationError
from core.rag.datasource.vdb.milvus.milvus_vector import MilvusConfig
def test_default_value():
valid_config = {
'host': 'localhost',
'port': 19530,
'user': 'root',
'password': 'Milvus'
}
for key in valid_config:
config = valid_config.copy()
del config[key]
with pytest.raises(ValidationError) as e:
MilvusConfig(**config)
assert e.value.errors()[1]['msg'] == f'config MILVUS_{key.upper()} is required'
config = MilvusConfig(**valid_config)
assert config.secure is False
assert config.database == 'default'
+2 -2
View File
@@ -50,7 +50,7 @@ services:
AUTHORIZATION_ADMINLIST_USERS: 'hello@dify.ai'
ports:
- "8080:8080"
# The DifySandbox
sandbox:
image: langgenius/dify-sandbox:latest
@@ -75,6 +75,6 @@ services:
# volumes:
# - ./volumes/qdrant:/qdrant/storage
# environment:
# QDRANT_API_KEY: 'difyai123456'
# QDRANT__API_KEY: 'difyai123456'
# ports:
# - "6333:6333"
+6 -4
View File
@@ -2,7 +2,7 @@ version: '3'
services:
# API service
api:
image: langgenius/dify-api:0.6.1
image: langgenius/dify-api:0.6.0-preview-workflow.2
restart: always
environment:
# Startup mode, 'api' starts the API server.
@@ -150,7 +150,7 @@ services:
# worker service
# The Celery worker for processing the queue.
worker:
image: langgenius/dify-api:0.6.1
image: langgenius/dify-api:0.6.0-preview-workflow.2
restart: always
environment:
# Startup mode, 'worker' starts the Celery worker for processing the queue.
@@ -232,7 +232,7 @@ services:
# Frontend web application.
web:
image: langgenius/dify-web:0.6.1
image: langgenius/dify-web:0.6.0-preview-workflow.2
restart: always
environment:
EDITION: SELF_HOSTED
@@ -323,6 +323,8 @@ services:
API_KEY: dify-sandbox
GIN_MODE: release
WORKER_TIMEOUT: 15
ports:
- "8194:8194"
# Qdrant vector store.
# uncomment to use qdrant as vector store.
@@ -334,7 +336,7 @@ services:
# volumes:
# - ./volumes/qdrant:/qdrant/storage
# environment:
# QDRANT_API_KEY: 'difyai123456'
# QDRANT__API_KEY: 'difyai123456'
# # uncomment to expose qdrant port to host
# # ports:
# # - "6333:6333"
Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

@@ -1,6 +1,5 @@
'use client'
import type { FC } from 'react'
import { useUnmount } from 'ahooks'
import React, { useCallback, useEffect, useState } from 'react'
import { usePathname, useRouter } from 'next/navigation'
import cn from 'classnames'
@@ -81,9 +80,8 @@ const AppDetailLayout: FC<IAppDetailLayoutProps> = (props) => {
const localeMode = localStorage.getItem('app-detail-collapse-or-expand') || 'expand'
const mode = isMobile ? 'collapse' : 'expand'
setAppSiderbarExpand(isMobile ? mode : localeMode)
// TODO: consider screen size and mode
// if ((appDetail.mode === 'advanced-chat' || appDetail.mode === 'workflow') && (pathname).endsWith('workflow'))
// setAppSiderbarExpand('collapse')
if ((appDetail.mode === 'advanced-chat' || appDetail.mode === 'workflow') && (pathname).endsWith('workflow'))
setAppSiderbarExpand('collapse')
}
}, [appDetail, isMobile])
@@ -104,10 +102,6 @@ const AppDetailLayout: FC<IAppDetailLayoutProps> = (props) => {
})
}, [appId, isCurrentWorkspaceManager])
useUnmount(() => {
setAppDetail()
})
if (!appDetail) {
return (
<div className='flex h-full items-center justify-center bg-white'>
@@ -28,6 +28,7 @@ import type { RelatedApp, RelatedAppResponse } from '@/models/datasets'
import { getLocaleOnClient } from '@/i18n'
import AppSideBar from '@/app/components/app-sidebar'
import Divider from '@/app/components/base/divider'
import Indicator from '@/app/components/header/indicator'
import AppIcon from '@/app/components/base/app-icon'
import Loading from '@/app/components/base/loading'
import FloatPopoverContainer from '@/app/components/base/float-popover-container'
@@ -35,9 +36,6 @@ import DatasetDetailContext from '@/context/dataset-detail'
import { DataSourceType } from '@/models/datasets'
import useBreakpoints, { MediaType } from '@/hooks/use-breakpoints'
import { LanguagesSupported } from '@/i18n/language'
import { useStore } from '@/app/components/app/store'
import { AiText, ChatBot, CuteRobote } from '@/app/components/base/icons/src/vender/solid/communication'
import { Route } from '@/app/components/base/icons/src/vender/solid/mapsAndTravel'
export type IAppDetailLayoutProps = {
children: React.ReactNode
@@ -53,31 +51,18 @@ type ILikedItemProps = {
const LikedItem = ({
type = 'app',
appStatus = true,
detail,
isMobile,
}: ILikedItemProps) => {
return (
<Link className={classNames(s.itemWrapper, 'px-2', isMobile && 'justify-center')} href={`/app/${detail?.id}/overview`}>
<Link className={classNames(s.itemWrapper, 'px-0', isMobile && 'justify-center')} href={`/app/${detail?.id}/overview`}>
<div className={classNames(s.iconWrapper, 'mr-0')}>
<AppIcon size='tiny' icon={detail?.icon} background={detail?.icon_background} />
{type === 'app' && (
<span className='absolute bottom-[-2px] right-[-2px] w-3.5 h-3.5 p-0.5 bg-white rounded border-[0.5px] border-[rgba(0,0,0,0.02)] shadow-sm'>
{detail.mode === 'advanced-chat' && (
<ChatBot className='w-2.5 h-2.5 text-[#1570EF]' />
)}
{detail.mode === 'agent-chat' && (
<CuteRobote className='w-2.5 h-2.5 text-indigo-600' />
)}
{detail.mode === 'chat' && (
<ChatBot className='w-2.5 h-2.5 text-[#1570EF]' />
)}
{detail.mode === 'completion' && (
<AiText className='w-2.5 h-2.5 text-[#0E9384]' />
)}
{detail.mode === 'workflow' && (
<Route className='w-2.5 h-2.5 text-[#f79009]' />
)}
</span>
<div className={s.statusPoint}>
<Indicator color={appStatus ? 'green' : 'gray'} />
</div>
)}
</div>
{!isMobile && <div className={classNames(s.appInfo, 'ml-2')}>{detail?.name || '--'}</div>}
@@ -131,7 +116,7 @@ const ExtraInfo = ({ isMobile, relatedApps }: IExtraInfoProps) => {
<Divider className='mt-5' />
{(relatedApps?.data && relatedApps?.data?.length > 0) && (
<>
{!isMobile && <div className='w-full px-2 pb-1 pt-4 uppercase text-xs text-gray-500 font-medium'>{relatedApps?.total || '--'} {t('common.datasetMenus.relatedApp')}</div>}
{!isMobile && <div className={s.subTitle}>{relatedApps?.total || '--'} {t('common.datasetMenus.relatedApp')}</div>}
{isMobile && <div className={classNames(s.subTitle, 'flex items-center justify-center !px-0 gap-1')}>
{relatedApps?.total || '--'}
<PaperClipIcon className='h-4 w-4 text-gray-700' />
@@ -213,14 +198,6 @@ const DatasetDetailLayout: FC<IAppDetailLayoutProps> = (props) => {
document.title = `${datasetRes.name || 'Dataset'} - Dify`
}, [datasetRes])
const { setAppSiderbarExpand } = useStore()
useEffect(() => {
const localeMode = localStorage.getItem('app-detail-collapse-or-expand') || 'expand'
const mode = isMobile ? 'collapse' : 'expand'
setAppSiderbarExpand(isMobile ? mode : localeMode)
}, [isMobile, setAppSiderbarExpand])
if (!datasetRes && !error)
return <Loading />
@@ -5,7 +5,7 @@
@apply truncate text-gray-700 text-sm font-normal;
}
.iconWrapper {
@apply relative w-6 h-6 rounded-lg;
@apply relative w-6 h-6 bg-[#D5F5F6] rounded-md;
}
.statusPoint {
@apply flex justify-center items-center absolute -right-0.5 -bottom-0.5 w-2.5 h-2.5 bg-white rounded;
+3 -42
View File
@@ -22,8 +22,6 @@ import { copyApp, deleteApp, exportAppConfig, updateAppInfo } from '@/service/ap
import DuplicateAppModal from '@/app/components/app/duplicate-modal'
import type { DuplicateAppModalProps } from '@/app/components/app/duplicate-modal'
import CreateAppModal from '@/app/components/explore/create-app-modal'
import { AiText, ChatBot, CuteRobote } from '@/app/components/base/icons/src/vender/solid/communication'
import { Route } from '@/app/components/base/icons/src/vender/solid/mapsAndTravel'
import type { CreateAppModalProps } from '@/app/components/explore/create-app-modal'
import { NEED_REFRESH_APP_LIST_KEY } from '@/config'
import { getRedirection } from '@/utils/app-redirection'
@@ -158,28 +156,8 @@ const AppInfo = ({ expand }: IAppInfoProps) => {
className='block'
>
<div className={cn('flex cursor-pointer p-1 rounded-lg hover:bg-gray-100', open && 'bg-gray-100')}>
<div className='relative shrink-0 mr-2'>
<div className='shrink-0 mr-2'>
<AppIcon size={expand ? 'large' : 'small'} icon={appDetail.icon} background={appDetail.icon_background} />
<span className={cn(
'absolute bottom-[-3px] right-[-3px] w-4 h-4 p-0.5 bg-white rounded border-[0.5px] border-[rgba(0,0,0,0.02)] shadow-sm',
!expand && '!w-3.5 !h-3.5 !bottom-[-2px] !right-[-2px]',
)}>
{appDetail.mode === 'advanced-chat' && (
<ChatBot className={cn('w-3 h-3 text-[#1570EF]', !expand && '!w-2.5 !h-2.5')} />
)}
{appDetail.mode === 'agent-chat' && (
<CuteRobote className={cn('w-3 h-3 text-indigo-600', !expand && '!w-2.5 !h-2.5')} />
)}
{appDetail.mode === 'chat' && (
<ChatBot className={cn('w-3 h-3 text-[#1570EF]', !expand && '!w-2.5 !h-2.5')} />
)}
{appDetail.mode === 'completion' && (
<AiText className={cn('w-3 h-3 text-[#0E9384]', !expand && '!w-2.5 !h-2.5')} />
)}
{appDetail.mode === 'workflow' && (
<Route className={cn('w-3 h-3 text-[#f79009]', !expand && '!w-2.5 !h-2.5')} />
)}
</span>
</div>
{expand && (
<div className="grow w-0">
@@ -221,25 +199,8 @@ const AppInfo = ({ expand }: IAppInfoProps) => {
<div className='relative w-[320px] bg-white rounded-2xl shadow-xl'>
{/* header */}
<div className={cn('flex pl-4 pt-3 pr-3', !appDetail.description && 'pb-2')}>
<div className='relative shrink-0 mr-2'>
<div className='shrink-0 mr-2'>
<AppIcon size="large" icon={appDetail.icon} background={appDetail.icon_background} />
<span className='absolute bottom-[-3px] right-[-3px] w-4 h-4 p-0.5 bg-white rounded border-[0.5px] border-[rgba(0,0,0,0.02)] shadow-sm'>
{appDetail.mode === 'advanced-chat' && (
<ChatBot className='w-3 h-3 text-[#1570EF]' />
)}
{appDetail.mode === 'agent-chat' && (
<CuteRobote className='w-3 h-3 text-indigo-600' />
)}
{appDetail.mode === 'chat' && (
<ChatBot className='w-3 h-3 text-[#1570EF]' />
)}
{appDetail.mode === 'completion' && (
<AiText className='w-3 h-3 text-[#0E9384]' />
)}
{appDetail.mode === 'workflow' && (
<Route className='w-3 h-3 text-[#f79009]' />
)}
</span>
</div>
<div className='grow w-0'>
<div title={appDetail.name} className='flex justify-between items-center text-sm leading-5 font-medium text-gray-900 truncate'>{appDetail.name}</div>
@@ -333,7 +294,7 @@ const AppInfo = ({ expand }: IAppInfoProps) => {
)}/>
<div className='px-4 pb-2'>
<div className='flex items-center gap-1 text-gray-700 text-md leading-6 font-semibold'>
{showSwitchTip === 'chat' ? t('app.newApp.advanced') : t('app.types.workflow')}
{t('app.newApp.advanced')}
<span className='px-1 rounded-[5px] bg-white border border-black/8 text-gray-500 text-[10px] leading-[18px] font-medium'>BETA</span>
</div>
<div className='text-orange-500 text-xs leading-[18px] font-medium'>{t('app.newApp.advancedFor').toLocaleUpperCase()}</div>
+22 -68
View File
@@ -1,6 +1,6 @@
'use client'
import type { FC, ReactNode } from 'react'
import React, { useEffect, useMemo, useRef, useState } from 'react'
import React, { useState } from 'react'
import { useTranslation } from 'react-i18next'
import { UserCircleIcon } from '@heroicons/react/24/solid'
import cn from 'classnames'
@@ -84,7 +84,7 @@ const Answer: FC<IAnswerProps> = ({
}) => {
const { id, content, more, feedback, adminFeedback, annotation, agent_thoughts } = item
const isAgentMode = !!agent_thoughts && agent_thoughts.length > 0
const hasAnnotation = useMemo(() => !!annotation, [annotation])
const hasAnnotation = !!annotation?.id
// const [annotation, setAnnotation] = useState<Annotation | undefined | null>(initAnnotation)
// const [inputValue, setInputValue] = useState<string>(initAnnotation?.content ?? '')
const [localAdminFeedback, setLocalAdminFeedback] = useState<Feedbacktype | undefined | null>(adminFeedback)
@@ -136,6 +136,19 @@ const Answer: FC<IAnswerProps> = ({
)
}
const renderHasAnnotationBtn = () => {
return (
<div
className={cn(s.hasAnnotationBtn, 'relative box-border flex items-center justify-center h-7 w-7 p-0.5 rounded-lg bg-white cursor-pointer text-[#444CE7]')}
style={{ boxShadow: '0px 4px 6px -1px rgba(0, 0, 0, 0.1), 0px 2px 4px -2px rgba(0, 0, 0, 0.05)' }}
>
<div className='p-1 rounded-lg bg-[#EEF4FF] '>
<MessageFast className='w-4 h-4' />
</div>
</div>
)
}
/**
* Different scenarios have different operation items.
* @param isWebScene Whether it is web scene
@@ -220,50 +233,6 @@ const Answer: FC<IAnswerProps> = ({
</div>
)
const [containerWidth, setContainerWidth] = useState(0)
const [contentWidth, setContentWidth] = useState(0)
const containerRef = useRef<HTMLDivElement>(null)
const contentRef = useRef<HTMLDivElement>(null)
const getContainerWidth = () => {
if (containerRef.current)
setContainerWidth(containerRef.current?.clientWidth + 24)
}
const getContentWidth = () => {
if (contentRef.current)
setContentWidth(contentRef.current?.clientWidth)
}
useEffect(() => {
getContainerWidth()
}, [])
useEffect(() => {
if (!isResponding)
getContentWidth()
}, [isResponding])
const operationWidth = useMemo(() => {
let width = 0
if (!item.isOpeningStatement)
width += 28
if (!item.isOpeningStatement && isShowPromptLog)
width += 102 + 8
if (!item.isOpeningStatement && isShowTextToSpeech)
width += 33
if (!item.isOpeningStatement && supportAnnotation)
width += 96 + 8
if (!feedbackDisabled && !item.feedbackDisabled)
width += 60 + 8
if (!feedbackDisabled && localAdminFeedback?.rating && !item.isOpeningStatement)
width += 60 + 8
if (!feedbackDisabled && feedback?.rating && !item.isOpeningStatement)
width += 28 + 8
return width
}, [item.isOpeningStatement, item.feedbackDisabled, isShowPromptLog, isShowTextToSpeech, supportAnnotation, feedbackDisabled, localAdminFeedback?.rating, feedback?.rating])
const positionRight = useMemo(() => operationWidth < containerWidth - contentWidth - 4, [operationWidth, containerWidth, contentWidth])
return (
// data-id for debug the item message is right
<div key={id} data-id={id}>
@@ -279,9 +248,9 @@ const Answer: FC<IAnswerProps> = ({
</div>
)
}
<div ref={containerRef} className={cn(s.answerWrapWrap, 'chat-answer-container')}>
<div className={cn(s.answerWrapWrap, 'chat-answer-container')}>
<div className={cn(s.answerWrap, 'group')}>
<div ref={contentRef} className={`${s.answer} relative text-sm text-gray-900`}>
<div className={`${s.answer} relative text-sm text-gray-900`}>
<div className={'ml-2 py-3 px-4 bg-gray-100 rounded-tr-2xl rounded-b-2xl'}>
{(isResponding && (isAgentMode ? (!content && (agent_thoughts || []).filter(item => !!item.thought || !!item.tool).length === 0) : !content))
? (
@@ -318,7 +287,7 @@ const Answer: FC<IAnswerProps> = ({
</div>
{(hasAnnotation && !annotation?.logAnnotation) && (
<EditTitle className='mt-1' title={t('appAnnotation.editBy', {
author: annotation?.authorName,
author: annotation.authorName,
})} />
)}
{item.isOpeningStatement && item.suggestedQuestions && item.suggestedQuestions.filter(q => !!q && q.trim()).length > 0 && (
@@ -342,23 +311,7 @@ const Answer: FC<IAnswerProps> = ({
)
}
</div>
{hasAnnotation && (
<div
className={cn(s.hasAnnotationBtn, 'absolute -top-3.5 -right-3.5 box-border flex items-center justify-center h-7 w-7 p-0.5 rounded-lg bg-white cursor-pointer text-[#444CE7]')}
style={{ boxShadow: '0px 4px 6px -1px rgba(0, 0, 0, 0.1), 0px 2px 4px -2px rgba(0, 0, 0, 0.05)' }}
>
<div className='p-1 rounded-lg bg-[#EEF4FF] '>
<MessageFast className='w-4 h-4' />
</div>
</div>
)}
<div
className={cn(
'absolute -top-3.5 flex justify-end gap-1',
positionRight ? '!top-[9px]' : '-right-3.5',
)}
style={positionRight ? { left: contentWidth + 8 } : {}}
>
<div className='absolute top-[-14px] left-[-6px] flex flex-row justify-end gap-1'>
{!item.isOpeningStatement && (
<CopyBtn
value={content}
@@ -366,7 +319,7 @@ const Answer: FC<IAnswerProps> = ({
/>
)}
{((isShowPromptLog && !isResponding) || (!item.isOpeningStatement && isShowTextToSpeech)) && (
<div className='hidden group-hover:flex items-center w-max h-[28px] p-0.5 rounded-lg bg-white border-[0.5px] border-gray-100 shadow-md shrink-0'>
<div className='hidden group-hover:flex items-center w-max h-[28px] p-0.5 rounded-lg bg-white border-[0.5px] border-gray-100 shadow-md'>
{isShowPromptLog && !isResponding && (
<Log logItem={item} />
)}
@@ -386,7 +339,7 @@ const Answer: FC<IAnswerProps> = ({
appId={appId!}
messageId={id}
annotationId={annotation?.id || ''}
className={cn(s.annotationBtn, 'ml-1 shrink-0')}
className={cn(s.annotationBtn, 'ml-1')}
cached={hasAnnotation}
query={question}
answer={content}
@@ -409,6 +362,7 @@ const Answer: FC<IAnswerProps> = ({
createdAt={annotation?.created_at}
onRemove={() => { }}
/>
{hasAnnotation && renderHasAnnotationBtn()}
{!feedbackDisabled && !item.feedbackDisabled && renderItemOperation(displayScene !== 'console')}
{/* Admin feedback is displayed only in the background. */}
@@ -20,13 +20,11 @@ import ConfigContext from '@/context/debug-configuration'
import ConfigPrompt from '@/app/components/app/configuration/config-prompt'
import ConfigVar from '@/app/components/app/configuration/config-var'
import { type CitationConfig, type ModelConfig, type ModerationConfig, type MoreLikeThisConfig, type PromptVariable, type SpeechToTextConfig, type SuggestedQuestionsAfterAnswerConfig, type TextToSpeechConfig } from '@/models/debug'
import type { AppType } from '@/types/app'
import { ModelModeType } from '@/types/app'
import { AppType, ModelModeType } from '@/types/app'
import { useModalContext } from '@/context/modal-context'
import ConfigParamModal from '@/app/components/app/configuration/toolbox/annotation/config-param-modal'
import AnnotationFullModal from '@/app/components/billing/annotation-full/modal'
import { useDefaultModel } from '@/app/components/header/account-setting/model-provider-page/hooks'
import { ModelTypeEnum } from '@/app/components/header/account-setting/model-provider-page/declarations'
const Config: FC = () => {
const {
@@ -61,9 +59,9 @@ const Config: FC = () => {
moderationConfig,
setModerationConfig,
} = useContext(ConfigContext)
const isChatApp = ['advanced-chat', 'agent-chat', 'chat'].includes(mode)
const { data: speech2textDefaultModel } = useDefaultModel(ModelTypeEnum.speech2text)
const { data: text2speechDefaultModel } = useDefaultModel(ModelTypeEnum.tts)
const isChatApp = mode !== AppType.completion
const { data: speech2textDefaultModel } = useDefaultModel(4)
const { data: text2speechDefaultModel } = useDefaultModel(5)
const { setShowModerationSettingModal } = useModalContext()
const formattingChangedDispatcher = useFormattingChangedDispatcher()
@@ -20,7 +20,6 @@ import type { ModelConfig } from '@/app/components/workflow/types'
import ModelParameterModal from '@/app/components/header/account-setting/model-provider-page/model-parameter-modal'
import TooltipPlus from '@/app/components/base/tooltip-plus'
import { HelpCircle } from '@/app/components/base/icons/src/vender/line/general'
import { ModelTypeEnum } from '@/app/components/header/account-setting/model-provider-page/declarations'
type Props = {
datasetConfigs: DatasetConfigs
@@ -50,7 +49,7 @@ const ConfigContent: FC<Props> = ({
const {
modelList: rerankModelList,
defaultModel: rerankDefaultModel,
} = useModelListAndDefaultModelAndCurrentProviderAndModel(ModelTypeEnum.rerank)
} = useModelListAndDefaultModelAndCurrentProviderAndModel(3)
const rerankModel = (() => {
if (datasetConfigs.reranking_model) {
return {
@@ -159,7 +158,6 @@ const ConfigContent: FC<Props> = ({
</TooltipPlus>
</div>
<ModelParameterModal
isInWorkflow={isInWorkflow}
popupClassName='!w-[387px]'
portalToFollowElemContentClassName='!z-[1002]'
isAdvancedMode={true}
@@ -13,7 +13,6 @@ import { RETRIEVE_TYPE } from '@/types/app'
import Toast from '@/app/components/base/toast'
import { DATASET_DEFAULT } from '@/config'
import { useModelListAndDefaultModelAndCurrentProviderAndModel } from '@/app/components/header/account-setting/model-provider-page/hooks'
import { ModelTypeEnum } from '@/app/components/header/account-setting/model-provider-page/declarations'
const ParamsConfig: FC = () => {
const { t } = useTranslation()
@@ -27,7 +26,7 @@ const ParamsConfig: FC = () => {
const {
defaultModel: rerankDefaultModel,
currentModel: isRerankDefaultModelVaild,
} = useModelListAndDefaultModelAndCurrentProviderAndModel(ModelTypeEnum.rerank)
} = useModelListAndDefaultModelAndCurrentProviderAndModel(3)
const isValid = () => {
let errMsg = ''
@@ -22,7 +22,6 @@ import {
useModelList,
useModelListAndDefaultModelAndCurrentProviderAndModel,
} from '@/app/components/header/account-setting/model-provider-page/hooks'
import { ModelTypeEnum } from '@/app/components/header/account-setting/model-provider-page/declarations'
type SettingsModalProps = {
currentDataset: DataSet
@@ -43,12 +42,12 @@ const SettingsModal: FC<SettingsModalProps> = ({
onCancel,
onSave,
}) => {
const { data: embeddingsModelList } = useModelList(ModelTypeEnum.textEmbedding)
const { data: embeddingsModelList } = useModelList(2)
const {
modelList: rerankModelList,
defaultModel: rerankDefaultModel,
currentModel: isRerankDefaultModelVaild,
} = useModelListAndDefaultModelAndCurrentProviderAndModel(ModelTypeEnum.rerank)
} = useModelListAndDefaultModelAndCurrentProviderAndModel(3)
const { t } = useTranslation()
const { notify } = useToastContext()
const ref = useRef(null)
@@ -31,7 +31,7 @@ import { IS_CE_EDITION } from '@/config'
import type { Inputs } from '@/models/debug'
import { fetchFileUploadConfig } from '@/service/common'
import { useDefaultModel } from '@/app/components/header/account-setting/model-provider-page/hooks'
import { ModelFeatureEnum, ModelTypeEnum } from '@/app/components/header/account-setting/model-provider-page/declarations'
import { ModelFeatureEnum } from '@/app/components/header/account-setting/model-provider-page/declarations'
import type { ModelParameterModalProps } from '@/app/components/header/account-setting/model-provider-page/model-parameter-modal'
import { Plus } from '@/app/components/base/icons/src/vender/line/general'
import { useEventEmitterContextContext } from '@/context/event-emitter'
@@ -86,7 +86,7 @@ const Debug: FC<IDebug> = ({
setVisionConfig,
} = useContext(ConfigContext)
const { eventEmitter } = useEventEmitterContextContext()
const { data: text2speechDefaultModel } = useDefaultModel(ModelTypeEnum.textEmbedding)
const { data: text2speechDefaultModel } = useDefaultModel(5)
const { data: fileUploadConfigResponse } = useSWR({ url: '/files/upload' }, fetchFileUploadConfig)
useEffect(() => {
setAutoFreeze(false)
@@ -3,7 +3,7 @@ import { clone } from 'lodash-es'
import produce from 'immer'
import type { ChatPromptConfig, CompletionPromptConfig, ConversationHistoriesRole, PromptItem } from '@/models/debug'
import { PromptMode } from '@/models/debug'
import { ModelModeType } from '@/types/app'
import { AppType, ModelModeType } from '@/types/app'
import { DEFAULT_CHAT_PROMPT_CONFIG, DEFAULT_COMPLETION_PROMPT_CONFIG } from '@/config'
import { PRE_PROMPT_PLACEHOLDER_TEXT, checkHasContextBlock, checkHasHistoryBlock, checkHasQueryBlock } from '@/app/components/base/prompt-editor/constants'
import { fetchPromptTemplate } from '@/service/debug'
@@ -152,7 +152,7 @@ const useAdvancedPromptConfig = ({
else
draft.prompt.text = completionPromptConfig.prompt?.text.replace(PRE_PROMPT_PLACEHOLDER_TEXT, toReplacePrePrompt)
if (['advanced-chat', 'agent-chat', 'chat'].includes(appMode) && completionPromptConfig.conversation_histories_role.assistant_prefix && completionPromptConfig.conversation_histories_role.user_prefix)
if (appMode === AppType.chat && completionPromptConfig.conversation_histories_role.assistant_prefix && completionPromptConfig.conversation_histories_role.user_prefix)
draft.conversation_histories_role = completionPromptConfig.conversation_histories_role
})
setCompletionPromptConfig(newPromptConfig)
@@ -388,10 +388,7 @@ const Configuration: FC = () => {
const promptMode = modelConfig.prompt_type === PromptMode.advanced ? PromptMode.advanced : PromptMode.simple
doSetPromptMode(promptMode)
if (promptMode === PromptMode.advanced) {
if (modelConfig.chat_prompt_config && modelConfig.chat_prompt_config.prompt.length > 0)
setChatPromptConfig(modelConfig.chat_prompt_config)
else
setChatPromptConfig(clone(DEFAULT_CHAT_PROMPT_CONFIG) as any)
setChatPromptConfig(modelConfig.chat_prompt_config || clone(DEFAULT_CHAT_PROMPT_CONFIG) as any)
setCompletionPromptConfig(modelConfig.completion_prompt_config || clone(DEFAULT_COMPLETION_PROMPT_CONFIG) as any)
setCanReturnToSimpleMode(false)
}
@@ -11,7 +11,6 @@ import type { AnnotationReplyConfig } from '@/models/debug'
import { ANNOTATION_DEFAULT } from '@/config'
import ModelSelector from '@/app/components/header/account-setting/model-provider-page/model-selector'
import { useModelListAndDefaultModelAndCurrentProviderAndModel } from '@/app/components/header/account-setting/model-provider-page/hooks'
import { ModelTypeEnum } from '@/app/components/header/account-setting/model-provider-page/declarations'
type Props = {
appId: string
@@ -37,7 +36,7 @@ const ConfigParamModal: FC<Props> = ({
modelList: embeddingsModelList,
defaultModel: embeddingsDefaultModel,
currentModel: isEmbeddingsDefaultModelValid,
} = useModelListAndDefaultModelAndCurrentProviderAndModel(ModelTypeEnum.textEmbedding)
} = useModelListAndDefaultModelAndCurrentProviderAndModel(2)
const [annotationConfig, setAnnotationConfig] = useState(oldAnnotationConfig)
const [isLoading, setLoading] = useState(false)

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