1818from core .ops .ops_trace_manager import OpsTraceManager
1919from core .workflow .enums import NodeType
2020from extensions .ext_database import db
21- from fields .app_fields import app_detail_fields , app_detail_fields_with_site , app_pagination_fields
21+ from fields .app_fields import (
22+ deleted_tool_fields ,
23+ model_config_fields ,
24+ model_config_partial_fields ,
25+ site_fields ,
26+ tag_fields ,
27+ )
28+ from fields .workflow_fields import workflow_partial_fields as _workflow_partial_fields_dict
29+ from libs .helper import AppIconUrlField , TimestampField
2230from libs .login import current_account_with_tenant , login_required
2331from libs .validators import validate_description_length
2432from models import App , Workflow
2937
3038ALLOW_CREATE_APP_MODES = ["chat" , "agent-chat" , "advanced-chat" , "workflow" , "completion" ]
3139
40+ # Register models for flask_restx to avoid dict type issues in Swagger
41+ # Register base models first
42+ tag_model = console_ns .model ("Tag" , tag_fields )
43+
44+ workflow_partial_model = console_ns .model ("WorkflowPartial" , _workflow_partial_fields_dict )
45+
46+ model_config_model = console_ns .model ("ModelConfig" , model_config_fields )
47+
48+ model_config_partial_model = console_ns .model ("ModelConfigPartial" , model_config_partial_fields )
49+
50+ deleted_tool_model = console_ns .model ("DeletedTool" , deleted_tool_fields )
51+
52+ site_model = console_ns .model ("Site" , site_fields )
53+
54+ app_partial_model = console_ns .model (
55+ "AppPartial" ,
56+ {
57+ "id" : fields .String ,
58+ "name" : fields .String ,
59+ "max_active_requests" : fields .Raw (),
60+ "description" : fields .String (attribute = "desc_or_prompt" ),
61+ "mode" : fields .String (attribute = "mode_compatible_with_agent" ),
62+ "icon_type" : fields .String ,
63+ "icon" : fields .String ,
64+ "icon_background" : fields .String ,
65+ "icon_url" : AppIconUrlField ,
66+ "model_config" : fields .Nested (model_config_partial_model , attribute = "app_model_config" , allow_null = True ),
67+ "workflow" : fields .Nested (workflow_partial_model , allow_null = True ),
68+ "use_icon_as_answer_icon" : fields .Boolean ,
69+ "created_by" : fields .String ,
70+ "created_at" : TimestampField ,
71+ "updated_by" : fields .String ,
72+ "updated_at" : TimestampField ,
73+ "tags" : fields .List (fields .Nested (tag_model )),
74+ "access_mode" : fields .String ,
75+ "create_user_name" : fields .String ,
76+ "author_name" : fields .String ,
77+ "has_draft_trigger" : fields .Boolean ,
78+ },
79+ )
80+
81+ app_detail_model = console_ns .model (
82+ "AppDetail" ,
83+ {
84+ "id" : fields .String ,
85+ "name" : fields .String ,
86+ "description" : fields .String ,
87+ "mode" : fields .String (attribute = "mode_compatible_with_agent" ),
88+ "icon" : fields .String ,
89+ "icon_background" : fields .String ,
90+ "enable_site" : fields .Boolean ,
91+ "enable_api" : fields .Boolean ,
92+ "model_config" : fields .Nested (model_config_model , attribute = "app_model_config" , allow_null = True ),
93+ "workflow" : fields .Nested (workflow_partial_model , allow_null = True ),
94+ "tracing" : fields .Raw ,
95+ "use_icon_as_answer_icon" : fields .Boolean ,
96+ "created_by" : fields .String ,
97+ "created_at" : TimestampField ,
98+ "updated_by" : fields .String ,
99+ "updated_at" : TimestampField ,
100+ "access_mode" : fields .String ,
101+ "tags" : fields .List (fields .Nested (tag_model )),
102+ },
103+ )
104+
105+ app_detail_with_site_model = console_ns .model (
106+ "AppDetailWithSite" ,
107+ {
108+ "id" : fields .String ,
109+ "name" : fields .String ,
110+ "description" : fields .String ,
111+ "mode" : fields .String (attribute = "mode_compatible_with_agent" ),
112+ "icon_type" : fields .String ,
113+ "icon" : fields .String ,
114+ "icon_background" : fields .String ,
115+ "icon_url" : AppIconUrlField ,
116+ "enable_site" : fields .Boolean ,
117+ "enable_api" : fields .Boolean ,
118+ "model_config" : fields .Nested (model_config_model , attribute = "app_model_config" , allow_null = True ),
119+ "workflow" : fields .Nested (workflow_partial_model , allow_null = True ),
120+ "api_base_url" : fields .String ,
121+ "use_icon_as_answer_icon" : fields .Boolean ,
122+ "max_active_requests" : fields .Integer ,
123+ "created_by" : fields .String ,
124+ "created_at" : TimestampField ,
125+ "updated_by" : fields .String ,
126+ "updated_at" : TimestampField ,
127+ "deleted_tools" : fields .List (fields .Nested (deleted_tool_model )),
128+ "access_mode" : fields .String ,
129+ "tags" : fields .List (fields .Nested (tag_model )),
130+ "site" : fields .Nested (site_model ),
131+ },
132+ )
133+
134+ app_pagination_model = console_ns .model (
135+ "AppPagination" ,
136+ {
137+ "page" : fields .Integer ,
138+ "limit" : fields .Integer (attribute = "per_page" ),
139+ "total" : fields .Integer ,
140+ "has_more" : fields .Boolean (attribute = "has_next" ),
141+ "data" : fields .List (fields .Nested (app_partial_model ), attribute = "items" ),
142+ },
143+ )
144+
32145
33146@console_ns .route ("/apps" )
34147class AppListApi (Resource ):
@@ -50,7 +163,7 @@ class AppListApi(Resource):
50163 .add_argument ("tag_ids" , type = str , location = "args" , help = "Comma-separated tag IDs" )
51164 .add_argument ("is_created_by_me" , type = bool , location = "args" , help = "Filter by creator" )
52165 )
53- @console_ns .response (200 , "Success" , app_pagination_fields )
166+ @console_ns .response (200 , "Success" , app_pagination_model )
54167 @setup_required
55168 @login_required
56169 @account_initialization_required
@@ -137,7 +250,7 @@ def uuid_list(value):
137250 for app in app_pagination .items :
138251 app .has_draft_trigger = str (app .id ) in draft_trigger_app_ids
139252
140- return marshal (app_pagination , app_pagination_fields ), 200
253+ return marshal (app_pagination , app_pagination_model ), 200
141254
142255 @console_ns .doc ("create_app" )
143256 @console_ns .doc (description = "Create a new application" )
@@ -154,13 +267,13 @@ def uuid_list(value):
154267 },
155268 )
156269 )
157- @console_ns .response (201 , "App created successfully" , app_detail_fields )
270+ @console_ns .response (201 , "App created successfully" , app_detail_model )
158271 @console_ns .response (403 , "Insufficient permissions" )
159272 @console_ns .response (400 , "Invalid request parameters" )
160273 @setup_required
161274 @login_required
162275 @account_initialization_required
163- @marshal_with (app_detail_fields )
276+ @marshal_with (app_detail_model )
164277 @cloud_edition_billing_resource_check ("apps" )
165278 @edit_permission_required
166279 def post (self ):
@@ -191,13 +304,13 @@ class AppApi(Resource):
191304 @console_ns .doc ("get_app_detail" )
192305 @console_ns .doc (description = "Get application details" )
193306 @console_ns .doc (params = {"app_id" : "Application ID" })
194- @console_ns .response (200 , "Success" , app_detail_fields_with_site )
307+ @console_ns .response (200 , "Success" , app_detail_with_site_model )
195308 @setup_required
196309 @login_required
197310 @account_initialization_required
198311 @enterprise_license_required
199312 @get_app_model
200- @marshal_with (app_detail_fields_with_site )
313+ @marshal_with (app_detail_with_site_model )
201314 def get (self , app_model ):
202315 """Get app detail"""
203316 app_service = AppService ()
@@ -227,15 +340,15 @@ def get(self, app_model):
227340 },
228341 )
229342 )
230- @console_ns .response (200 , "App updated successfully" , app_detail_fields_with_site )
343+ @console_ns .response (200 , "App updated successfully" , app_detail_with_site_model )
231344 @console_ns .response (403 , "Insufficient permissions" )
232345 @console_ns .response (400 , "Invalid request parameters" )
233346 @setup_required
234347 @login_required
235348 @account_initialization_required
236349 @get_app_model
237350 @edit_permission_required
238- @marshal_with (app_detail_fields_with_site )
351+ @marshal_with (app_detail_with_site_model )
239352 def put (self , app_model ):
240353 """Update app"""
241354 parser = (
@@ -300,14 +413,14 @@ class AppCopyApi(Resource):
300413 },
301414 )
302415 )
303- @console_ns .response (201 , "App copied successfully" , app_detail_fields_with_site )
416+ @console_ns .response (201 , "App copied successfully" , app_detail_with_site_model )
304417 @console_ns .response (403 , "Insufficient permissions" )
305418 @setup_required
306419 @login_required
307420 @account_initialization_required
308421 @get_app_model
309422 @edit_permission_required
310- @marshal_with (app_detail_fields_with_site )
423+ @marshal_with (app_detail_with_site_model )
311424 def post (self , app_model ):
312425 """Copy app"""
313426 # The role of the current user in the ta table must be admin, owner, or editor
@@ -396,7 +509,7 @@ class AppNameApi(Resource):
396509 @login_required
397510 @account_initialization_required
398511 @get_app_model
399- @marshal_with (app_detail_fields )
512+ @marshal_with (app_detail_model )
400513 @edit_permission_required
401514 def post (self , app_model ):
402515 args = parser .parse_args ()
@@ -428,7 +541,7 @@ class AppIconApi(Resource):
428541 @login_required
429542 @account_initialization_required
430543 @get_app_model
431- @marshal_with (app_detail_fields )
544+ @marshal_with (app_detail_model )
432545 @edit_permission_required
433546 def post (self , app_model ):
434547 parser = (
@@ -454,13 +567,13 @@ class AppSiteStatus(Resource):
454567 "AppSiteStatusRequest" , {"enable_site" : fields .Boolean (required = True , description = "Enable or disable site" )}
455568 )
456569 )
457- @console_ns .response (200 , "Site status updated successfully" , app_detail_fields )
570+ @console_ns .response (200 , "Site status updated successfully" , app_detail_model )
458571 @console_ns .response (403 , "Insufficient permissions" )
459572 @setup_required
460573 @login_required
461574 @account_initialization_required
462575 @get_app_model
463- @marshal_with (app_detail_fields )
576+ @marshal_with (app_detail_model )
464577 @edit_permission_required
465578 def post (self , app_model ):
466579 parser = reqparse .RequestParser ().add_argument ("enable_site" , type = bool , required = True , location = "json" )
@@ -482,14 +595,14 @@ class AppApiStatus(Resource):
482595 "AppApiStatusRequest" , {"enable_api" : fields .Boolean (required = True , description = "Enable or disable API" )}
483596 )
484597 )
485- @console_ns .response (200 , "API status updated successfully" , app_detail_fields )
598+ @console_ns .response (200 , "API status updated successfully" , app_detail_model )
486599 @console_ns .response (403 , "Insufficient permissions" )
487600 @setup_required
488601 @login_required
489602 @is_admin_or_owner_required
490603 @account_initialization_required
491604 @get_app_model
492- @marshal_with (app_detail_fields )
605+ @marshal_with (app_detail_model )
493606 def post (self , app_model ):
494607 parser = reqparse .RequestParser ().add_argument ("enable_api" , type = bool , required = True , location = "json" )
495608 args = parser .parse_args ()
0 commit comments