Commit 116e02ec authored by takatost's avatar takatost

refactor app mode

add app import and export
parent 62797bca
This diff is collapsed.
import json from models.model import AppMode
model_templates = { default_app_templates = {
# workflow default mode # workflow default mode
'workflow_default': { AppMode.WORKFLOW: {
'app': { 'app': {
'mode': 'workflow', 'mode': AppMode.WORKFLOW.value,
'enable_site': True, 'enable_site': True,
'enable_api': True, 'enable_api': True
'is_demo': False,
'api_rpm': 0,
'api_rph': 0,
'status': 'normal'
}, },
'model_config': { 'model_config': {}
'provider': '',
'model_id': '',
'configs': {}
}
}, },
# chat default mode # chat default mode
'chat_default': { AppMode.CHAT: {
'app': { 'app': {
'mode': 'chat', 'mode': AppMode.CHAT.value,
'enable_site': True, 'enable_site': True,
'enable_api': True, 'enable_api': True
'is_demo': False,
'api_rpm': 0,
'api_rph': 0,
'status': 'normal'
}, },
'model_config': { 'model_config': {
'provider': 'openai', 'model': {
'model_id': 'gpt-4',
'configs': {
'prompt_template': '',
'prompt_variables': [],
'completion_params': {
'max_token': 512,
'temperature': 1,
'top_p': 1,
'presence_penalty': 0,
'frequency_penalty': 0,
}
},
'model': json.dumps({
"provider": "openai", "provider": "openai",
"name": "gpt-4", "name": "gpt-4",
"mode": "chat", "mode": "chat",
...@@ -55,36 +30,42 @@ model_templates = { ...@@ -55,36 +30,42 @@ model_templates = {
"presence_penalty": 0, "presence_penalty": 0,
"frequency_penalty": 0 "frequency_penalty": 0
} }
}) }
} }
}, },
# agent default mode # advanced-chat default mode
'agent_default': { AppMode.ADVANCED_CHAT: {
'app': { 'app': {
'mode': 'agent', 'mode': AppMode.ADVANCED_CHAT.value,
'enable_site': True, 'enable_site': True,
'enable_api': True, 'enable_api': True
'is_demo': False,
'api_rpm': 0,
'api_rph': 0,
'status': 'normal'
}, },
'model_config': { 'model_config': {
'provider': 'openai', 'model': {
'model_id': 'gpt-4', "provider": "openai",
'configs': { "name": "gpt-4",
'prompt_template': '', "mode": "chat",
'prompt_variables': [], "completion_params": {
'completion_params': { "max_tokens": 512,
'max_token': 512, "temperature": 1,
'temperature': 1, "top_p": 1,
'top_p': 1, "presence_penalty": 0,
'presence_penalty': 0, "frequency_penalty": 0
'frequency_penalty': 0,
} }
}, }
'model': json.dumps({ }
},
# agent-chat default mode
AppMode.AGENT_CHAT: {
'app': {
'mode': AppMode.AGENT_CHAT.value,
'enable_site': True,
'enable_api': True
},
'model_config': {
'model': {
"provider": "openai", "provider": "openai",
"name": "gpt-4", "name": "gpt-4",
"mode": "chat", "mode": "chat",
...@@ -95,7 +76,7 @@ model_templates = { ...@@ -95,7 +76,7 @@ model_templates = {
"presence_penalty": 0, "presence_penalty": 0,
"frequency_penalty": 0 "frequency_penalty": 0
} }
}) }
} }
}, },
} }
......
This diff is collapsed.
...@@ -7,7 +7,7 @@ from controllers.console.setup import setup_required ...@@ -7,7 +7,7 @@ from controllers.console.setup import setup_required
from controllers.console.wraps import account_initialization_required from controllers.console.wraps import account_initialization_required
from fields.workflow_fields import workflow_fields from fields.workflow_fields import workflow_fields
from libs.login import current_user, login_required from libs.login import current_user, login_required
from models.model import App, AppMode, ChatbotAppEngine from models.model import App, AppMode
from services.workflow_service import WorkflowService from services.workflow_service import WorkflowService
...@@ -15,7 +15,7 @@ class DraftWorkflowApi(Resource): ...@@ -15,7 +15,7 @@ class DraftWorkflowApi(Resource):
@setup_required @setup_required
@login_required @login_required
@account_initialization_required @account_initialization_required
@get_app_model(mode=[AppMode.CHAT, AppMode.WORKFLOW], app_engine=ChatbotAppEngine.WORKFLOW) @get_app_model(mode=[AppMode.ADVANCED_CHAT, AppMode.WORKFLOW])
@marshal_with(workflow_fields) @marshal_with(workflow_fields)
def get(self, app_model: App): def get(self, app_model: App):
""" """
...@@ -34,7 +34,7 @@ class DraftWorkflowApi(Resource): ...@@ -34,7 +34,7 @@ class DraftWorkflowApi(Resource):
@setup_required @setup_required
@login_required @login_required
@account_initialization_required @account_initialization_required
@get_app_model(mode=[AppMode.CHAT, AppMode.WORKFLOW], app_engine=ChatbotAppEngine.WORKFLOW) @get_app_model(mode=[AppMode.ADVANCED_CHAT, AppMode.WORKFLOW])
def post(self, app_model: App): def post(self, app_model: App):
""" """
Sync draft workflow Sync draft workflow
...@@ -55,7 +55,7 @@ class DefaultBlockConfigApi(Resource): ...@@ -55,7 +55,7 @@ class DefaultBlockConfigApi(Resource):
@setup_required @setup_required
@login_required @login_required
@account_initialization_required @account_initialization_required
@get_app_model(mode=[AppMode.CHAT, AppMode.WORKFLOW], app_engine=ChatbotAppEngine.WORKFLOW) @get_app_model(mode=[AppMode.ADVANCED_CHAT, AppMode.WORKFLOW])
def get(self, app_model: App): def get(self, app_model: App):
""" """
Get default block config Get default block config
...@@ -72,7 +72,8 @@ class ConvertToWorkflowApi(Resource): ...@@ -72,7 +72,8 @@ class ConvertToWorkflowApi(Resource):
@get_app_model(mode=[AppMode.CHAT, AppMode.COMPLETION]) @get_app_model(mode=[AppMode.CHAT, AppMode.COMPLETION])
def post(self, app_model: App): def post(self, app_model: App):
""" """
Convert basic mode of chatbot app(expert mode) to workflow mode Convert basic mode of chatbot app to workflow mode
Convert expert mode of chatbot app to workflow mode
Convert Completion App to Workflow App Convert Completion App to Workflow App
""" """
# convert to workflow mode # convert to workflow mode
......
...@@ -5,12 +5,11 @@ from typing import Optional, Union ...@@ -5,12 +5,11 @@ from typing import Optional, Union
from controllers.console.app.error import AppNotFoundError from controllers.console.app.error import AppNotFoundError
from extensions.ext_database import db from extensions.ext_database import db
from libs.login import current_user from libs.login import current_user
from models.model import App, AppMode, ChatbotAppEngine from models.model import App, AppMode
def get_app_model(view: Optional[Callable] = None, *, def get_app_model(view: Optional[Callable] = None, *,
mode: Union[AppMode, list[AppMode]] = None, mode: Union[AppMode, list[AppMode]] = None):
app_engine: ChatbotAppEngine = None):
def decorator(view_func): def decorator(view_func):
@wraps(view_func) @wraps(view_func)
def decorated_view(*args, **kwargs): def decorated_view(*args, **kwargs):
...@@ -32,6 +31,9 @@ def get_app_model(view: Optional[Callable] = None, *, ...@@ -32,6 +31,9 @@ def get_app_model(view: Optional[Callable] = None, *,
raise AppNotFoundError() raise AppNotFoundError()
app_mode = AppMode.value_of(app_model.mode) app_mode = AppMode.value_of(app_model.mode)
if app_mode == AppMode.CHANNEL:
raise AppNotFoundError()
if mode is not None: if mode is not None:
if isinstance(mode, list): if isinstance(mode, list):
modes = mode modes = mode
...@@ -42,16 +44,6 @@ def get_app_model(view: Optional[Callable] = None, *, ...@@ -42,16 +44,6 @@ def get_app_model(view: Optional[Callable] = None, *,
mode_values = {m.value for m in modes} mode_values = {m.value for m in modes}
raise AppNotFoundError(f"App mode is not in the supported list: {mode_values}") raise AppNotFoundError(f"App mode is not in the supported list: {mode_values}")
if app_engine is not None:
if app_mode not in [AppMode.CHAT, AppMode.WORKFLOW]:
raise AppNotFoundError(f"App mode is not supported for {app_engine.value} app engine.")
if app_mode == AppMode.CHAT:
# fetch current app model config
app_model_config = app_model.app_model_config
if not app_model_config or app_model_config.chatbot_app_engine != app_engine.value:
raise AppNotFoundError(f"{app_engine.value} app engine is not supported.")
kwargs['app_model'] = app_model kwargs['app_model'] = app_model
return view_func(*args, **kwargs) return view_func(*args, **kwargs)
......
...@@ -34,8 +34,7 @@ class InstalledAppsListApi(Resource): ...@@ -34,8 +34,7 @@ class InstalledAppsListApi(Resource):
'is_pinned': installed_app.is_pinned, 'is_pinned': installed_app.is_pinned,
'last_used_at': installed_app.last_used_at, 'last_used_at': installed_app.last_used_at,
'editable': current_user.role in ["owner", "admin"], 'editable': current_user.role in ["owner", "admin"],
'uninstallable': current_tenant_id == installed_app.app_owner_tenant_id, 'uninstallable': current_tenant_id == installed_app.app_owner_tenant_id
'is_agent': installed_app.is_agent
} }
for installed_app in installed_apps for installed_app in installed_apps
] ]
......
import json
import yaml
from flask_login import current_user from flask_login import current_user
from flask_restful import Resource, fields, marshal_with, reqparse from flask_restful import Resource, fields, marshal_with, reqparse
...@@ -6,6 +9,7 @@ from controllers.console import api ...@@ -6,6 +9,7 @@ from controllers.console import api
from controllers.console.app.error import AppNotFoundError from controllers.console.app.error import AppNotFoundError
from extensions.ext_database import db from extensions.ext_database import db
from models.model import App, RecommendedApp from models.model import App, RecommendedApp
from services.workflow_service import WorkflowService
app_fields = { app_fields = {
'id': fields.String, 'id': fields.String,
...@@ -23,8 +27,7 @@ recommended_app_fields = { ...@@ -23,8 +27,7 @@ recommended_app_fields = {
'privacy_policy': fields.String, 'privacy_policy': fields.String,
'category': fields.String, 'category': fields.String,
'position': fields.Integer, 'position': fields.Integer,
'is_listed': fields.Boolean, 'is_listed': fields.Boolean
'is_agent': fields.Boolean
} }
recommended_app_list_fields = { recommended_app_list_fields = {
...@@ -73,8 +76,7 @@ class RecommendedAppListApi(Resource): ...@@ -73,8 +76,7 @@ class RecommendedAppListApi(Resource):
'privacy_policy': site.privacy_policy, 'privacy_policy': site.privacy_policy,
'category': recommended_app.category, 'category': recommended_app.category,
'position': recommended_app.position, 'position': recommended_app.position,
'is_listed': recommended_app.is_listed, 'is_listed': recommended_app.is_listed
"is_agent": app.is_agent
} }
recommended_apps_result.append(recommended_app_result) recommended_apps_result.append(recommended_app_result)
...@@ -84,27 +86,6 @@ class RecommendedAppListApi(Resource): ...@@ -84,27 +86,6 @@ class RecommendedAppListApi(Resource):
class RecommendedAppApi(Resource): class RecommendedAppApi(Resource):
model_config_fields = {
'opening_statement': fields.String,
'suggested_questions': fields.Raw(attribute='suggested_questions_list'),
'suggested_questions_after_answer': fields.Raw(attribute='suggested_questions_after_answer_dict'),
'more_like_this': fields.Raw(attribute='more_like_this_dict'),
'model': fields.Raw(attribute='model_dict'),
'user_input_form': fields.Raw(attribute='user_input_form_list'),
'pre_prompt': fields.String,
'agent_mode': fields.Raw(attribute='agent_mode_dict'),
}
app_simple_detail_fields = {
'id': fields.String,
'name': fields.String,
'icon': fields.String,
'icon_background': fields.String,
'mode': fields.String,
'app_model_config': fields.Nested(model_config_fields),
}
@marshal_with(app_simple_detail_fields)
def get(self, app_id): def get(self, app_id):
app_id = str(app_id) app_id = str(app_id)
...@@ -118,11 +99,38 @@ class RecommendedAppApi(Resource): ...@@ -118,11 +99,38 @@ class RecommendedAppApi(Resource):
raise AppNotFoundError raise AppNotFoundError
# get app detail # get app detail
app = db.session.query(App).filter(App.id == app_id).first() app_model = db.session.query(App).filter(App.id == app_id).first()
if not app or not app.is_public: if not app_model or not app_model.is_public:
raise AppNotFoundError raise AppNotFoundError
return app app_model_config = app_model.app_model_config
export_data = {
"app": {
"name": app_model.name,
"mode": app_model.mode,
"icon": app_model.icon,
"icon_background": app_model.icon_background
},
"model_config": app_model_config.to_dict(),
}
if app_model_config.workflow_id:
export_data['workflow_graph'] = json.loads(app_model_config.workflow.graph)
else:
# get draft workflow
workflow_service = WorkflowService()
workflow = workflow_service.get_draft_workflow(app_model)
export_data['workflow_graph'] = json.loads(workflow.graph)
return {
'id': app_model.id,
'name': app_model.name,
'icon': app_model.icon,
'icon_background': app_model.icon_background,
'mode': app_model.mode,
'export_data': yaml.dump(export_data)
}
api.add_resource(RecommendedAppListApi, '/explore/apps') api.add_resource(RecommendedAppListApi, '/explore/apps')
......
...@@ -235,7 +235,7 @@ class ProviderManager: ...@@ -235,7 +235,7 @@ class ProviderManager:
if available_models: if available_models:
found = False found = False
for available_model in available_models: for available_model in available_models:
if available_model.model == "gpt-3.5-turbo-1106": if available_model.model == "gpt-4":
default_model = TenantDefaultModel( default_model = TenantDefaultModel(
tenant_id=tenant_id, tenant_id=tenant_id,
model_type=model_type.to_origin_model_type(), model_type=model_type.to_origin_model_type(),
......
...@@ -42,14 +42,10 @@ app_detail_fields = { ...@@ -42,14 +42,10 @@ app_detail_fields = {
'id': fields.String, 'id': fields.String,
'name': fields.String, 'name': fields.String,
'mode': fields.String, 'mode': fields.String,
'is_agent': fields.Boolean,
'icon': fields.String, 'icon': fields.String,
'icon_background': fields.String, 'icon_background': fields.String,
'enable_site': fields.Boolean, 'enable_site': fields.Boolean,
'enable_api': fields.Boolean, 'enable_api': fields.Boolean,
'api_rpm': fields.Integer,
'api_rph': fields.Integer,
'is_demo': fields.Boolean,
'model_config': fields.Nested(model_config_fields, attribute='app_model_config'), 'model_config': fields.Nested(model_config_fields, attribute='app_model_config'),
'created_at': TimestampField 'created_at': TimestampField
} }
...@@ -67,12 +63,8 @@ app_partial_fields = { ...@@ -67,12 +63,8 @@ app_partial_fields = {
'id': fields.String, 'id': fields.String,
'name': fields.String, 'name': fields.String,
'mode': fields.String, 'mode': fields.String,
'is_agent': fields.Boolean,
'icon': fields.String, 'icon': fields.String,
'icon_background': fields.String, 'icon_background': fields.String,
'enable_site': fields.Boolean,
'enable_api': fields.Boolean,
'is_demo': fields.Boolean,
'model_config': fields.Nested(model_config_partial_fields, attribute='app_model_config'), 'model_config': fields.Nested(model_config_partial_fields, attribute='app_model_config'),
'created_at': TimestampField 'created_at': TimestampField
} }
...@@ -122,10 +114,6 @@ app_detail_fields_with_site = { ...@@ -122,10 +114,6 @@ app_detail_fields_with_site = {
'icon_background': fields.String, 'icon_background': fields.String,
'enable_site': fields.Boolean, 'enable_site': fields.Boolean,
'enable_api': fields.Boolean, 'enable_api': fields.Boolean,
'api_rpm': fields.Integer,
'api_rph': fields.Integer,
'is_agent': fields.Boolean,
'is_demo': fields.Boolean,
'model_config': fields.Nested(model_config_fields, attribute='app_model_config'), 'model_config': fields.Nested(model_config_fields, attribute='app_model_config'),
'site': fields.Nested(site_fields), 'site': fields.Nested(site_fields),
'api_base_url': fields.String, 'api_base_url': fields.String,
......
...@@ -17,8 +17,7 @@ installed_app_fields = { ...@@ -17,8 +17,7 @@ installed_app_fields = {
'is_pinned': fields.Boolean, 'is_pinned': fields.Boolean,
'last_used_at': TimestampField, 'last_used_at': TimestampField,
'editable': fields.Boolean, 'editable': fields.Boolean,
'uninstallable': fields.Boolean, 'uninstallable': fields.Boolean
'is_agent': fields.Boolean,
} }
installed_app_list_fields = { installed_app_list_fields = {
......
...@@ -107,7 +107,6 @@ def upgrade(): ...@@ -107,7 +107,6 @@ def upgrade():
batch_op.create_index('workflow_version_idx', ['tenant_id', 'app_id', 'version'], unique=False) batch_op.create_index('workflow_version_idx', ['tenant_id', 'app_id', 'version'], unique=False)
with op.batch_alter_table('app_model_configs', schema=None) as batch_op: with op.batch_alter_table('app_model_configs', schema=None) as batch_op:
batch_op.add_column(sa.Column('chatbot_app_engine', sa.String(length=255), server_default=sa.text("'normal'::character varying"), nullable=False))
batch_op.add_column(sa.Column('workflow_id', postgresql.UUID(), nullable=True)) batch_op.add_column(sa.Column('workflow_id', postgresql.UUID(), nullable=True))
with op.batch_alter_table('messages', schema=None) as batch_op: with op.batch_alter_table('messages', schema=None) as batch_op:
...@@ -123,7 +122,6 @@ def downgrade(): ...@@ -123,7 +122,6 @@ def downgrade():
with op.batch_alter_table('app_model_configs', schema=None) as batch_op: with op.batch_alter_table('app_model_configs', schema=None) as batch_op:
batch_op.drop_column('workflow_id') batch_op.drop_column('workflow_id')
batch_op.drop_column('chatbot_app_engine')
with op.batch_alter_table('workflows', schema=None) as batch_op: with op.batch_alter_table('workflows', schema=None) as batch_op:
batch_op.drop_index('workflow_version_idx') batch_op.drop_index('workflow_version_idx')
......
"""set model config column nullable
Revision ID: cc04d0998d4d
Revises: b289e2408ee2
Create Date: 2024-02-27 03:47:47.376325
"""
from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import postgresql
# revision identifiers, used by Alembic.
revision = 'cc04d0998d4d'
down_revision = 'b289e2408ee2'
branch_labels = None
depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
with op.batch_alter_table('app_model_configs', schema=None) as batch_op:
batch_op.alter_column('provider',
existing_type=sa.VARCHAR(length=255),
nullable=True)
batch_op.alter_column('model_id',
existing_type=sa.VARCHAR(length=255),
nullable=True)
batch_op.alter_column('configs',
existing_type=postgresql.JSON(astext_type=sa.Text()),
nullable=True)
with op.batch_alter_table('apps', schema=None) as batch_op:
batch_op.alter_column('api_rpm',
existing_type=sa.Integer(),
server_default='0',
nullable=False)
batch_op.alter_column('api_rph',
existing_type=sa.Integer(),
server_default='0',
nullable=False)
# ### end Alembic commands ###
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
with op.batch_alter_table('apps', schema=None) as batch_op:
batch_op.alter_column('api_rpm',
existing_type=sa.Integer(),
server_default=None,
nullable=False)
batch_op.alter_column('api_rph',
existing_type=sa.Integer(),
server_default=None,
nullable=False)
with op.batch_alter_table('app_model_configs', schema=None) as batch_op:
batch_op.alter_column('configs',
existing_type=postgresql.JSON(astext_type=sa.Text()),
nullable=False)
batch_op.alter_column('model_id',
existing_type=sa.VARCHAR(length=255),
nullable=False)
batch_op.alter_column('provider',
existing_type=sa.VARCHAR(length=255),
nullable=False)
# ### end Alembic commands ###
...@@ -31,7 +31,9 @@ class AppMode(Enum): ...@@ -31,7 +31,9 @@ class AppMode(Enum):
COMPLETION = 'completion' COMPLETION = 'completion'
WORKFLOW = 'workflow' WORKFLOW = 'workflow'
CHAT = 'chat' CHAT = 'chat'
AGENT = 'agent' ADVANCED_CHAT = 'advanced-chat'
AGENT_CHAT = 'agent-chat'
CHANNEL = 'channel'
@classmethod @classmethod
def value_of(cls, value: str) -> 'AppMode': def value_of(cls, value: str) -> 'AppMode':
...@@ -64,8 +66,8 @@ class App(db.Model): ...@@ -64,8 +66,8 @@ class App(db.Model):
status = db.Column(db.String(255), nullable=False, server_default=db.text("'normal'::character varying")) status = db.Column(db.String(255), nullable=False, server_default=db.text("'normal'::character varying"))
enable_site = db.Column(db.Boolean, nullable=False) enable_site = db.Column(db.Boolean, nullable=False)
enable_api = db.Column(db.Boolean, nullable=False) enable_api = db.Column(db.Boolean, nullable=False)
api_rpm = db.Column(db.Integer, nullable=False) api_rpm = db.Column(db.Integer, nullable=False, server_default=db.text('0'))
api_rph = db.Column(db.Integer, nullable=False) api_rph = db.Column(db.Integer, nullable=False, server_default=db.text('0'))
is_demo = db.Column(db.Boolean, nullable=False, server_default=db.text('false')) is_demo = db.Column(db.Boolean, nullable=False, server_default=db.text('false'))
is_public = db.Column(db.Boolean, nullable=False, server_default=db.text('false')) is_public = db.Column(db.Boolean, nullable=False, server_default=db.text('false'))
is_universal = db.Column(db.Boolean, nullable=False, server_default=db.text('false')) is_universal = db.Column(db.Boolean, nullable=False, server_default=db.text('false'))
...@@ -92,19 +94,7 @@ class App(db.Model): ...@@ -92,19 +94,7 @@ class App(db.Model):
def tenant(self): def tenant(self):
tenant = db.session.query(Tenant).filter(Tenant.id == self.tenant_id).first() tenant = db.session.query(Tenant).filter(Tenant.id == self.tenant_id).first()
return tenant return tenant
@property
def is_agent(self) -> bool:
app_model_config = self.app_model_config
if not app_model_config:
return False
if not app_model_config.agent_mode:
return False
if self.app_model_config.agent_mode_dict.get('enabled', False) \
and self.app_model_config.agent_mode_dict.get('strategy', '') in ['function_call', 'react']:
return True
return False
@property @property
def deleted_tools(self) -> list: def deleted_tools(self) -> list:
# get agent mode tools # get agent mode tools
...@@ -153,11 +143,6 @@ class App(db.Model): ...@@ -153,11 +143,6 @@ class App(db.Model):
return deleted_tools return deleted_tools
class ChatbotAppEngine(Enum):
NORMAL = 'normal'
WORKFLOW = 'workflow'
class AppModelConfig(db.Model): class AppModelConfig(db.Model):
__tablename__ = 'app_model_configs' __tablename__ = 'app_model_configs'
__table_args__ = ( __table_args__ = (
...@@ -167,9 +152,9 @@ class AppModelConfig(db.Model): ...@@ -167,9 +152,9 @@ class AppModelConfig(db.Model):
id = db.Column(UUID, server_default=db.text('uuid_generate_v4()')) id = db.Column(UUID, server_default=db.text('uuid_generate_v4()'))
app_id = db.Column(UUID, nullable=False) app_id = db.Column(UUID, nullable=False)
provider = db.Column(db.String(255), nullable=False) provider = db.Column(db.String(255), nullable=True)
model_id = db.Column(db.String(255), nullable=False) model_id = db.Column(db.String(255), nullable=True)
configs = db.Column(db.JSON, nullable=False) configs = db.Column(db.JSON, nullable=True)
created_at = db.Column(db.DateTime, nullable=False, server_default=db.text('CURRENT_TIMESTAMP(0)')) created_at = db.Column(db.DateTime, nullable=False, server_default=db.text('CURRENT_TIMESTAMP(0)'))
updated_at = db.Column(db.DateTime, nullable=False, server_default=db.text('CURRENT_TIMESTAMP(0)')) updated_at = db.Column(db.DateTime, nullable=False, server_default=db.text('CURRENT_TIMESTAMP(0)'))
opening_statement = db.Column(db.Text) opening_statement = db.Column(db.Text)
...@@ -191,7 +176,6 @@ class AppModelConfig(db.Model): ...@@ -191,7 +176,6 @@ class AppModelConfig(db.Model):
dataset_configs = db.Column(db.Text) dataset_configs = db.Column(db.Text)
external_data_tools = db.Column(db.Text) external_data_tools = db.Column(db.Text)
file_upload = db.Column(db.Text) file_upload = db.Column(db.Text)
chatbot_app_engine = db.Column(db.String(255), nullable=False, server_default=db.text("'normal'::character varying"))
workflow_id = db.Column(UUID) workflow_id = db.Column(UUID)
@property @property
...@@ -301,9 +285,6 @@ class AppModelConfig(db.Model): ...@@ -301,9 +285,6 @@ class AppModelConfig(db.Model):
def to_dict(self) -> dict: def to_dict(self) -> dict:
return { return {
"provider": "",
"model_id": "",
"configs": {},
"opening_statement": self.opening_statement, "opening_statement": self.opening_statement,
"suggested_questions": self.suggested_questions_list, "suggested_questions": self.suggested_questions_list,
"suggested_questions_after_answer": self.suggested_questions_after_answer_dict, "suggested_questions_after_answer": self.suggested_questions_after_answer_dict,
...@@ -327,9 +308,6 @@ class AppModelConfig(db.Model): ...@@ -327,9 +308,6 @@ class AppModelConfig(db.Model):
} }
def from_model_config_dict(self, model_config: dict): def from_model_config_dict(self, model_config: dict):
self.provider = ""
self.model_id = ""
self.configs = {}
self.opening_statement = model_config['opening_statement'] self.opening_statement = model_config['opening_statement']
self.suggested_questions = json.dumps(model_config['suggested_questions']) self.suggested_questions = json.dumps(model_config['suggested_questions'])
self.suggested_questions_after_answer = json.dumps(model_config['suggested_questions_after_answer']) self.suggested_questions_after_answer = json.dumps(model_config['suggested_questions_after_answer'])
...@@ -358,15 +336,13 @@ class AppModelConfig(db.Model): ...@@ -358,15 +336,13 @@ class AppModelConfig(db.Model):
if model_config.get('dataset_configs') else None if model_config.get('dataset_configs') else None
self.file_upload = json.dumps(model_config.get('file_upload')) \ self.file_upload = json.dumps(model_config.get('file_upload')) \
if model_config.get('file_upload') else None if model_config.get('file_upload') else None
self.workflow_id = model_config.get('workflow_id')
return self return self
def copy(self): def copy(self):
new_app_model_config = AppModelConfig( new_app_model_config = AppModelConfig(
id=self.id, id=self.id,
app_id=self.app_id, app_id=self.app_id,
provider="",
model_id="",
configs={},
opening_statement=self.opening_statement, opening_statement=self.opening_statement,
suggested_questions=self.suggested_questions, suggested_questions=self.suggested_questions,
suggested_questions_after_answer=self.suggested_questions_after_answer, suggested_questions_after_answer=self.suggested_questions_after_answer,
...@@ -385,7 +361,8 @@ class AppModelConfig(db.Model): ...@@ -385,7 +361,8 @@ class AppModelConfig(db.Model):
chat_prompt_config=self.chat_prompt_config, chat_prompt_config=self.chat_prompt_config,
completion_prompt_config=self.completion_prompt_config, completion_prompt_config=self.completion_prompt_config,
dataset_configs=self.dataset_configs, dataset_configs=self.dataset_configs,
file_upload=self.file_upload file_upload=self.file_upload,
workflow_id=self.workflow_id
) )
return new_app_model_config return new_app_model_config
...@@ -446,12 +423,6 @@ class InstalledApp(db.Model): ...@@ -446,12 +423,6 @@ class InstalledApp(db.Model):
tenant = db.session.query(Tenant).filter(Tenant.id == self.tenant_id).first() tenant = db.session.query(Tenant).filter(Tenant.id == self.tenant_id).first()
return tenant return tenant
@property
def is_agent(self) -> bool:
app = self.app
if not app:
return False
return app.is_agent
class Conversation(db.Model): class Conversation(db.Model):
__tablename__ = 'conversations' __tablename__ = 'conversations'
......
...@@ -21,7 +21,7 @@ from events.app_event import app_was_created ...@@ -21,7 +21,7 @@ from events.app_event import app_was_created
from extensions.ext_database import db from extensions.ext_database import db
from models.account import Account 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, AppModelConfig, ChatbotAppEngine, Site from models.model import App, AppMode, AppModelConfig, Site
from models.workflow import Workflow, WorkflowType from models.workflow import Workflow, WorkflowType
...@@ -85,8 +85,6 @@ class WorkflowConverter: ...@@ -85,8 +85,6 @@ class WorkflowConverter:
new_app_model_config.chat_prompt_config = '' new_app_model_config.chat_prompt_config = ''
new_app_model_config.completion_prompt_config = '' new_app_model_config.completion_prompt_config = ''
new_app_model_config.dataset_configs = '' new_app_model_config.dataset_configs = ''
new_app_model_config.chatbot_app_engine = ChatbotAppEngine.WORKFLOW.value \
if app_model.mode == AppMode.CHAT.value else ChatbotAppEngine.NORMAL.value
new_app_model_config.workflow_id = workflow.id new_app_model_config.workflow_id = workflow.id
db.session.add(new_app_model_config) db.session.add(new_app_model_config)
......
import json import json
from datetime import datetime from datetime import datetime
from typing import Optional
from extensions.ext_database import db from extensions.ext_database import db
from models.account import Account from models.account import Account
from models.model import App, AppMode, ChatbotAppEngine from models.model import App, AppMode
from models.workflow import Workflow, WorkflowType from models.workflow import Workflow, WorkflowType
from services.workflow.defaults import default_block_configs from services.workflow.defaults import default_block_configs
from services.workflow.workflow_converter import WorkflowConverter from services.workflow.workflow_converter import WorkflowConverter
...@@ -58,6 +59,40 @@ class WorkflowService: ...@@ -58,6 +59,40 @@ class WorkflowService:
# return draft workflow # return draft workflow
return workflow return workflow
def publish_draft_workflow(self, app_model: App,
account: Account,
draft_workflow: Optional[Workflow] = None) -> Workflow:
"""
Publish draft workflow
:param app_model: App instance
:param account: Account instance
:param draft_workflow: Workflow instance
"""
if not draft_workflow:
# fetch draft workflow by app_model
draft_workflow = self.get_draft_workflow(app_model=app_model)
if not draft_workflow:
raise ValueError('No valid workflow found.')
# create new workflow
workflow = Workflow(
tenant_id=app_model.tenant_id,
app_id=app_model.id,
type=draft_workflow.type,
version=str(datetime.utcnow()),
graph=draft_workflow.graph,
created_by=account.id
)
# commit db session changes
db.session.add(workflow)
db.session.commit()
# return new workflow
return workflow
def get_default_block_configs(self) -> dict: def get_default_block_configs(self) -> dict:
""" """
Get default block configs Get default block configs
...@@ -77,11 +112,7 @@ class WorkflowService: ...@@ -77,11 +112,7 @@ class WorkflowService:
# chatbot convert to workflow mode # chatbot convert to workflow mode
workflow_converter = WorkflowConverter() workflow_converter = WorkflowConverter()
if app_model.mode == AppMode.CHAT.value: if app_model.mode not in [AppMode.CHAT.value, AppMode.COMPLETION.value]:
# check if chatbot app is in basic mode
if app_model.app_model_config.chatbot_app_engine != ChatbotAppEngine.NORMAL:
raise ValueError('Chatbot app already in workflow mode')
elif app_model.mode != AppMode.COMPLETION.value:
raise ValueError(f'Current App mode: {app_model.mode} is not supported convert to workflow.') raise ValueError(f'Current App mode: {app_model.mode} is not supported convert to workflow.')
# convert to workflow # convert to workflow
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment