@josephyan/qingflow-cli 0.2.0-beta.81 → 0.2.0-beta.83
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/package.json +1 -1
- package/pyproject.toml +1 -1
- package/src/qingflow_mcp/__init__.py +1 -1
- package/src/qingflow_mcp/builder_facade/service.py +714 -20
- package/src/qingflow_mcp/cli/commands/builder.py +36 -95
- package/src/qingflow_mcp/public_surface.py +1 -5
- package/src/qingflow_mcp/response_trim.py +2 -4
- package/src/qingflow_mcp/server_app_builder.py +41 -61
- package/src/qingflow_mcp/tools/ai_builder_tools.py +219 -195
- package/src/qingflow_mcp/tools/package_tools.py +49 -0
|
@@ -71,48 +71,36 @@ class AiBuilderTools(ToolBase):
|
|
|
71
71
|
)
|
|
72
72
|
|
|
73
73
|
def register(self, mcp) -> None:
|
|
74
|
-
@mcp.tool()
|
|
75
|
-
def package_list(profile: str = DEFAULT_PROFILE, trial_status: str = "all") -> JSONObject:
|
|
76
|
-
return self.package_list(profile=profile, trial_status=trial_status)
|
|
77
|
-
|
|
78
|
-
@mcp.tool()
|
|
79
|
-
def package_resolve(profile: str = DEFAULT_PROFILE, package_name: str = "") -> JSONObject:
|
|
80
|
-
return self.package_resolve(profile=profile, package_name=package_name)
|
|
81
|
-
|
|
82
74
|
@mcp.tool()
|
|
83
75
|
def builder_tool_contract(tool_name: str = "") -> JSONObject:
|
|
84
76
|
return self.builder_tool_contract(tool_name=tool_name)
|
|
85
77
|
|
|
86
78
|
@mcp.tool()
|
|
87
|
-
def
|
|
88
|
-
profile
|
|
89
|
-
package_name: str = "",
|
|
90
|
-
icon: str | None = None,
|
|
91
|
-
color: str | None = None,
|
|
92
|
-
visibility: JSONObject | None = None,
|
|
93
|
-
) -> JSONObject:
|
|
94
|
-
return self.package_create(profile=profile, package_name=package_name, icon=icon, color=color, visibility=visibility)
|
|
79
|
+
def package_get(profile: str = DEFAULT_PROFILE, package_id: int = 0) -> JSONObject:
|
|
80
|
+
return self.package_get(profile=profile, package_id=package_id)
|
|
95
81
|
|
|
96
82
|
@mcp.tool()
|
|
97
|
-
def
|
|
98
|
-
return self.package_get(profile=profile, tag_id=tag_id)
|
|
99
|
-
|
|
100
|
-
@mcp.tool()
|
|
101
|
-
def package_update(
|
|
83
|
+
def package_apply(
|
|
102
84
|
profile: str = DEFAULT_PROFILE,
|
|
103
|
-
|
|
85
|
+
package_id: int | None = None,
|
|
104
86
|
package_name: str | None = None,
|
|
87
|
+
create_if_missing: bool = False,
|
|
105
88
|
icon: str | None = None,
|
|
106
89
|
color: str | None = None,
|
|
107
90
|
visibility: JSONObject | None = None,
|
|
91
|
+
items: list[dict] | None = None,
|
|
92
|
+
allow_detach: bool = False,
|
|
108
93
|
) -> JSONObject:
|
|
109
|
-
return self.
|
|
94
|
+
return self.package_apply(
|
|
110
95
|
profile=profile,
|
|
111
|
-
|
|
96
|
+
package_id=package_id,
|
|
112
97
|
package_name=package_name,
|
|
98
|
+
create_if_missing=create_if_missing,
|
|
113
99
|
icon=icon,
|
|
114
100
|
color=color,
|
|
115
101
|
visibility=visibility,
|
|
102
|
+
items=items or None,
|
|
103
|
+
allow_detach=allow_detach,
|
|
116
104
|
)
|
|
117
105
|
|
|
118
106
|
@mcp.tool()
|
|
@@ -172,14 +160,6 @@ class AiBuilderTools(ToolBase):
|
|
|
172
160
|
role_icon=role_icon,
|
|
173
161
|
)
|
|
174
162
|
|
|
175
|
-
@mcp.tool()
|
|
176
|
-
def package_attach_app(
|
|
177
|
-
profile: str = DEFAULT_PROFILE,
|
|
178
|
-
tag_id: int = 0,
|
|
179
|
-
app_key: str = "",
|
|
180
|
-
) -> JSONObject:
|
|
181
|
-
return self.package_attach_app(profile=profile, tag_id=tag_id, app_key=app_key)
|
|
182
|
-
|
|
183
163
|
@mcp.tool()
|
|
184
164
|
def app_release_edit_lock_if_mine(
|
|
185
165
|
profile: str = DEFAULT_PROFILE,
|
|
@@ -199,24 +179,24 @@ class AiBuilderTools(ToolBase):
|
|
|
199
179
|
profile: str = DEFAULT_PROFILE,
|
|
200
180
|
app_key: str = "",
|
|
201
181
|
app_name: str = "",
|
|
202
|
-
|
|
182
|
+
package_id: int | None = None,
|
|
203
183
|
) -> JSONObject:
|
|
204
184
|
has_app_key = bool((app_key or "").strip())
|
|
205
185
|
has_app_name = bool((app_name or "").strip())
|
|
206
|
-
|
|
207
|
-
if has_app_key and (has_app_name or
|
|
186
|
+
has_package_id = package_id is not None
|
|
187
|
+
if has_app_key and (has_app_name or has_package_id):
|
|
208
188
|
return _config_failure(
|
|
209
189
|
tool_name="app_resolve",
|
|
210
190
|
message="app_resolve accepts exactly one selector mode.",
|
|
211
|
-
fix_hint="Use only `app_key`, or use `app_name` together with `
|
|
191
|
+
fix_hint="Use only `app_key`, or use `app_name` together with `package_id`.",
|
|
212
192
|
)
|
|
213
|
-
if not has_app_key and not (has_app_name and
|
|
193
|
+
if not has_app_key and not (has_app_name and has_package_id):
|
|
214
194
|
return _config_failure(
|
|
215
195
|
tool_name="app_resolve",
|
|
216
|
-
message="app_resolve requires either app_key, or app_name together with
|
|
217
|
-
fix_hint="For an existing known app, pass `app_key`. For package-scoped lookup, pass both `app_name` and `
|
|
196
|
+
message="app_resolve requires either app_key, or app_name together with package_id.",
|
|
197
|
+
fix_hint="For an existing known app, pass `app_key`. For package-scoped lookup, pass both `app_name` and `package_id`.",
|
|
218
198
|
)
|
|
219
|
-
return self.app_resolve(profile=profile, app_key=app_key, app_name=app_name,
|
|
199
|
+
return self.app_resolve(profile=profile, app_key=app_key, app_name=app_name, package_id=package_id)
|
|
220
200
|
|
|
221
201
|
@mcp.tool()
|
|
222
202
|
def app_custom_button_list(profile: str = DEFAULT_PROFILE, app_key: str = "") -> JSONObject:
|
|
@@ -307,7 +287,7 @@ class AiBuilderTools(ToolBase):
|
|
|
307
287
|
def app_schema_apply(
|
|
308
288
|
profile: str = DEFAULT_PROFILE,
|
|
309
289
|
app_key: str = "",
|
|
310
|
-
|
|
290
|
+
package_id: int | None = None,
|
|
311
291
|
app_name: str = "",
|
|
312
292
|
app_title: str = "",
|
|
313
293
|
icon: str = "",
|
|
@@ -322,24 +302,24 @@ class AiBuilderTools(ToolBase):
|
|
|
322
302
|
has_app_key = bool((app_key or "").strip())
|
|
323
303
|
has_app_name = bool((app_name or "").strip())
|
|
324
304
|
has_app_title = bool((app_title or "").strip())
|
|
325
|
-
|
|
305
|
+
has_package_id = package_id is not None
|
|
326
306
|
if has_app_key:
|
|
327
|
-
if create_if_missing or
|
|
307
|
+
if create_if_missing or has_package_id:
|
|
328
308
|
return _config_failure(
|
|
329
309
|
tool_name="app_schema_apply",
|
|
330
310
|
message="app_schema_apply edit mode accepts app_key and optional app_name rename only.",
|
|
331
|
-
fix_hint="For existing apps, use `app_key` and optionally `app_name`. For create mode, use `
|
|
311
|
+
fix_hint="For existing apps, use `app_key` and optionally `app_name`. For create mode, use `package_id + app_name + create_if_missing=true`.",
|
|
332
312
|
)
|
|
333
|
-
elif not (create_if_missing and
|
|
313
|
+
elif not (create_if_missing and has_package_id and (has_app_name or has_app_title)):
|
|
334
314
|
return _config_failure(
|
|
335
315
|
tool_name="app_schema_apply",
|
|
336
|
-
message="app_schema_apply create mode requires
|
|
337
|
-
fix_hint="Use `app_key` for existing apps, or pass `
|
|
316
|
+
message="app_schema_apply create mode requires package_id, app_name, and create_if_missing=true.",
|
|
317
|
+
fix_hint="Use `app_key` for existing apps, or pass `package_id + app_name + create_if_missing=true` to create a new app.",
|
|
338
318
|
)
|
|
339
319
|
return self.app_schema_apply(
|
|
340
320
|
profile=profile,
|
|
341
321
|
app_key=app_key,
|
|
342
|
-
|
|
322
|
+
package_id=package_id,
|
|
343
323
|
app_name=app_name,
|
|
344
324
|
app_title=app_title,
|
|
345
325
|
icon=icon,
|
|
@@ -417,7 +397,7 @@ class AiBuilderTools(ToolBase):
|
|
|
417
397
|
profile: str = DEFAULT_PROFILE,
|
|
418
398
|
dash_key: str = "",
|
|
419
399
|
dash_name: str = "",
|
|
420
|
-
|
|
400
|
+
package_id: int | None = None,
|
|
421
401
|
publish: bool = True,
|
|
422
402
|
sections: list[JSONObject] | None = None,
|
|
423
403
|
visibility: JSONObject | None = None,
|
|
@@ -430,24 +410,24 @@ class AiBuilderTools(ToolBase):
|
|
|
430
410
|
) -> JSONObject:
|
|
431
411
|
has_dash_key = bool((dash_key or "").strip())
|
|
432
412
|
has_dash_name = bool((dash_name or "").strip())
|
|
433
|
-
|
|
434
|
-
if has_dash_key and
|
|
413
|
+
has_package_id = package_id is not None
|
|
414
|
+
if has_dash_key and has_package_id:
|
|
435
415
|
return _config_failure(
|
|
436
416
|
tool_name="portal_apply",
|
|
437
417
|
message="portal_apply accepts exactly one selector mode.",
|
|
438
|
-
fix_hint="Use `dash_key` to update an existing portal, or use `
|
|
418
|
+
fix_hint="Use `dash_key` to update an existing portal, or use `package_id + dash_name` to create a new portal.",
|
|
439
419
|
)
|
|
440
|
-
if not has_dash_key and not (
|
|
420
|
+
if not has_dash_key and not (has_package_id and has_dash_name):
|
|
441
421
|
return _config_failure(
|
|
442
422
|
tool_name="portal_apply",
|
|
443
|
-
message="portal_apply requires either dash_key, or
|
|
444
|
-
fix_hint="Use `dash_key` for an existing portal. For create mode, pass `
|
|
423
|
+
message="portal_apply requires either dash_key, or package_id together with dash_name.",
|
|
424
|
+
fix_hint="Use `dash_key` for an existing portal. For create mode, pass `package_id + dash_name`.",
|
|
445
425
|
)
|
|
446
426
|
return self.portal_apply(
|
|
447
427
|
profile=profile,
|
|
448
428
|
dash_key=dash_key,
|
|
449
429
|
dash_name=dash_name,
|
|
450
|
-
|
|
430
|
+
package_id=package_id,
|
|
451
431
|
publish=publish,
|
|
452
432
|
sections=sections or [],
|
|
453
433
|
visibility=visibility,
|
|
@@ -463,12 +443,12 @@ class AiBuilderTools(ToolBase):
|
|
|
463
443
|
def app_publish_verify(
|
|
464
444
|
profile: str = DEFAULT_PROFILE,
|
|
465
445
|
app_key: str = "",
|
|
466
|
-
|
|
446
|
+
expected_package_id: int | None = None,
|
|
467
447
|
) -> JSONObject:
|
|
468
448
|
return self.app_publish_verify(
|
|
469
449
|
profile=profile,
|
|
470
450
|
app_key=app_key,
|
|
471
|
-
|
|
451
|
+
expected_package_id=expected_package_id,
|
|
472
452
|
)
|
|
473
453
|
|
|
474
454
|
def package_list(self, *, profile: str, trial_status: str = "all") -> JSONObject:
|
|
@@ -494,10 +474,10 @@ class AiBuilderTools(ToolBase):
|
|
|
494
474
|
public_tool_names = public_builder_contract_tool_names()
|
|
495
475
|
if requested in _PRIVATE_BUILDER_TOOL_CONTRACTS:
|
|
496
476
|
lookup_name = ""
|
|
497
|
-
elif requested in _BUILDER_TOOL_CONTRACTS:
|
|
498
|
-
lookup_name = requested
|
|
499
477
|
else:
|
|
500
478
|
lookup_name = _BUILDER_TOOL_CONTRACT_ALIASES.get(requested, requested)
|
|
479
|
+
if lookup_name not in public_tool_names:
|
|
480
|
+
lookup_name = ""
|
|
501
481
|
contract = _BUILDER_TOOL_CONTRACTS.get(lookup_name)
|
|
502
482
|
if contract is None:
|
|
503
483
|
return {
|
|
@@ -582,14 +562,60 @@ class AiBuilderTools(ToolBase):
|
|
|
582
562
|
},
|
|
583
563
|
)
|
|
584
564
|
|
|
585
|
-
def package_get(self, *, profile: str,
|
|
586
|
-
normalized_args = {"
|
|
587
|
-
return _safe_tool_call(
|
|
588
|
-
lambda: self._facade.package_get(profile=profile,
|
|
565
|
+
def package_get(self, *, profile: str, package_id: int | None = None) -> JSONObject:
|
|
566
|
+
normalized_args = {"package_id": package_id}
|
|
567
|
+
return _publicize_package_fields(_safe_tool_call(
|
|
568
|
+
lambda: self._facade.package_get(profile=profile, package_id=package_id),
|
|
589
569
|
error_code="PACKAGE_GET_FAILED",
|
|
590
570
|
normalized_args=normalized_args,
|
|
591
|
-
suggested_next_call={"tool_name": "package_get", "arguments": {"profile": profile, "
|
|
592
|
-
)
|
|
571
|
+
suggested_next_call={"tool_name": "package_get", "arguments": {"profile": profile, "package_id": package_id}},
|
|
572
|
+
))
|
|
573
|
+
|
|
574
|
+
def package_apply(
|
|
575
|
+
self,
|
|
576
|
+
*,
|
|
577
|
+
profile: str,
|
|
578
|
+
package_id: int | None = None,
|
|
579
|
+
package_name: str | None = None,
|
|
580
|
+
create_if_missing: bool = False,
|
|
581
|
+
icon: str | None = None,
|
|
582
|
+
color: str | None = None,
|
|
583
|
+
visibility: JSONObject | None = None,
|
|
584
|
+
items: list[dict] | None = None,
|
|
585
|
+
allow_detach: bool = False,
|
|
586
|
+
) -> JSONObject:
|
|
587
|
+
visibility_patch = None
|
|
588
|
+
if visibility is not None:
|
|
589
|
+
try:
|
|
590
|
+
visibility_patch = VisibilityPatch.model_validate(visibility)
|
|
591
|
+
except ValidationError as exc:
|
|
592
|
+
return _visibility_validation_failure(str(exc), tool_name="package_apply", exc=exc)
|
|
593
|
+
normalized_args = {
|
|
594
|
+
"package_id": package_id,
|
|
595
|
+
**({"package_name": package_name} if str(package_name or "").strip() else {}),
|
|
596
|
+
"create_if_missing": bool(create_if_missing),
|
|
597
|
+
**({"icon": icon} if icon else {}),
|
|
598
|
+
**({"color": color} if color else {}),
|
|
599
|
+
**({"visibility": visibility_patch.model_dump(mode="json")} if visibility_patch is not None else {}),
|
|
600
|
+
**({"items": deepcopy(items)} if items is not None else {}),
|
|
601
|
+
"allow_detach": bool(allow_detach),
|
|
602
|
+
}
|
|
603
|
+
return _publicize_package_fields(_safe_tool_call(
|
|
604
|
+
lambda: self._facade.package_apply(
|
|
605
|
+
profile=profile,
|
|
606
|
+
package_id=package_id,
|
|
607
|
+
package_name=package_name,
|
|
608
|
+
create_if_missing=create_if_missing,
|
|
609
|
+
icon=icon,
|
|
610
|
+
color=color,
|
|
611
|
+
visibility=visibility_patch,
|
|
612
|
+
items=items,
|
|
613
|
+
allow_detach=allow_detach,
|
|
614
|
+
),
|
|
615
|
+
error_code="PACKAGE_APPLY_FAILED",
|
|
616
|
+
normalized_args=normalized_args,
|
|
617
|
+
suggested_next_call={"tool_name": "package_apply", "arguments": {"profile": profile, **normalized_args}},
|
|
618
|
+
))
|
|
593
619
|
|
|
594
620
|
def package_update(
|
|
595
621
|
self,
|
|
@@ -765,14 +791,21 @@ class AiBuilderTools(ToolBase):
|
|
|
765
791
|
suggested_next_call={"tool_name": "app_release_edit_lock_if_mine", "arguments": {"profile": profile, **normalized_args}},
|
|
766
792
|
)
|
|
767
793
|
|
|
768
|
-
def app_resolve(
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
794
|
+
def app_resolve(
|
|
795
|
+
self,
|
|
796
|
+
*,
|
|
797
|
+
profile: str,
|
|
798
|
+
app_key: str = "",
|
|
799
|
+
app_name: str = "",
|
|
800
|
+
package_id: int | None = None,
|
|
801
|
+
) -> JSONObject:
|
|
802
|
+
normalized_args = {"app_key": app_key, "app_name": app_name, "package_id": package_id}
|
|
803
|
+
return _publicize_package_fields(_safe_tool_call(
|
|
804
|
+
lambda: self._facade.app_resolve(profile=profile, app_key=app_key, app_name=app_name, package_tag_id=package_id),
|
|
772
805
|
error_code="APP_RESOLVE_FAILED",
|
|
773
806
|
normalized_args=normalized_args,
|
|
774
807
|
suggested_next_call={"tool_name": "app_resolve", "arguments": {"profile": profile, **normalized_args}},
|
|
775
|
-
)
|
|
808
|
+
))
|
|
776
809
|
|
|
777
810
|
def app_custom_button_list(self, *, profile: str, app_key: str) -> JSONObject:
|
|
778
811
|
normalized_args = {"app_key": app_key}
|
|
@@ -868,21 +901,21 @@ class AiBuilderTools(ToolBase):
|
|
|
868
901
|
|
|
869
902
|
def app_read_summary(self, *, profile: str, app_key: str) -> JSONObject:
|
|
870
903
|
normalized_args = {"app_key": app_key}
|
|
871
|
-
return _safe_tool_call(
|
|
904
|
+
return _publicize_package_fields(_safe_tool_call(
|
|
872
905
|
lambda: self._facade.app_read_summary(profile=profile, app_key=app_key),
|
|
873
906
|
error_code="APP_READ_FAILED",
|
|
874
907
|
normalized_args=normalized_args,
|
|
875
908
|
suggested_next_call={"tool_name": "app_get", "arguments": {"profile": profile, "app_key": app_key}},
|
|
876
|
-
)
|
|
909
|
+
))
|
|
877
910
|
|
|
878
911
|
def app_get(self, *, profile: str, app_key: str) -> JSONObject:
|
|
879
912
|
normalized_args = {"app_key": app_key}
|
|
880
|
-
return _safe_tool_call(
|
|
913
|
+
return _publicize_package_fields(_safe_tool_call(
|
|
881
914
|
lambda: self._facade.app_get(profile=profile, app_key=app_key),
|
|
882
915
|
error_code="APP_GET_FAILED",
|
|
883
916
|
normalized_args=normalized_args,
|
|
884
917
|
suggested_next_call={"tool_name": "app_get", "arguments": {"profile": profile, "app_key": app_key}},
|
|
885
|
-
)
|
|
918
|
+
))
|
|
886
919
|
|
|
887
920
|
def app_read_fields(self, *, profile: str, app_key: str) -> JSONObject:
|
|
888
921
|
normalized_args = {"app_key": app_key}
|
|
@@ -991,30 +1024,30 @@ class AiBuilderTools(ToolBase):
|
|
|
991
1024
|
)
|
|
992
1025
|
|
|
993
1026
|
def portal_list(self, *, profile: str) -> JSONObject:
|
|
994
|
-
return _safe_tool_call(
|
|
1027
|
+
return _publicize_package_fields(_safe_tool_call(
|
|
995
1028
|
lambda: self._facade.portal_list(profile=profile),
|
|
996
1029
|
error_code="PORTAL_LIST_FAILED",
|
|
997
1030
|
normalized_args={},
|
|
998
1031
|
suggested_next_call={"tool_name": "portal_list", "arguments": {"profile": profile}},
|
|
999
|
-
)
|
|
1032
|
+
))
|
|
1000
1033
|
|
|
1001
1034
|
def portal_get(self, *, profile: str, dash_key: str, being_draft: bool = True) -> JSONObject:
|
|
1002
1035
|
normalized_args = {"dash_key": dash_key, "being_draft": being_draft}
|
|
1003
|
-
return _safe_tool_call(
|
|
1036
|
+
return _publicize_package_fields(_safe_tool_call(
|
|
1004
1037
|
lambda: self._facade.portal_get(profile=profile, dash_key=dash_key, being_draft=being_draft),
|
|
1005
1038
|
error_code="PORTAL_GET_FAILED",
|
|
1006
1039
|
normalized_args=normalized_args,
|
|
1007
1040
|
suggested_next_call={"tool_name": "portal_get", "arguments": {"profile": profile, **normalized_args}},
|
|
1008
|
-
)
|
|
1041
|
+
))
|
|
1009
1042
|
|
|
1010
1043
|
def portal_read_summary(self, *, profile: str, dash_key: str, being_draft: bool = True) -> JSONObject:
|
|
1011
1044
|
normalized_args = {"dash_key": dash_key, "being_draft": being_draft}
|
|
1012
|
-
return _safe_tool_call(
|
|
1045
|
+
return _publicize_package_fields(_safe_tool_call(
|
|
1013
1046
|
lambda: self._facade.portal_read_summary(profile=profile, dash_key=dash_key, being_draft=being_draft),
|
|
1014
1047
|
error_code="PORTAL_READ_FAILED",
|
|
1015
1048
|
normalized_args=normalized_args,
|
|
1016
1049
|
suggested_next_call={"tool_name": "portal_get", "arguments": {"profile": profile, **normalized_args}},
|
|
1017
|
-
)
|
|
1050
|
+
))
|
|
1018
1051
|
|
|
1019
1052
|
def view_get(self, *, profile: str, view_key: str = "", viewgraph_key: str = "") -> JSONObject:
|
|
1020
1053
|
resolved_view_key = str(view_key or viewgraph_key or "").strip()
|
|
@@ -1045,7 +1078,7 @@ class AiBuilderTools(ToolBase):
|
|
|
1045
1078
|
*,
|
|
1046
1079
|
profile: str,
|
|
1047
1080
|
app_key: str = "",
|
|
1048
|
-
|
|
1081
|
+
package_id: int | None = None,
|
|
1049
1082
|
app_name: str = "",
|
|
1050
1083
|
icon: str = "",
|
|
1051
1084
|
color: str = "",
|
|
@@ -1059,7 +1092,7 @@ class AiBuilderTools(ToolBase):
|
|
|
1059
1092
|
request = SchemaPlanRequest.model_validate(
|
|
1060
1093
|
{
|
|
1061
1094
|
"app_key": app_key,
|
|
1062
|
-
"package_tag_id":
|
|
1095
|
+
"package_tag_id": package_id,
|
|
1063
1096
|
"app_name": app_name,
|
|
1064
1097
|
"icon": icon,
|
|
1065
1098
|
"color": color,
|
|
@@ -1080,7 +1113,7 @@ class AiBuilderTools(ToolBase):
|
|
|
1080
1113
|
"arguments": {
|
|
1081
1114
|
"profile": profile,
|
|
1082
1115
|
"app_key": app_key,
|
|
1083
|
-
"
|
|
1116
|
+
"package_id": package_id,
|
|
1084
1117
|
"app_name": app_name,
|
|
1085
1118
|
"icon": icon,
|
|
1086
1119
|
"color": color,
|
|
@@ -1092,12 +1125,13 @@ class AiBuilderTools(ToolBase):
|
|
|
1092
1125
|
},
|
|
1093
1126
|
},
|
|
1094
1127
|
)
|
|
1095
|
-
|
|
1128
|
+
normalized_args = _publicize_package_fields(request.model_dump(mode="json"))
|
|
1129
|
+
return _publicize_package_fields(_safe_tool_call(
|
|
1096
1130
|
lambda: self._facade.app_schema_plan(profile=profile, request=request),
|
|
1097
1131
|
error_code="SCHEMA_PLAN_FAILED",
|
|
1098
|
-
normalized_args=
|
|
1099
|
-
suggested_next_call={"tool_name": "app_schema_plan", "arguments": {"profile": profile, **
|
|
1100
|
-
)
|
|
1132
|
+
normalized_args=normalized_args,
|
|
1133
|
+
suggested_next_call={"tool_name": "app_schema_plan", "arguments": {"profile": profile, **normalized_args}},
|
|
1134
|
+
))
|
|
1101
1135
|
|
|
1102
1136
|
def app_layout_plan(
|
|
1103
1137
|
self,
|
|
@@ -1235,7 +1269,7 @@ class AiBuilderTools(ToolBase):
|
|
|
1235
1269
|
*,
|
|
1236
1270
|
profile: str,
|
|
1237
1271
|
app_key: str = "",
|
|
1238
|
-
|
|
1272
|
+
package_id: int | None = None,
|
|
1239
1273
|
app_name: str = "",
|
|
1240
1274
|
app_title: str = "",
|
|
1241
1275
|
icon: str = "",
|
|
@@ -1250,7 +1284,7 @@ class AiBuilderTools(ToolBase):
|
|
|
1250
1284
|
result = self._app_schema_apply_once(
|
|
1251
1285
|
profile=profile,
|
|
1252
1286
|
app_key=app_key,
|
|
1253
|
-
|
|
1287
|
+
package_id=package_id,
|
|
1254
1288
|
app_name=app_name,
|
|
1255
1289
|
app_title=app_title,
|
|
1256
1290
|
icon=icon,
|
|
@@ -1268,7 +1302,7 @@ class AiBuilderTools(ToolBase):
|
|
|
1268
1302
|
retry_call=lambda: self._app_schema_apply_once(
|
|
1269
1303
|
profile=profile,
|
|
1270
1304
|
app_key=app_key,
|
|
1271
|
-
|
|
1305
|
+
package_id=package_id,
|
|
1272
1306
|
app_name=app_name,
|
|
1273
1307
|
app_title=app_title,
|
|
1274
1308
|
icon=icon,
|
|
@@ -1287,7 +1321,7 @@ class AiBuilderTools(ToolBase):
|
|
|
1287
1321
|
*,
|
|
1288
1322
|
profile: str,
|
|
1289
1323
|
app_key: str = "",
|
|
1290
|
-
|
|
1324
|
+
package_id: int | None = None,
|
|
1291
1325
|
app_name: str = "",
|
|
1292
1326
|
app_title: str = "",
|
|
1293
1327
|
icon: str = "",
|
|
@@ -1304,7 +1338,7 @@ class AiBuilderTools(ToolBase):
|
|
|
1304
1338
|
result=self.app_schema_plan(
|
|
1305
1339
|
profile=profile,
|
|
1306
1340
|
app_key=app_key,
|
|
1307
|
-
|
|
1341
|
+
package_id=package_id,
|
|
1308
1342
|
app_name=effective_app_name,
|
|
1309
1343
|
icon=icon,
|
|
1310
1344
|
color=color,
|
|
@@ -1338,7 +1372,7 @@ class AiBuilderTools(ToolBase):
|
|
|
1338
1372
|
"arguments": {
|
|
1339
1373
|
"profile": profile,
|
|
1340
1374
|
"app_key": str(plan_args.get("app_key") or app_key),
|
|
1341
|
-
"
|
|
1375
|
+
"package_id": plan_args.get("package_id", package_id),
|
|
1342
1376
|
"app_name": str(plan_args.get("app_name") or effective_app_name),
|
|
1343
1377
|
"icon": str(plan_args.get("icon") or icon),
|
|
1344
1378
|
"color": str(plan_args.get("color") or color),
|
|
@@ -1353,7 +1387,7 @@ class AiBuilderTools(ToolBase):
|
|
|
1353
1387
|
)
|
|
1354
1388
|
normalized_args = {
|
|
1355
1389
|
"app_key": str(plan_args.get("app_key") or app_key),
|
|
1356
|
-
"
|
|
1390
|
+
"package_id": plan_args.get("package_id", package_id),
|
|
1357
1391
|
"app_name": str(plan_args.get("app_name") or effective_app_name),
|
|
1358
1392
|
"icon": str(plan_args.get("icon") or icon or ""),
|
|
1359
1393
|
"color": str(plan_args.get("color") or color or ""),
|
|
@@ -1368,7 +1402,7 @@ class AiBuilderTools(ToolBase):
|
|
|
1368
1402
|
lambda: self._facade.app_schema_apply(
|
|
1369
1403
|
profile=profile,
|
|
1370
1404
|
app_key=str(plan_args.get("app_key") or app_key),
|
|
1371
|
-
package_tag_id=plan_args.get("
|
|
1405
|
+
package_tag_id=plan_args.get("package_id", package_id),
|
|
1372
1406
|
app_name=str(plan_args.get("app_name") or effective_app_name),
|
|
1373
1407
|
icon=str(plan_args.get("icon") or icon or ""),
|
|
1374
1408
|
color=str(plan_args.get("color") or color or ""),
|
|
@@ -1383,7 +1417,7 @@ class AiBuilderTools(ToolBase):
|
|
|
1383
1417
|
normalized_args=normalized_args,
|
|
1384
1418
|
suggested_next_call={"tool_name": "app_schema_apply", "arguments": {"profile": profile, **normalized_args}},
|
|
1385
1419
|
)
|
|
1386
|
-
return result
|
|
1420
|
+
return _publicize_package_fields(result)
|
|
1387
1421
|
|
|
1388
1422
|
def app_layout_apply(self, *, profile: str, app_key: str, mode: str = "merge", publish: bool = True, sections: list[JSONObject]) -> JSONObject:
|
|
1389
1423
|
result = self._app_layout_apply_once(
|
|
@@ -1727,7 +1761,7 @@ class AiBuilderTools(ToolBase):
|
|
|
1727
1761
|
profile: str,
|
|
1728
1762
|
dash_key: str = "",
|
|
1729
1763
|
dash_name: str = "",
|
|
1730
|
-
|
|
1764
|
+
package_id: int | None = None,
|
|
1731
1765
|
publish: bool = True,
|
|
1732
1766
|
sections: list[JSONObject],
|
|
1733
1767
|
visibility: JSONObject | None = None,
|
|
@@ -1743,7 +1777,7 @@ class AiBuilderTools(ToolBase):
|
|
|
1743
1777
|
{
|
|
1744
1778
|
"dash_key": dash_key or None,
|
|
1745
1779
|
"dash_name": dash_name or None,
|
|
1746
|
-
"package_tag_id":
|
|
1780
|
+
"package_tag_id": package_id,
|
|
1747
1781
|
"publish": publish,
|
|
1748
1782
|
"sections": sections or [],
|
|
1749
1783
|
"visibility": visibility,
|
|
@@ -1765,7 +1799,7 @@ class AiBuilderTools(ToolBase):
|
|
|
1765
1799
|
"arguments": {
|
|
1766
1800
|
"profile": profile,
|
|
1767
1801
|
"dash_name": dash_name or "业务门户",
|
|
1768
|
-
"
|
|
1802
|
+
"package_id": package_id or 1001,
|
|
1769
1803
|
"publish": True,
|
|
1770
1804
|
"sections": [
|
|
1771
1805
|
{
|
|
@@ -1778,30 +1812,37 @@ class AiBuilderTools(ToolBase):
|
|
|
1778
1812
|
},
|
|
1779
1813
|
)
|
|
1780
1814
|
normalized_args = request.model_dump(mode="json")
|
|
1781
|
-
|
|
1815
|
+
normalized_args["package_id"] = normalized_args.pop("package_tag_id", package_id)
|
|
1816
|
+
return _publicize_package_fields(_safe_tool_call(
|
|
1782
1817
|
lambda: self._facade.portal_apply(profile=profile, request=request),
|
|
1783
1818
|
error_code="PORTAL_APPLY_FAILED",
|
|
1784
1819
|
normalized_args=normalized_args,
|
|
1785
1820
|
suggested_next_call={"tool_name": "portal_apply", "arguments": {"profile": profile, **normalized_args}},
|
|
1786
|
-
)
|
|
1821
|
+
))
|
|
1787
1822
|
|
|
1788
|
-
def app_publish_verify(
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1823
|
+
def app_publish_verify(
|
|
1824
|
+
self,
|
|
1825
|
+
*,
|
|
1826
|
+
profile: str,
|
|
1827
|
+
app_key: str,
|
|
1828
|
+
expected_package_id: int | None = None,
|
|
1829
|
+
) -> JSONObject:
|
|
1830
|
+
normalized_args = {"app_key": app_key, "expected_package_id": expected_package_id}
|
|
1831
|
+
result = _publicize_package_fields(_safe_tool_call(
|
|
1832
|
+
lambda: self._facade.app_publish_verify(profile=profile, app_key=app_key, expected_package_tag_id=expected_package_id),
|
|
1792
1833
|
error_code="PUBLISH_VERIFY_FAILED",
|
|
1793
1834
|
normalized_args=normalized_args,
|
|
1794
1835
|
suggested_next_call={"tool_name": "app_publish_verify", "arguments": {"profile": profile, **normalized_args}},
|
|
1795
|
-
)
|
|
1796
|
-
return self._retry_after_self_lock_release(
|
|
1836
|
+
))
|
|
1837
|
+
return _publicize_package_fields(self._retry_after_self_lock_release(
|
|
1797
1838
|
profile=profile,
|
|
1798
1839
|
result=result,
|
|
1799
1840
|
retry_call=lambda: self._facade.app_publish_verify(
|
|
1800
1841
|
profile=profile,
|
|
1801
1842
|
app_key=app_key,
|
|
1802
|
-
expected_package_tag_id=
|
|
1843
|
+
expected_package_tag_id=expected_package_id,
|
|
1803
1844
|
),
|
|
1804
|
-
)
|
|
1845
|
+
))
|
|
1805
1846
|
|
|
1806
1847
|
def _retry_after_self_lock_release(self, *, profile: str, result: JSONObject, retry_call) -> JSONObject:
|
|
1807
1848
|
if not isinstance(result, dict) or result.get("status") != "failed" or result.get("error_code") != "APP_EDIT_LOCKED":
|
|
@@ -2057,6 +2098,29 @@ def _safe_tool_call(
|
|
|
2057
2098
|
}
|
|
2058
2099
|
|
|
2059
2100
|
|
|
2101
|
+
def _publicize_package_fields(value):
|
|
2102
|
+
if isinstance(value, list):
|
|
2103
|
+
return [_publicize_package_fields(item) for item in value]
|
|
2104
|
+
if not isinstance(value, dict):
|
|
2105
|
+
return value
|
|
2106
|
+
key_map = {
|
|
2107
|
+
"tag_id": "package_id",
|
|
2108
|
+
"tag_ids": "package_ids",
|
|
2109
|
+
"tag_ids_before": "package_ids_before",
|
|
2110
|
+
"tag_ids_after": "package_ids_after",
|
|
2111
|
+
"tag_name": "package_name",
|
|
2112
|
+
"tag_icon": "icon",
|
|
2113
|
+
"package_tag_id": "package_id",
|
|
2114
|
+
"package_tag_ids": "package_ids",
|
|
2115
|
+
"expected_package_tag_id": "expected_package_id",
|
|
2116
|
+
}
|
|
2117
|
+
public: JSONObject = {}
|
|
2118
|
+
for key, item in value.items():
|
|
2119
|
+
public_key = key_map.get(key, key)
|
|
2120
|
+
public[public_key] = _publicize_package_fields(item)
|
|
2121
|
+
return public
|
|
2122
|
+
|
|
2123
|
+
|
|
2060
2124
|
def _coerce_api_error(error: Exception) -> QingflowApiError:
|
|
2061
2125
|
if isinstance(error, QingflowApiError):
|
|
2062
2126
|
return error
|
|
@@ -2205,88 +2269,59 @@ _BUILDER_TOOL_CONTRACTS: dict[str, JSONObject] = {
|
|
|
2205
2269
|
"tool_name": "chart_get",
|
|
2206
2270
|
},
|
|
2207
2271
|
},
|
|
2208
|
-
"package_list": {
|
|
2209
|
-
"allowed_keys": ["trial_status"],
|
|
2210
|
-
"aliases": {"trialStatus": "trial_status"},
|
|
2211
|
-
"allowed_values": {"trial_status": ["all", "trial", "formal"]},
|
|
2212
|
-
"minimal_example": {
|
|
2213
|
-
"profile": "default",
|
|
2214
|
-
"trial_status": "all",
|
|
2215
|
-
},
|
|
2216
|
-
},
|
|
2217
|
-
"package_resolve": {
|
|
2218
|
-
"allowed_keys": ["package_name"],
|
|
2219
|
-
"aliases": {"packageName": "package_name"},
|
|
2220
|
-
"allowed_values": {},
|
|
2221
|
-
"minimal_example": {
|
|
2222
|
-
"profile": "default",
|
|
2223
|
-
"package_name": "PLM(备用,施工中)",
|
|
2224
|
-
},
|
|
2225
|
-
},
|
|
2226
|
-
"package_create": {
|
|
2227
|
-
"allowed_keys": ["package_name", "icon", "color", "visibility"],
|
|
2228
|
-
"aliases": {
|
|
2229
|
-
"packageName": "package_name",
|
|
2230
|
-
"iconName": "icon",
|
|
2231
|
-
"iconColor": "color",
|
|
2232
|
-
},
|
|
2233
|
-
"allowed_values": deepcopy(_VISIBILITY_ALLOWED_VALUES),
|
|
2234
|
-
"execution_notes": [
|
|
2235
|
-
"create a package and optionally set visibility in the same call",
|
|
2236
|
-
*_VISIBILITY_EXECUTION_NOTES,
|
|
2237
|
-
],
|
|
2238
|
-
"minimal_example": {
|
|
2239
|
-
"profile": "default",
|
|
2240
|
-
"package_name": "项目管理",
|
|
2241
|
-
"icon": "files-folder",
|
|
2242
|
-
"color": "azure",
|
|
2243
|
-
"visibility": deepcopy(_VISIBILITY_WORKSPACE_EXAMPLE),
|
|
2244
|
-
},
|
|
2245
|
-
"specific_visibility_example": {
|
|
2246
|
-
"profile": "default",
|
|
2247
|
-
"package_name": "项目管理",
|
|
2248
|
-
"icon": "files-folder",
|
|
2249
|
-
"color": "azure",
|
|
2250
|
-
"visibility": deepcopy(_VISIBILITY_SPECIFIC_EXAMPLE),
|
|
2251
|
-
},
|
|
2252
|
-
},
|
|
2253
2272
|
"package_get": {
|
|
2254
|
-
"allowed_keys": ["
|
|
2255
|
-
"aliases": {"
|
|
2273
|
+
"allowed_keys": ["package_id"],
|
|
2274
|
+
"aliases": {"packageId": "package_id"},
|
|
2256
2275
|
"allowed_values": {},
|
|
2257
2276
|
"execution_notes": [
|
|
2258
|
-
"returns package
|
|
2277
|
+
"returns complete public package schema with package_id, package_name, icon, visibility, and items",
|
|
2278
|
+
"package_id maps internally to backend tagId; do not use tag_id in public calls",
|
|
2259
2279
|
"visibility is normalized from backend MemberAuthInfoVO auth",
|
|
2260
2280
|
],
|
|
2261
2281
|
"minimal_example": {
|
|
2262
2282
|
"profile": "default",
|
|
2263
|
-
"
|
|
2283
|
+
"package_id": 1001,
|
|
2264
2284
|
},
|
|
2265
2285
|
},
|
|
2266
|
-
"
|
|
2267
|
-
"allowed_keys": ["
|
|
2286
|
+
"package_apply": {
|
|
2287
|
+
"allowed_keys": ["package_id", "package_name", "create_if_missing", "icon", "color", "visibility", "items", "allow_detach"],
|
|
2268
2288
|
"aliases": {
|
|
2269
|
-
"
|
|
2289
|
+
"packageId": "package_id",
|
|
2270
2290
|
"packageName": "package_name",
|
|
2291
|
+
"createIfMissing": "create_if_missing",
|
|
2271
2292
|
"iconName": "icon",
|
|
2272
2293
|
"iconColor": "color",
|
|
2294
|
+
"allowDetach": "allow_detach",
|
|
2273
2295
|
},
|
|
2274
2296
|
"allowed_values": deepcopy(_VISIBILITY_ALLOWED_VALUES),
|
|
2275
2297
|
"execution_notes": [
|
|
2276
|
-
"update package
|
|
2298
|
+
"create or update package metadata, visibility, grouping, and ordering in one call",
|
|
2299
|
+
"package_id maps internally to backend tagId; do not use tag_id in public calls",
|
|
2300
|
+
"items is a full package layout tree; omitting existing app/portal items is blocked unless allow_detach=true",
|
|
2301
|
+
"item shapes: {type:'app', app_key}, {type:'portal', dash_key}, or {type:'group', group_id?, name, items:[...]}",
|
|
2277
2302
|
*_VISIBILITY_EXECUTION_NOTES,
|
|
2278
2303
|
],
|
|
2279
2304
|
"minimal_example": {
|
|
2280
2305
|
"profile": "default",
|
|
2281
|
-
"
|
|
2306
|
+
"package_id": 1001,
|
|
2282
2307
|
"package_name": "项目管理",
|
|
2283
2308
|
"visibility": deepcopy(_VISIBILITY_WORKSPACE_EXAMPLE),
|
|
2309
|
+
"items": [{"type": "app", "app_key": "APP_KEY", "title": "项目台账"}],
|
|
2310
|
+
"allow_detach": False,
|
|
2284
2311
|
},
|
|
2285
2312
|
"specific_visibility_example": {
|
|
2286
2313
|
"profile": "default",
|
|
2287
|
-
"
|
|
2314
|
+
"package_id": 1001,
|
|
2288
2315
|
"visibility": deepcopy(_VISIBILITY_SPECIFIC_EXAMPLE),
|
|
2289
2316
|
},
|
|
2317
|
+
"create_example": {
|
|
2318
|
+
"profile": "default",
|
|
2319
|
+
"package_name": "项目管理",
|
|
2320
|
+
"create_if_missing": True,
|
|
2321
|
+
"icon": "files-folder",
|
|
2322
|
+
"color": "azure",
|
|
2323
|
+
"visibility": deepcopy(_VISIBILITY_WORKSPACE_EXAMPLE),
|
|
2324
|
+
},
|
|
2290
2325
|
},
|
|
2291
2326
|
"solution_install": {
|
|
2292
2327
|
"allowed_keys": ["solution_key", "being_copy_data", "solution_source"],
|
|
@@ -2350,28 +2385,14 @@ _BUILDER_TOOL_CONTRACTS: dict[str, JSONObject] = {
|
|
|
2350
2385
|
"role_icon": "ex-user-outlined",
|
|
2351
2386
|
},
|
|
2352
2387
|
},
|
|
2353
|
-
"package_attach_app": {
|
|
2354
|
-
"allowed_keys": ["tag_id", "app_key"],
|
|
2355
|
-
"aliases": {},
|
|
2356
|
-
"allowed_values": {},
|
|
2357
|
-
"execution_notes": [
|
|
2358
|
-
"attach one existing app to one existing package",
|
|
2359
|
-
"app_title is no longer accepted as a public selector; resolve the app first and pass app_key",
|
|
2360
|
-
],
|
|
2361
|
-
"minimal_example": {
|
|
2362
|
-
"profile": "default",
|
|
2363
|
-
"tag_id": 1001,
|
|
2364
|
-
"app_key": "APP_KEY",
|
|
2365
|
-
},
|
|
2366
|
-
},
|
|
2367
2388
|
"app_resolve": {
|
|
2368
|
-
"allowed_keys": ["app_key", "app_name", "
|
|
2369
|
-
"aliases": {},
|
|
2389
|
+
"allowed_keys": ["app_key", "app_name", "package_id"],
|
|
2390
|
+
"aliases": {"packageId": "package_id"},
|
|
2370
2391
|
"allowed_values": {},
|
|
2371
2392
|
"execution_notes": [
|
|
2372
2393
|
"use exactly one selector mode",
|
|
2373
2394
|
"mode 1: app_key",
|
|
2374
|
-
"mode 2: app_name +
|
|
2395
|
+
"mode 2: app_name + package_id",
|
|
2375
2396
|
],
|
|
2376
2397
|
"minimal_example": {
|
|
2377
2398
|
"profile": "default",
|
|
@@ -2380,7 +2401,7 @@ _BUILDER_TOOL_CONTRACTS: dict[str, JSONObject] = {
|
|
|
2380
2401
|
"package_scoped_example": {
|
|
2381
2402
|
"profile": "default",
|
|
2382
2403
|
"app_name": "研发项目管理",
|
|
2383
|
-
"
|
|
2404
|
+
"package_id": 1001,
|
|
2384
2405
|
},
|
|
2385
2406
|
},
|
|
2386
2407
|
"app_release_edit_lock_if_mine": {
|
|
@@ -2505,10 +2526,11 @@ _BUILDER_TOOL_CONTRACTS: dict[str, JSONObject] = {
|
|
|
2505
2526
|
},
|
|
2506
2527
|
},
|
|
2507
2528
|
"app_schema_plan": {
|
|
2508
|
-
"allowed_keys": ["app_key", "
|
|
2529
|
+
"allowed_keys": ["app_key", "package_id", "app_name", "icon", "color", "visibility", "create_if_missing", "add_fields", "update_fields", "remove_fields"],
|
|
2509
2530
|
"aliases": {
|
|
2510
2531
|
"app_title": "app_name",
|
|
2511
2532
|
"title": "app_name",
|
|
2533
|
+
"packageId": "package_id",
|
|
2512
2534
|
"field.title": "field.name",
|
|
2513
2535
|
"field.label": "field.name",
|
|
2514
2536
|
"field.fields": "field.subfields",
|
|
@@ -2542,7 +2564,7 @@ _BUILDER_TOOL_CONTRACTS: dict[str, JSONObject] = {
|
|
|
2542
2564
|
"minimal_example": {
|
|
2543
2565
|
"profile": "default",
|
|
2544
2566
|
"app_name": "研发项目管理",
|
|
2545
|
-
"
|
|
2567
|
+
"package_id": 1001,
|
|
2546
2568
|
"icon": "template",
|
|
2547
2569
|
"color": "emerald",
|
|
2548
2570
|
"visibility": deepcopy(_VISIBILITY_WORKSPACE_EXAMPLE),
|
|
@@ -2569,10 +2591,11 @@ _BUILDER_TOOL_CONTRACTS: dict[str, JSONObject] = {
|
|
|
2569
2591
|
},
|
|
2570
2592
|
},
|
|
2571
2593
|
"app_schema_apply": {
|
|
2572
|
-
"allowed_keys": ["app_key", "
|
|
2594
|
+
"allowed_keys": ["app_key", "package_id", "app_name", "icon", "color", "visibility", "create_if_missing", "publish", "add_fields", "update_fields", "remove_fields"],
|
|
2573
2595
|
"aliases": {
|
|
2574
2596
|
"app_title": "app_name",
|
|
2575
2597
|
"title": "app_name",
|
|
2598
|
+
"packageId": "package_id",
|
|
2576
2599
|
"field.title": "field.name",
|
|
2577
2600
|
"field.label": "field.name",
|
|
2578
2601
|
"field.fields": "field.subfields",
|
|
@@ -2605,7 +2628,7 @@ _BUILDER_TOOL_CONTRACTS: dict[str, JSONObject] = {
|
|
|
2605
2628
|
"execution_notes": [
|
|
2606
2629
|
"use exactly one resource mode",
|
|
2607
2630
|
"edit mode: app_key, optional app_name to rename the existing app",
|
|
2608
|
-
"create mode:
|
|
2631
|
+
"create mode: package_id + app_name + create_if_missing=true",
|
|
2609
2632
|
"create mode defaults new app visibility to workspace/not when visibility is omitted; edit mode preserves current visibility when omitted",
|
|
2610
2633
|
*_VISIBILITY_EXECUTION_NOTES,
|
|
2611
2634
|
"multiple relation fields are backend-risky; read verification.relation_field_limit_verified and warnings before declaring the schema stable",
|
|
@@ -2624,7 +2647,7 @@ _BUILDER_TOOL_CONTRACTS: dict[str, JSONObject] = {
|
|
|
2624
2647
|
"minimal_example": {
|
|
2625
2648
|
"profile": "default",
|
|
2626
2649
|
"app_name": "研发项目管理",
|
|
2627
|
-
"
|
|
2650
|
+
"package_id": 1001,
|
|
2628
2651
|
"icon": "template",
|
|
2629
2652
|
"color": "emerald",
|
|
2630
2653
|
"visibility": deepcopy(_VISIBILITY_WORKSPACE_EXAMPLE),
|
|
@@ -3178,8 +3201,9 @@ _BUILDER_TOOL_CONTRACTS: dict[str, JSONObject] = {
|
|
|
3178
3201
|
},
|
|
3179
3202
|
},
|
|
3180
3203
|
"portal_apply": {
|
|
3181
|
-
"allowed_keys": ["dash_key", "dash_name", "
|
|
3204
|
+
"allowed_keys": ["dash_key", "dash_name", "package_id", "publish", "sections", "visibility", "auth", "icon", "color", "hide_copyright", "dash_global_config", "config"],
|
|
3182
3205
|
"aliases": {
|
|
3206
|
+
"packageId": "package_id",
|
|
3183
3207
|
"sourceType": "source_type",
|
|
3184
3208
|
"chartRef": "chart_ref",
|
|
3185
3209
|
"viewRef": "view_ref",
|
|
@@ -3196,10 +3220,10 @@ _BUILDER_TOOL_CONTRACTS: dict[str, JSONObject] = {
|
|
|
3196
3220
|
"execution_notes": [
|
|
3197
3221
|
"use exactly one resource mode",
|
|
3198
3222
|
"update mode: dash_key",
|
|
3199
|
-
"create mode:
|
|
3223
|
+
"create mode: package_id + dash_name",
|
|
3200
3224
|
"portal_apply uses replace semantics for sections",
|
|
3201
3225
|
"remove a section by omitting it from the new sections list",
|
|
3202
|
-
"
|
|
3226
|
+
"package_id is required when creating a new portal",
|
|
3203
3227
|
"publish=false only guarantees draft and base-info updates; it does not claim live has changed",
|
|
3204
3228
|
"chart_ref resolves by chart_id first, then exact unique chart_name",
|
|
3205
3229
|
"view_ref resolves by view_key first, then exact unique view_name",
|
|
@@ -3211,7 +3235,7 @@ _BUILDER_TOOL_CONTRACTS: dict[str, JSONObject] = {
|
|
|
3211
3235
|
"minimal_example": {
|
|
3212
3236
|
"profile": "default",
|
|
3213
3237
|
"dash_name": "经营门户",
|
|
3214
|
-
"
|
|
3238
|
+
"package_id": 1001,
|
|
3215
3239
|
"publish": True,
|
|
3216
3240
|
"visibility": deepcopy(_VISIBILITY_WORKSPACE_EXAMPLE),
|
|
3217
3241
|
"sections": [
|
|
@@ -3237,18 +3261,18 @@ _BUILDER_TOOL_CONTRACTS: dict[str, JSONObject] = {
|
|
|
3237
3261
|
},
|
|
3238
3262
|
},
|
|
3239
3263
|
"app_publish_verify": {
|
|
3240
|
-
"allowed_keys": ["app_key", "
|
|
3264
|
+
"allowed_keys": ["app_key", "expected_package_id"],
|
|
3241
3265
|
"aliases": {},
|
|
3242
3266
|
"allowed_values": {},
|
|
3243
3267
|
"execution_notes": [
|
|
3244
3268
|
"verifies that the current app draft has been published and is readable through the builder surface",
|
|
3245
|
-
"
|
|
3269
|
+
"expected_package_id is optional and adds an extra package consistency check",
|
|
3246
3270
|
"when verification fails because of an edit lock owned by the current user, retry after app_release_edit_lock_if_mine",
|
|
3247
3271
|
],
|
|
3248
3272
|
"minimal_example": {
|
|
3249
3273
|
"profile": "default",
|
|
3250
3274
|
"app_key": "APP_KEY",
|
|
3251
|
-
"
|
|
3275
|
+
"expected_package_id": 1001,
|
|
3252
3276
|
},
|
|
3253
3277
|
},
|
|
3254
3278
|
"app_repair_code_blocks": {
|