Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
D
dify
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
ai-tech
dify
Commits
afb0ff37
Commit
afb0ff37
authored
Feb 25, 2024
by
takatost
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
add expert mode of chatapp convert command
parent
67b6f08d
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
114 additions
and
28 deletions
+114
-28
commands.py
api/commands.py
+71
-1
application_manager.py
api/core/application_manager.py
+24
-17
application_entities.py
api/core/entities/application_entities.py
+1
-1
workflow_converter.py
api/services/workflow/workflow_converter.py
+15
-8
workflow_service.py
api/services/workflow_service.py
+1
-1
test_workflow_converter.py
...s/unit_tests/services/workflow/test_workflow_converter.py
+2
-0
No files found.
api/commands.py
View file @
afb0ff37
import
base64
import
base64
import
json
import
json
import
logging
import
secrets
import
secrets
import
click
import
click
...
@@ -12,11 +13,12 @@ from extensions.ext_database import db
...
@@ -12,11 +13,12 @@ from extensions.ext_database import db
from
libs.helper
import
email
as
email_validate
from
libs.helper
import
email
as
email_validate
from
libs.password
import
hash_password
,
password_pattern
,
valid_password
from
libs.password
import
hash_password
,
password_pattern
,
valid_password
from
libs.rsa
import
generate_key_pair
from
libs.rsa
import
generate_key_pair
from
models.account
import
Tenant
from
models.account
import
Tenant
,
TenantAccountJoin
from
models.dataset
import
Dataset
,
DatasetCollectionBinding
,
DocumentSegment
from
models.dataset
import
Dataset
,
DatasetCollectionBinding
,
DocumentSegment
from
models.dataset
import
Document
as
DatasetDocument
from
models.dataset
import
Document
as
DatasetDocument
from
models.model
import
Account
,
App
,
AppMode
,
AppModelConfig
,
AppAnnotationSetting
,
Conversation
,
MessageAnnotation
from
models.model
import
Account
,
App
,
AppMode
,
AppModelConfig
,
AppAnnotationSetting
,
Conversation
,
MessageAnnotation
from
models.provider
import
Provider
,
ProviderModel
from
models.provider
import
Provider
,
ProviderModel
from
services.workflow.workflow_converter
import
WorkflowConverter
@
click
.
command
(
'reset-password'
,
help
=
'Reset the account password.'
)
@
click
.
command
(
'reset-password'
,
help
=
'Reset the account password.'
)
...
@@ -422,9 +424,77 @@ and am.agent_mode like '{"enabled": true%' ORDER BY a.created_at DESC LIMIT 1000
...
@@ -422,9 +424,77 @@ and am.agent_mode like '{"enabled": true%' ORDER BY a.created_at DESC LIMIT 1000
click
.
echo
(
click
.
style
(
'Congratulations! Converted {} agent apps.'
.
format
(
len
(
proceeded_app_ids
)),
fg
=
'green'
))
click
.
echo
(
click
.
style
(
'Congratulations! Converted {} agent apps.'
.
format
(
len
(
proceeded_app_ids
)),
fg
=
'green'
))
@
click
.
command
(
'convert-to-workflow-chatbot-apps'
,
help
=
'Convert Basic Export Assistant to Chatbot Workflow App.'
)
def
convert_to_workflow_chatbot_apps
():
"""
Convert Basic Export Assistant to Chatbot Workflow App.
"""
click
.
echo
(
click
.
style
(
'Start convert to workflow chatbot apps.'
,
fg
=
'green'
))
proceeded_app_ids
=
[]
workflow_converter
=
WorkflowConverter
()
while
True
:
# fetch first 1000 apps
sql_query
=
"""SELECT a.id FROM apps a
LEFT JOIN app_model_configs am ON a.app_model_config_id=am.id
WHERE a.mode = 'chat' AND am.prompt_type='advanced' ORDER BY a.created_at DESC LIMIT 1000"""
with
db
.
engine
.
begin
()
as
conn
:
rs
=
conn
.
execute
(
db
.
text
(
sql_query
))
apps
=
[]
for
i
in
rs
:
app_id
=
str
(
i
.
id
)
print
(
app_id
)
if
app_id
not
in
proceeded_app_ids
:
proceeded_app_ids
.
append
(
app_id
)
app
=
db
.
session
.
query
(
App
)
.
filter
(
App
.
id
==
app_id
)
.
first
()
apps
.
append
(
app
)
if
len
(
apps
)
==
0
:
break
for
app
in
apps
:
click
.
echo
(
'Converting app: {}'
.
format
(
app
.
id
))
try
:
# get workspace of app
tenant
=
db
.
session
.
query
(
Tenant
)
.
filter
(
Tenant
.
id
==
app
.
tenant_id
)
.
first
()
if
not
tenant
:
click
.
echo
(
click
.
style
(
'Tenant not found: {}'
.
format
(
app
.
tenant_id
),
fg
=
'red'
))
continue
# get workspace owner
tenant_account_join
=
db
.
session
.
query
(
TenantAccountJoin
)
.
filter
(
TenantAccountJoin
.
tenant_id
==
tenant
.
id
,
TenantAccountJoin
.
role
==
'owner'
)
.
first
()
if
not
tenant_account_join
:
click
.
echo
(
click
.
style
(
'Tenant owner not found: {}'
.
format
(
tenant
.
id
),
fg
=
'red'
))
continue
# convert to workflow
workflow_converter
.
convert_to_workflow
(
app_model
=
app
,
account_id
=
tenant_account_join
.
account_id
)
click
.
echo
(
click
.
style
(
'Converted app: {}'
.
format
(
app
.
id
),
fg
=
'green'
))
except
Exception
as
e
:
logging
.
exception
(
'Convert app error: {}'
.
format
(
app
.
id
))
click
.
echo
(
click
.
style
(
'Convert app error: {} {}'
.
format
(
e
.
__class__
.
__name__
,
str
(
e
)),
fg
=
'red'
))
click
.
echo
(
click
.
style
(
'Congratulations! Converted {} workflow chatbot apps.'
.
format
(
len
(
proceeded_app_ids
)),
fg
=
'green'
))
def
register_commands
(
app
):
def
register_commands
(
app
):
app
.
cli
.
add_command
(
reset_password
)
app
.
cli
.
add_command
(
reset_password
)
app
.
cli
.
add_command
(
reset_email
)
app
.
cli
.
add_command
(
reset_email
)
app
.
cli
.
add_command
(
reset_encrypt_key_pair
)
app
.
cli
.
add_command
(
reset_encrypt_key_pair
)
app
.
cli
.
add_command
(
vdb_migrate
)
app
.
cli
.
add_command
(
vdb_migrate
)
app
.
cli
.
add_command
(
convert_to_agent_apps
)
app
.
cli
.
add_command
(
convert_to_agent_apps
)
app
.
cli
.
add_command
(
convert_to_workflow_chatbot_apps
)
api/core/application_manager.py
View file @
afb0ff37
...
@@ -235,12 +235,15 @@ class ApplicationManager:
...
@@ -235,12 +235,15 @@ class ApplicationManager:
logger
.
exception
(
e
)
logger
.
exception
(
e
)
raise
e
raise
e
def
convert_from_app_model_config_dict
(
self
,
tenant_id
:
str
,
app_model_config_dict
:
dict
)
\
def
convert_from_app_model_config_dict
(
self
,
tenant_id
:
str
,
app_model_config_dict
:
dict
,
skip_check
:
bool
=
False
)
\
->
AppOrchestrationConfigEntity
:
->
AppOrchestrationConfigEntity
:
"""
"""
Convert app model config dict to entity.
Convert app model config dict to entity.
:param tenant_id: tenant ID
:param tenant_id: tenant ID
:param app_model_config_dict: app model config dict
:param app_model_config_dict: app model config dict
:param skip_check: skip check
:raises ProviderTokenNotInitError: provider token not init error
:raises ProviderTokenNotInitError: provider token not init error
:return: app orchestration config entity
:return: app orchestration config entity
"""
"""
...
@@ -268,24 +271,28 @@ class ApplicationManager:
...
@@ -268,24 +271,28 @@ class ApplicationManager:
)
)
if
model_credentials
is
None
:
if
model_credentials
is
None
:
raise
ProviderTokenNotInitError
(
f
"Model {model_name} credentials is not initialized."
)
if
not
skip_check
:
raise
ProviderTokenNotInitError
(
f
"Model {model_name} credentials is not initialized."
)
else
:
model_credentials
=
{}
# check model
if
not
skip_check
:
provider_model
=
provider_model_bundle
.
configuration
.
get_provider_model
(
# check model
model
=
copy_app_model_config_dict
[
'model'
][
'name'
],
provider_model
=
provider_model_bundle
.
configuration
.
get_provider_model
(
model_type
=
ModelType
.
LLM
model
=
copy_app_model_config_dict
[
'model'
][
'name'
],
)
model_type
=
ModelType
.
LLM
)
if
provider_model
is
None
:
if
provider_model
is
None
:
model_name
=
copy_app_model_config_dict
[
'model'
][
'name'
]
model_name
=
copy_app_model_config_dict
[
'model'
][
'name'
]
raise
ValueError
(
f
"Model {model_name} not exist."
)
raise
ValueError
(
f
"Model {model_name} not exist."
)
if
provider_model
.
status
==
ModelStatus
.
NO_CONFIGURE
:
if
provider_model
.
status
==
ModelStatus
.
NO_CONFIGURE
:
raise
ProviderTokenNotInitError
(
f
"Model {model_name} credentials is not initialized."
)
raise
ProviderTokenNotInitError
(
f
"Model {model_name} credentials is not initialized."
)
elif
provider_model
.
status
==
ModelStatus
.
NO_PERMISSION
:
elif
provider_model
.
status
==
ModelStatus
.
NO_PERMISSION
:
raise
ModelCurrentlyNotSupportError
(
f
"Dify Hosted OpenAI {model_name} currently not support."
)
raise
ModelCurrentlyNotSupportError
(
f
"Dify Hosted OpenAI {model_name} currently not support."
)
elif
provider_model
.
status
==
ModelStatus
.
QUOTA_EXCEEDED
:
elif
provider_model
.
status
==
ModelStatus
.
QUOTA_EXCEEDED
:
raise
QuotaExceededError
(
f
"Model provider {provider_name} quota exceeded."
)
raise
QuotaExceededError
(
f
"Model provider {provider_name} quota exceeded."
)
# model config
# model config
completion_params
=
copy_app_model_config_dict
[
'model'
]
.
get
(
'completion_params'
)
completion_params
=
copy_app_model_config_dict
[
'model'
]
.
get
(
'completion_params'
)
...
@@ -309,7 +316,7 @@ class ApplicationManager:
...
@@ -309,7 +316,7 @@ class ApplicationManager:
model_credentials
model_credentials
)
)
if
not
model_schema
:
if
not
skip_check
and
not
model_schema
:
raise
ValueError
(
f
"Model {model_name} not exist."
)
raise
ValueError
(
f
"Model {model_name} not exist."
)
properties
[
'model_config'
]
=
ModelConfigEntity
(
properties
[
'model_config'
]
=
ModelConfigEntity
(
...
...
api/core/entities/application_entities.py
View file @
afb0ff37
...
@@ -15,7 +15,7 @@ class ModelConfigEntity(BaseModel):
...
@@ -15,7 +15,7 @@ class ModelConfigEntity(BaseModel):
"""
"""
provider
:
str
provider
:
str
model
:
str
model
:
str
model_schema
:
AIModelEntity
model_schema
:
Optional
[
AIModelEntity
]
=
None
mode
:
str
mode
:
str
provider_model_bundle
:
ProviderModelBundle
provider_model_bundle
:
ProviderModelBundle
credentials
:
dict
[
str
,
Any
]
=
{}
credentials
:
dict
[
str
,
Any
]
=
{}
...
...
api/services/workflow/workflow_converter.py
View file @
afb0ff37
...
@@ -13,12 +13,11 @@ from core.entities.application_entities import (
...
@@ -13,12 +13,11 @@ from core.entities.application_entities import (
)
)
from
core.helper
import
encrypter
from
core.helper
import
encrypter
from
core.model_runtime.entities.llm_entities
import
LLMMode
from
core.model_runtime.entities.llm_entities
import
LLMMode
from
core.model_runtime.utils
import
help
er
from
core.model_runtime.utils
.encoders
import
jsonable_encod
er
from
core.prompt.simple_prompt_transform
import
SimplePromptTransform
from
core.prompt.simple_prompt_transform
import
SimplePromptTransform
from
core.workflow.entities.NodeEntities
import
NodeType
from
core.workflow.entities.NodeEntities
import
NodeType
from
core.workflow.nodes.end.entities
import
EndNodeOutputType
from
core.workflow.nodes.end.entities
import
EndNodeOutputType
from
extensions.ext_database
import
db
from
extensions.ext_database
import
db
from
models.account
import
Account
from
models.api_based_extension
import
APIBasedExtension
,
APIBasedExtensionPoint
from
models.api_based_extension
import
APIBasedExtension
,
APIBasedExtensionPoint
from
models.model
import
App
,
AppMode
,
ChatbotAppEngine
from
models.model
import
App
,
AppMode
,
ChatbotAppEngine
from
models.workflow
import
Workflow
,
WorkflowType
from
models.workflow
import
Workflow
,
WorkflowType
...
@@ -29,7 +28,7 @@ class WorkflowConverter:
...
@@ -29,7 +28,7 @@ class WorkflowConverter:
App Convert to Workflow Mode
App Convert to Workflow Mode
"""
"""
def
convert_to_workflow
(
self
,
app_model
:
App
,
account
:
Account
)
->
Workflow
:
def
convert_to_workflow
(
self
,
app_model
:
App
,
account
_id
:
str
)
->
Workflow
:
"""
"""
Convert to workflow mode
Convert to workflow mode
...
@@ -40,7 +39,7 @@ class WorkflowConverter:
...
@@ -40,7 +39,7 @@ class WorkflowConverter:
- completion app (for migration)
- completion app (for migration)
:param app_model: App instance
:param app_model: App instance
:param account
: Account instance
:param account
_id: Account ID
:return: workflow instance
:return: workflow instance
"""
"""
# get new app mode
# get new app mode
...
@@ -53,7 +52,8 @@ class WorkflowConverter:
...
@@ -53,7 +52,8 @@ class WorkflowConverter:
application_manager
=
ApplicationManager
()
application_manager
=
ApplicationManager
()
app_orchestration_config_entity
=
application_manager
.
convert_from_app_model_config_dict
(
app_orchestration_config_entity
=
application_manager
.
convert_from_app_model_config_dict
(
tenant_id
=
app_model
.
tenant_id
,
tenant_id
=
app_model
.
tenant_id
,
app_model_config_dict
=
app_model_config
.
to_dict
()
app_model_config_dict
=
app_model_config
.
to_dict
(),
skip_check
=
True
)
)
# init workflow graph
# init workflow graph
...
@@ -122,7 +122,7 @@ class WorkflowConverter:
...
@@ -122,7 +122,7 @@ class WorkflowConverter:
type
=
WorkflowType
.
from_app_mode
(
new_app_mode
)
.
value
,
type
=
WorkflowType
.
from_app_mode
(
new_app_mode
)
.
value
,
version
=
'draft'
,
version
=
'draft'
,
graph
=
json
.
dumps
(
graph
),
graph
=
json
.
dumps
(
graph
),
created_by
=
account
.
id
created_by
=
account
_
id
)
)
db
.
session
.
add
(
workflow
)
db
.
session
.
add
(
workflow
)
...
@@ -130,6 +130,7 @@ class WorkflowConverter:
...
@@ -130,6 +130,7 @@ class WorkflowConverter:
# create new app model config record
# create new app model config record
new_app_model_config
=
app_model_config
.
copy
()
new_app_model_config
=
app_model_config
.
copy
()
new_app_model_config
.
id
=
None
new_app_model_config
.
external_data_tools
=
''
new_app_model_config
.
external_data_tools
=
''
new_app_model_config
.
model
=
''
new_app_model_config
.
model
=
''
new_app_model_config
.
user_input_form
=
''
new_app_model_config
.
user_input_form
=
''
...
@@ -147,6 +148,9 @@ class WorkflowConverter:
...
@@ -147,6 +148,9 @@ class WorkflowConverter:
db
.
session
.
add
(
new_app_model_config
)
db
.
session
.
add
(
new_app_model_config
)
db
.
session
.
commit
()
db
.
session
.
commit
()
app_model
.
app_model_config_id
=
new_app_model_config
.
id
db
.
session
.
commit
()
return
workflow
return
workflow
def
_convert_to_start_node
(
self
,
variables
:
list
[
VariableEntity
])
->
dict
:
def
_convert_to_start_node
(
self
,
variables
:
list
[
VariableEntity
])
->
dict
:
...
@@ -161,7 +165,7 @@ class WorkflowConverter:
...
@@ -161,7 +165,7 @@ class WorkflowConverter:
"data"
:
{
"data"
:
{
"title"
:
"START"
,
"title"
:
"START"
,
"type"
:
NodeType
.
START
.
value
,
"type"
:
NodeType
.
START
.
value
,
"variables"
:
[
helper
.
dump_model
(
v
)
for
v
in
variables
]
"variables"
:
[
jsonable_encoder
(
v
)
for
v
in
variables
]
}
}
}
}
...
@@ -369,7 +373,10 @@ class WorkflowConverter:
...
@@ -369,7 +373,10 @@ class WorkflowConverter:
]
]
else
:
else
:
advanced_chat_prompt_template
=
prompt_template
.
advanced_chat_prompt_template
advanced_chat_prompt_template
=
prompt_template
.
advanced_chat_prompt_template
prompts
=
[
helper
.
dump_model
(
m
)
for
m
in
advanced_chat_prompt_template
.
messages
]
\
prompts
=
[{
"role"
:
m
.
role
.
value
,
"text"
:
m
.
text
}
for
m
in
advanced_chat_prompt_template
.
messages
]
\
if
advanced_chat_prompt_template
else
[]
if
advanced_chat_prompt_template
else
[]
# Completion Model
# Completion Model
else
:
else
:
...
...
api/services/workflow_service.py
View file @
afb0ff37
...
@@ -79,6 +79,6 @@ class WorkflowService:
...
@@ -79,6 +79,6 @@ class WorkflowService:
# convert to workflow mode
# convert to workflow mode
workflow_converter
=
WorkflowConverter
()
workflow_converter
=
WorkflowConverter
()
workflow
=
workflow_converter
.
convert_to_workflow
(
app_model
=
app_model
,
account
=
account
)
workflow
=
workflow_converter
.
convert_to_workflow
(
app_model
=
app_model
,
account
_id
=
account
.
id
)
return
workflow
return
workflow
api/tests/unit_tests/services/workflow/test_workflow_converter.py
View file @
afb0ff37
...
@@ -41,6 +41,8 @@ def test__convert_to_start_node(default_variables):
...
@@ -41,6 +41,8 @@ def test__convert_to_start_node(default_variables):
result
=
WorkflowConverter
()
.
_convert_to_start_node
(
default_variables
)
result
=
WorkflowConverter
()
.
_convert_to_start_node
(
default_variables
)
# assert
# assert
assert
isinstance
(
result
[
"data"
][
"variables"
][
0
][
"type"
],
str
)
assert
result
[
"data"
][
"variables"
][
0
][
"type"
]
==
"text-input"
assert
result
[
"data"
][
"variables"
][
0
][
"variable"
]
==
"text-input"
assert
result
[
"data"
][
"variables"
][
0
][
"variable"
]
==
"text-input"
assert
result
[
"data"
][
"variables"
][
1
][
"variable"
]
==
"paragraph"
assert
result
[
"data"
][
"variables"
][
1
][
"variable"
]
==
"paragraph"
assert
result
[
"data"
][
"variables"
][
2
][
"variable"
]
==
"select"
assert
result
[
"data"
][
"variables"
][
2
][
"variable"
]
==
"select"
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment