Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add api-based extension & external data tool & moderation backend #1403

Merged
merged 57 commits into from
Nov 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
30eb7c2
add form schemas.
GarfieldDai Oct 24, 2023
382d65c
update.
GarfieldDai Oct 27, 2023
3c36ce7
api_based_extension.
GarfieldDai Oct 27, 2023
b052a84
refactor.
GarfieldDai Oct 30, 2023
dc849bf
update.
GarfieldDai Oct 30, 2023
ce8af8b
update.
GarfieldDai Oct 30, 2023
bfa2a07
update.
GarfieldDai Oct 31, 2023
2819b08
feat: refactor code-based extension
takatost Oct 31, 2023
a21a950
feat: refactor.
takatost Oct 31, 2023
fb2bc44
feat: refactor moderation factory
takatost Oct 31, 2023
f1905e0
feat: sort builtin extensions
takatost Oct 31, 2023
f4497bd
feat: refactor extensions
takatost Nov 1, 2023
05c065a
feat: refactor api based extensions
takatost Nov 1, 2023
d526d86
feat: add api request support
takatost Nov 1, 2023
784d73e
feat: add comments
takatost Nov 1, 2023
abe576a
feat: add is_external_data_tools_valid
takatost Nov 1, 2023
b68b146
fix: circle import error
takatost Nov 1, 2023
0a791ce
feat: remove builtin extension from list
takatost Nov 1, 2023
fc6ab60
add implements.
GarfieldDai Nov 1, 2023
305f49e
feat: add external_data_tool query in generate
takatost Nov 1, 2023
f6866c8
fix: bug
takatost Nov 2, 2023
343c075
feat: optimize multi thread call api
takatost Nov 2, 2023
99dcb17
feat: optimize api response error
takatost Nov 2, 2023
c9adf39
feat: optimize api response error
takatost Nov 2, 2023
93b928c
add moderation api.
GarfieldDai Nov 2, 2023
513eb21
update.
GarfieldDai Nov 2, 2023
0a2cce6
refactor.
GarfieldDai Nov 2, 2023
26c37ad
update.
GarfieldDai Nov 2, 2023
8fdcee4
update.
GarfieldDai Nov 3, 2023
a86fc23
update.
GarfieldDai Nov 3, 2023
98fa9d5
refactor.
GarfieldDai Nov 3, 2023
e47dbca
update.
GarfieldDai Nov 3, 2023
348eebb
update.
GarfieldDai Nov 3, 2023
89b7cb2
feat: optimize APIBasedExtensionRequestor error message
takatost Nov 3, 2023
e1f4442
update.
GarfieldDai Nov 3, 2023
82120da
remove sample code.
GarfieldDai Nov 3, 2023
84af645
remove s.
GarfieldDai Nov 3, 2023
f67c2da
feat: add moderation output logic
takatost Nov 3, 2023
95e2d84
refactor.
GarfieldDai Nov 3, 2023
be3d362
feat: add message replace event
takatost Nov 3, 2023
fdaf63c
feat: fix moderation still stream output
takatost Nov 3, 2023
3b7e889
refactor.
GarfieldDai Nov 3, 2023
ffbf9b5
update.
GarfieldDai Nov 3, 2023
f48fd41
update.
GarfieldDai Nov 3, 2023
80441d5
feat: multi thread output moderation
takatost Nov 3, 2023
5c01a3e
fix: bug
takatost Nov 3, 2023
1be2578
fix bug.
GarfieldDai Nov 4, 2023
6f56b01
add validation.
GarfieldDai Nov 4, 2023
1b735a1
format.
GarfieldDai Nov 4, 2023
e07fac5
format.
GarfieldDai Nov 5, 2023
c88371a
fix: bug
takatost Nov 5, 2023
5918902
fix: bug
takatost Nov 5, 2023
7fb83e8
feat: refactor output moderation
takatost Nov 6, 2023
176a012
feat: add buffer size setting to env
takatost Nov 6, 2023
c5206d6
feat: optimize final output
takatost Nov 6, 2023
5a15f27
bug fixed.
GarfieldDai Nov 6, 2023
040672c
bug fix.
GarfieldDai Nov 6, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .vscode/launch.json → api/.vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"request": "launch",
"module": "flask",
"env": {
"FLASK_APP": "api/app.py",
"FLASK_APP": "app.py",
"FLASK_DEBUG": "1",
"GEVENT_SUPPORT": "True"
},
Expand Down
3 changes: 2 additions & 1 deletion api/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

from core.model_providers.providers import hosted
from extensions import ext_celery, ext_sentry, ext_redis, ext_login, ext_migrate, \
ext_database, ext_storage, ext_mail, ext_stripe
ext_database, ext_storage, ext_mail, ext_stripe, ext_code_based_extension
from extensions.ext_database import db
from extensions.ext_login import login_manager

Expand Down Expand Up @@ -79,6 +79,7 @@ def create_app(test_config=None) -> Flask:
def initialize_extensions(app):
# Since the application instance is now created, pass it to each Flask
# extension instance to bind it to the Flask application instance (app)
ext_code_based_extension.init()
ext_database.init_app(app)
ext_migrate.init(app, db)
ext_redis.init_app(app)
Expand Down
4 changes: 4 additions & 0 deletions api/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
'CLEAN_DAY_SETTING': 30,
'UPLOAD_FILE_SIZE_LIMIT': 15,
'UPLOAD_FILE_BATCH_LIMIT': 5,
'OUTPUT_MODERATION_BUFFER_SIZE': 300
}


Expand Down Expand Up @@ -228,6 +229,9 @@ def __init__(self):
self.UPLOAD_FILE_SIZE_LIMIT = int(get_env('UPLOAD_FILE_SIZE_LIMIT'))
self.UPLOAD_FILE_BATCH_LIMIT = int(get_env('UPLOAD_FILE_BATCH_LIMIT'))

# moderation settings
self.OUTPUT_MODERATION_BUFFER_SIZE = int(get_env('OUTPUT_MODERATION_BUFFER_SIZE'))


class CloudEditionConfig(Config):

Expand Down
2 changes: 1 addition & 1 deletion api/controllers/console/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
api = ExternalApi(bp)

# Import other controllers
from . import setup, version, apikey, admin
from . import extension, setup, version, apikey, admin

# Import app controllers
from .app import advanced_prompt_template, app, site, completion, model_config, statistic, conversation, message, generator, audio
Expand Down
4 changes: 3 additions & 1 deletion api/controllers/console/explore/parameter.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ class AppParameterApi(InstalledAppResource):
'retriever_resource': fields.Raw,
'more_like_this': fields.Raw,
'user_input_form': fields.Raw,
'sensitive_word_avoidance': fields.Raw
}

@marshal_with(parameters_fields)
Expand All @@ -42,7 +43,8 @@ def get(self, installed_app: InstalledApp):
'speech_to_text': app_model_config.speech_to_text_dict,
'retriever_resource': app_model_config.retriever_resource_dict,
'more_like_this': app_model_config.more_like_this_dict,
'user_input_form': app_model_config.user_input_form_list
'user_input_form': app_model_config.user_input_form_list,
'sensitive_word_avoidance': app_model_config.sensitive_word_avoidance_dict
}


Expand Down
114 changes: 114 additions & 0 deletions api/controllers/console/extension.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
from flask_restful import Resource, reqparse, marshal_with
from flask_login import current_user

from controllers.console import api
from controllers.console.setup import setup_required
from controllers.console.wraps import account_initialization_required
from libs.login import login_required
from models.api_based_extension import APIBasedExtension
from fields.api_based_extension_fields import api_based_extension_fields
from services.code_based_extension_service import CodeBasedExtensionService
from services.api_based_extension_service import APIBasedExtensionService


class CodeBasedExtensionAPI(Resource):

@setup_required
@login_required
@account_initialization_required
def get(self):
parser = reqparse.RequestParser()
parser.add_argument('module', type=str, required=True, location='args')
args = parser.parse_args()

return {
'module': args['module'],
'data': CodeBasedExtensionService.get_code_based_extension(args['module'])
}


class APIBasedExtensionAPI(Resource):

@setup_required
@login_required
@account_initialization_required
@marshal_with(api_based_extension_fields)
def get(self):
tenant_id = current_user.current_tenant_id
return APIBasedExtensionService.get_all_by_tenant_id(tenant_id)

@setup_required
@login_required
@account_initialization_required
@marshal_with(api_based_extension_fields)
def post(self):
parser = reqparse.RequestParser()
parser.add_argument('name', type=str, required=True, location='json')
parser.add_argument('api_endpoint', type=str, required=True, location='json')
parser.add_argument('api_key', type=str, required=True, location='json')
args = parser.parse_args()

extension_data = APIBasedExtension(
tenant_id=current_user.current_tenant_id,
name=args['name'],
api_endpoint=args['api_endpoint'],
api_key=args['api_key']
)

return APIBasedExtensionService.save(extension_data)


class APIBasedExtensionDetailAPI(Resource):

@setup_required
@login_required
@account_initialization_required
@marshal_with(api_based_extension_fields)
def get(self, id):
api_based_extension_id = str(id)
tenant_id = current_user.current_tenant_id

return APIBasedExtensionService.get_with_tenant_id(tenant_id, api_based_extension_id)

@setup_required
@login_required
@account_initialization_required
@marshal_with(api_based_extension_fields)
def post(self, id):
api_based_extension_id = str(id)
tenant_id = current_user.current_tenant_id

extension_data_from_db = APIBasedExtensionService.get_with_tenant_id(tenant_id, api_based_extension_id)

parser = reqparse.RequestParser()
parser.add_argument('name', type=str, required=True, location='json')
parser.add_argument('api_endpoint', type=str, required=True, location='json')
parser.add_argument('api_key', type=str, required=True, location='json')
args = parser.parse_args()

extension_data_from_db.name = args['name']
extension_data_from_db.api_endpoint = args['api_endpoint']

if args['api_key'] != '[__HIDDEN__]':
extension_data_from_db.api_key = args['api_key']

return APIBasedExtensionService.save(extension_data_from_db)

@setup_required
@login_required
@account_initialization_required
def delete(self, id):
api_based_extension_id = str(id)
tenant_id = current_user.current_tenant_id

extension_data_from_db = APIBasedExtensionService.get_with_tenant_id(tenant_id, api_based_extension_id)

APIBasedExtensionService.delete(extension_data_from_db)

return {'result': 'success'}


api.add_resource(CodeBasedExtensionAPI, '/code-based-extension')

api.add_resource(APIBasedExtensionAPI, '/api-based-extension')
api.add_resource(APIBasedExtensionDetailAPI, '/api-based-extension/<uuid:id>')
4 changes: 3 additions & 1 deletion api/controllers/service_api/app/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ class AppParameterApi(AppApiResource):
'retriever_resource': fields.Raw,
'more_like_this': fields.Raw,
'user_input_form': fields.Raw,
'sensitive_word_avoidance': fields.Raw
}

@marshal_with(parameters_fields)
Expand All @@ -42,7 +43,8 @@ def get(self, app_model: App, end_user):
'speech_to_text': app_model_config.speech_to_text_dict,
'retriever_resource': app_model_config.retriever_resource_dict,
'more_like_this': app_model_config.more_like_this_dict,
'user_input_form': app_model_config.user_input_form_list
'user_input_form': app_model_config.user_input_form_list,
'sensitive_word_avoidance': app_model_config.sensitive_word_avoidance_dict
}


Expand Down
1 change: 0 additions & 1 deletion api/controllers/service_api/app/completion.py
Original file line number Diff line number Diff line change
Expand Up @@ -183,4 +183,3 @@ def generate() -> Generator:
api.add_resource(CompletionStopApi, '/completion-messages/<string:task_id>/stop')
api.add_resource(ChatApi, '/chat-messages')
api.add_resource(ChatStopApi, '/chat-messages/<string:task_id>/stop')

4 changes: 3 additions & 1 deletion api/controllers/web/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ class AppParameterApi(WebApiResource):
'retriever_resource': fields.Raw,
'more_like_this': fields.Raw,
'user_input_form': fields.Raw,
'sensitive_word_avoidance': fields.Raw
}

@marshal_with(parameters_fields)
Expand All @@ -41,7 +42,8 @@ def get(self, app_model: App, end_user):
'speech_to_text': app_model_config.speech_to_text_dict,
'retriever_resource': app_model_config.retriever_resource_dict,
'more_like_this': app_model_config.more_like_this_dict,
'user_input_form': app_model_config.user_input_form_list
'user_input_form': app_model_config.user_input_form_list,
'sensitive_word_avoidance': app_model_config.sensitive_word_avoidance_dict
}


Expand Down
2 changes: 1 addition & 1 deletion api/controllers/web/completion.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ def post(self, app_model, end_user, task_id):
return {'result': 'success'}, 200


def compact_response(response: Union[dict | Generator]) -> Response:
def compact_response(response: Union[dict, Generator]) -> Response:
if isinstance(response, dict):
return Response(response=json.dumps(response), status=200, mimetype='application/json')
else:
Expand Down
1 change: 1 addition & 0 deletions api/core/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import core.moderation.base
Loading
Loading