@josephyan/qingflow-cli 0.2.0-beta.71 → 0.2.0-beta.73
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/backend_client.py +1 -0
- package/src/qingflow_mcp/builder_facade/models.py +22 -11
- package/src/qingflow_mcp/builder_facade/service.py +183 -121
- package/src/qingflow_mcp/cli/commands/__init__.py +4 -1
- package/src/qingflow_mcp/cli/commands/builder.py +81 -64
- package/src/qingflow_mcp/cli/commands/chart.py +18 -0
- package/src/qingflow_mcp/cli/commands/portal.py +25 -0
- package/src/qingflow_mcp/cli/commands/view.py +18 -0
- package/src/qingflow_mcp/cli/context.py +9 -0
- package/src/qingflow_mcp/response_trim.py +219 -178
- package/src/qingflow_mcp/server_app_builder.py +18 -42
- package/src/qingflow_mcp/server_app_user.py +21 -1
- package/src/qingflow_mcp/tools/ai_builder_tools.py +244 -124
- package/src/qingflow_mcp/tools/app_tools.py +0 -4
- package/src/qingflow_mcp/tools/resource_read_tools.py +399 -0
|
@@ -209,28 +209,28 @@ class AiBuilderTools(ToolBase):
|
|
|
209
209
|
return self.app_custom_button_delete(profile=profile, app_key=app_key, button_id=button_id)
|
|
210
210
|
|
|
211
211
|
@mcp.tool()
|
|
212
|
-
def
|
|
213
|
-
return self.
|
|
212
|
+
def app_get(profile: str = DEFAULT_PROFILE, app_key: str = "") -> JSONObject:
|
|
213
|
+
return self.app_get(profile=profile, app_key=app_key)
|
|
214
214
|
|
|
215
215
|
@mcp.tool()
|
|
216
|
-
def
|
|
217
|
-
return self.
|
|
216
|
+
def app_get_fields(profile: str = DEFAULT_PROFILE, app_key: str = "") -> JSONObject:
|
|
217
|
+
return self.app_get_fields(profile=profile, app_key=app_key)
|
|
218
218
|
|
|
219
219
|
@mcp.tool()
|
|
220
|
-
def
|
|
221
|
-
return self.
|
|
220
|
+
def app_get_layout(profile: str = DEFAULT_PROFILE, app_key: str = "") -> JSONObject:
|
|
221
|
+
return self.app_get_layout(profile=profile, app_key=app_key)
|
|
222
222
|
|
|
223
223
|
@mcp.tool()
|
|
224
|
-
def
|
|
225
|
-
return self.
|
|
224
|
+
def app_get_views(profile: str = DEFAULT_PROFILE, app_key: str = "") -> JSONObject:
|
|
225
|
+
return self.app_get_views(profile=profile, app_key=app_key)
|
|
226
226
|
|
|
227
227
|
@mcp.tool()
|
|
228
|
-
def
|
|
229
|
-
return self.
|
|
228
|
+
def app_get_flow(profile: str = DEFAULT_PROFILE, app_key: str = "") -> JSONObject:
|
|
229
|
+
return self.app_get_flow(profile=profile, app_key=app_key)
|
|
230
230
|
|
|
231
231
|
@mcp.tool()
|
|
232
|
-
def
|
|
233
|
-
return self.
|
|
232
|
+
def app_get_charts(profile: str = DEFAULT_PROFILE, app_key: str = "") -> JSONObject:
|
|
233
|
+
return self.app_get_charts(profile=profile, app_key=app_key)
|
|
234
234
|
|
|
235
235
|
@mcp.tool()
|
|
236
236
|
def portal_list(profile: str = DEFAULT_PROFILE) -> JSONObject:
|
|
@@ -245,36 +245,15 @@ class AiBuilderTools(ToolBase):
|
|
|
245
245
|
return self.portal_get(profile=profile, dash_key=dash_key, being_draft=being_draft)
|
|
246
246
|
|
|
247
247
|
@mcp.tool()
|
|
248
|
-
def
|
|
249
|
-
profile
|
|
250
|
-
dash_key: str = "",
|
|
251
|
-
being_draft: bool = True,
|
|
252
|
-
) -> JSONObject:
|
|
253
|
-
return self.portal_read_summary(profile=profile, dash_key=dash_key, being_draft=being_draft)
|
|
254
|
-
|
|
255
|
-
@mcp.tool()
|
|
256
|
-
def view_get(profile: str = DEFAULT_PROFILE, viewgraph_key: str = "") -> JSONObject:
|
|
257
|
-
return self.view_get(profile=profile, viewgraph_key=viewgraph_key)
|
|
248
|
+
def view_get(profile: str = DEFAULT_PROFILE, view_key: str = "") -> JSONObject:
|
|
249
|
+
return self.view_get(profile=profile, view_key=view_key)
|
|
258
250
|
|
|
259
251
|
@mcp.tool()
|
|
260
252
|
def chart_get(
|
|
261
253
|
profile: str = DEFAULT_PROFILE,
|
|
262
254
|
chart_id: str = "",
|
|
263
|
-
data_payload: JSONObject | None = None,
|
|
264
|
-
page_num: int | None = None,
|
|
265
|
-
page_size: int | None = None,
|
|
266
|
-
page_num_y: int | None = None,
|
|
267
|
-
page_size_y: int | None = None,
|
|
268
255
|
) -> JSONObject:
|
|
269
|
-
return self.chart_get(
|
|
270
|
-
profile=profile,
|
|
271
|
-
chart_id=chart_id,
|
|
272
|
-
data_payload=data_payload or {},
|
|
273
|
-
page_num=page_num,
|
|
274
|
-
page_size=page_size,
|
|
275
|
-
page_num_y=page_num_y,
|
|
276
|
-
page_size_y=page_size_y,
|
|
277
|
-
)
|
|
256
|
+
return self.chart_get(profile=profile, chart_id=chart_id)
|
|
278
257
|
|
|
279
258
|
@mcp.tool()
|
|
280
259
|
def app_schema_apply(
|
|
@@ -759,7 +738,16 @@ class AiBuilderTools(ToolBase):
|
|
|
759
738
|
lambda: self._facade.app_read_summary(profile=profile, app_key=app_key),
|
|
760
739
|
error_code="APP_READ_FAILED",
|
|
761
740
|
normalized_args=normalized_args,
|
|
762
|
-
suggested_next_call={"tool_name": "
|
|
741
|
+
suggested_next_call={"tool_name": "app_get", "arguments": {"profile": profile, "app_key": app_key}},
|
|
742
|
+
)
|
|
743
|
+
|
|
744
|
+
def app_get(self, *, profile: str, app_key: str) -> JSONObject:
|
|
745
|
+
normalized_args = {"app_key": app_key}
|
|
746
|
+
return _safe_tool_call(
|
|
747
|
+
lambda: self._facade.app_get(profile=profile, app_key=app_key),
|
|
748
|
+
error_code="APP_GET_FAILED",
|
|
749
|
+
normalized_args=normalized_args,
|
|
750
|
+
suggested_next_call={"tool_name": "app_get", "arguments": {"profile": profile, "app_key": app_key}},
|
|
763
751
|
)
|
|
764
752
|
|
|
765
753
|
def app_read_fields(self, *, profile: str, app_key: str) -> JSONObject:
|
|
@@ -768,7 +756,16 @@ class AiBuilderTools(ToolBase):
|
|
|
768
756
|
lambda: self._facade.app_read_fields(profile=profile, app_key=app_key),
|
|
769
757
|
error_code="FIELDS_READ_FAILED",
|
|
770
758
|
normalized_args=normalized_args,
|
|
771
|
-
suggested_next_call={"tool_name": "
|
|
759
|
+
suggested_next_call={"tool_name": "app_get_fields", "arguments": {"profile": profile, "app_key": app_key}},
|
|
760
|
+
)
|
|
761
|
+
|
|
762
|
+
def app_get_fields(self, *, profile: str, app_key: str) -> JSONObject:
|
|
763
|
+
normalized_args = {"app_key": app_key}
|
|
764
|
+
return _safe_tool_call(
|
|
765
|
+
lambda: self._facade.app_get_fields(profile=profile, app_key=app_key),
|
|
766
|
+
error_code="APP_GET_FIELDS_FAILED",
|
|
767
|
+
normalized_args=normalized_args,
|
|
768
|
+
suggested_next_call={"tool_name": "app_get_fields", "arguments": {"profile": profile, "app_key": app_key}},
|
|
772
769
|
)
|
|
773
770
|
|
|
774
771
|
def app_read_layout_summary(self, *, profile: str, app_key: str) -> JSONObject:
|
|
@@ -777,7 +774,16 @@ class AiBuilderTools(ToolBase):
|
|
|
777
774
|
lambda: self._facade.app_read_layout_summary(profile=profile, app_key=app_key),
|
|
778
775
|
error_code="LAYOUT_READ_FAILED",
|
|
779
776
|
normalized_args=normalized_args,
|
|
780
|
-
suggested_next_call={"tool_name": "
|
|
777
|
+
suggested_next_call={"tool_name": "app_get_layout", "arguments": {"profile": profile, "app_key": app_key}},
|
|
778
|
+
)
|
|
779
|
+
|
|
780
|
+
def app_get_layout(self, *, profile: str, app_key: str) -> JSONObject:
|
|
781
|
+
normalized_args = {"app_key": app_key}
|
|
782
|
+
return _safe_tool_call(
|
|
783
|
+
lambda: self._facade.app_get_layout(profile=profile, app_key=app_key),
|
|
784
|
+
error_code="APP_GET_LAYOUT_FAILED",
|
|
785
|
+
normalized_args=normalized_args,
|
|
786
|
+
suggested_next_call={"tool_name": "app_get_layout", "arguments": {"profile": profile, "app_key": app_key}},
|
|
781
787
|
)
|
|
782
788
|
|
|
783
789
|
def app_read_views_summary(self, *, profile: str, app_key: str) -> JSONObject:
|
|
@@ -786,7 +792,16 @@ class AiBuilderTools(ToolBase):
|
|
|
786
792
|
lambda: self._facade.app_read_views_summary(profile=profile, app_key=app_key),
|
|
787
793
|
error_code="VIEWS_READ_FAILED",
|
|
788
794
|
normalized_args=normalized_args,
|
|
789
|
-
suggested_next_call={"tool_name": "
|
|
795
|
+
suggested_next_call={"tool_name": "app_get_views", "arguments": {"profile": profile, "app_key": app_key}},
|
|
796
|
+
)
|
|
797
|
+
|
|
798
|
+
def app_get_views(self, *, profile: str, app_key: str) -> JSONObject:
|
|
799
|
+
normalized_args = {"app_key": app_key}
|
|
800
|
+
return _safe_tool_call(
|
|
801
|
+
lambda: self._facade.app_get_views(profile=profile, app_key=app_key),
|
|
802
|
+
error_code="APP_GET_VIEWS_FAILED",
|
|
803
|
+
normalized_args=normalized_args,
|
|
804
|
+
suggested_next_call={"tool_name": "app_get_views", "arguments": {"profile": profile, "app_key": app_key}},
|
|
790
805
|
)
|
|
791
806
|
|
|
792
807
|
def app_read_flow_summary(self, *, profile: str, app_key: str) -> JSONObject:
|
|
@@ -795,7 +810,16 @@ class AiBuilderTools(ToolBase):
|
|
|
795
810
|
lambda: self._facade.app_read_flow_summary(profile=profile, app_key=app_key),
|
|
796
811
|
error_code="FLOW_READ_FAILED",
|
|
797
812
|
normalized_args=normalized_args,
|
|
798
|
-
suggested_next_call={"tool_name": "
|
|
813
|
+
suggested_next_call={"tool_name": "app_get_flow", "arguments": {"profile": profile, "app_key": app_key}},
|
|
814
|
+
)
|
|
815
|
+
|
|
816
|
+
def app_get_flow(self, *, profile: str, app_key: str) -> JSONObject:
|
|
817
|
+
normalized_args = {"app_key": app_key}
|
|
818
|
+
return _safe_tool_call(
|
|
819
|
+
lambda: self._facade.app_get_flow(profile=profile, app_key=app_key),
|
|
820
|
+
error_code="APP_GET_FLOW_FAILED",
|
|
821
|
+
normalized_args=normalized_args,
|
|
822
|
+
suggested_next_call={"tool_name": "app_get_flow", "arguments": {"profile": profile, "app_key": app_key}},
|
|
799
823
|
)
|
|
800
824
|
|
|
801
825
|
def app_read_charts_summary(self, *, profile: str, app_key: str) -> JSONObject:
|
|
@@ -804,7 +828,16 @@ class AiBuilderTools(ToolBase):
|
|
|
804
828
|
lambda: self._facade.app_read_charts_summary(profile=profile, app_key=app_key),
|
|
805
829
|
error_code="CHARTS_READ_FAILED",
|
|
806
830
|
normalized_args=normalized_args,
|
|
807
|
-
suggested_next_call={"tool_name": "
|
|
831
|
+
suggested_next_call={"tool_name": "app_get_charts", "arguments": {"profile": profile, "app_key": app_key}},
|
|
832
|
+
)
|
|
833
|
+
|
|
834
|
+
def app_get_charts(self, *, profile: str, app_key: str) -> JSONObject:
|
|
835
|
+
normalized_args = {"app_key": app_key}
|
|
836
|
+
return _safe_tool_call(
|
|
837
|
+
lambda: self._facade.app_get_charts(profile=profile, app_key=app_key),
|
|
838
|
+
error_code="APP_GET_CHARTS_FAILED",
|
|
839
|
+
normalized_args=normalized_args,
|
|
840
|
+
suggested_next_call={"tool_name": "app_get_charts", "arguments": {"profile": profile, "app_key": app_key}},
|
|
808
841
|
)
|
|
809
842
|
|
|
810
843
|
def portal_list(self, *, profile: str) -> JSONObject:
|
|
@@ -830,13 +863,14 @@ class AiBuilderTools(ToolBase):
|
|
|
830
863
|
lambda: self._facade.portal_read_summary(profile=profile, dash_key=dash_key, being_draft=being_draft),
|
|
831
864
|
error_code="PORTAL_READ_FAILED",
|
|
832
865
|
normalized_args=normalized_args,
|
|
833
|
-
suggested_next_call={"tool_name": "
|
|
866
|
+
suggested_next_call={"tool_name": "portal_get", "arguments": {"profile": profile, **normalized_args}},
|
|
834
867
|
)
|
|
835
868
|
|
|
836
|
-
def view_get(self, *, profile: str, viewgraph_key: str) -> JSONObject:
|
|
837
|
-
|
|
869
|
+
def view_get(self, *, profile: str, view_key: str = "", viewgraph_key: str = "") -> JSONObject:
|
|
870
|
+
resolved_view_key = str(view_key or viewgraph_key or "").strip()
|
|
871
|
+
normalized_args = {"view_key": resolved_view_key}
|
|
838
872
|
return _safe_tool_call(
|
|
839
|
-
lambda: self._facade.view_get(profile=profile,
|
|
873
|
+
lambda: self._facade.view_get(profile=profile, view_key=resolved_view_key),
|
|
840
874
|
error_code="VIEW_GET_FAILED",
|
|
841
875
|
normalized_args=normalized_args,
|
|
842
876
|
suggested_next_call={"tool_name": "view_get", "arguments": {"profile": profile, **normalized_args}},
|
|
@@ -847,30 +881,10 @@ class AiBuilderTools(ToolBase):
|
|
|
847
881
|
*,
|
|
848
882
|
profile: str,
|
|
849
883
|
chart_id: str,
|
|
850
|
-
data_payload: JSONObject | None = None,
|
|
851
|
-
page_num: int | None = None,
|
|
852
|
-
page_size: int | None = None,
|
|
853
|
-
page_num_y: int | None = None,
|
|
854
|
-
page_size_y: int | None = None,
|
|
855
884
|
) -> JSONObject:
|
|
856
|
-
normalized_args = {
|
|
857
|
-
"chart_id": chart_id,
|
|
858
|
-
"data_payload": deepcopy(data_payload) if isinstance(data_payload, dict) else {},
|
|
859
|
-
"page_num": page_num,
|
|
860
|
-
"page_size": page_size,
|
|
861
|
-
"page_num_y": page_num_y,
|
|
862
|
-
"page_size_y": page_size_y,
|
|
863
|
-
}
|
|
885
|
+
normalized_args = {"chart_id": chart_id}
|
|
864
886
|
return _safe_tool_call(
|
|
865
|
-
lambda: self._facade.chart_get(
|
|
866
|
-
profile=profile,
|
|
867
|
-
chart_id=chart_id,
|
|
868
|
-
data_payload=normalized_args["data_payload"],
|
|
869
|
-
page_num=page_num,
|
|
870
|
-
page_size=page_size,
|
|
871
|
-
page_num_y=page_num_y,
|
|
872
|
-
page_size_y=page_size_y,
|
|
873
|
-
),
|
|
887
|
+
lambda: self._facade.chart_get(profile=profile, chart_id=chart_id),
|
|
874
888
|
error_code="CHART_GET_FAILED",
|
|
875
889
|
normalized_args=normalized_args,
|
|
876
890
|
suggested_next_call={"tool_name": "chart_get", "arguments": {"profile": profile, "chart_id": chart_id}},
|
|
@@ -1903,6 +1917,50 @@ def _public_error_message(error_code: str, error: QingflowApiError) -> str:
|
|
|
1903
1917
|
|
|
1904
1918
|
|
|
1905
1919
|
_BUILDER_TOOL_CONTRACTS: dict[str, JSONObject] = {
|
|
1920
|
+
"file_upload_local": {
|
|
1921
|
+
"allowed_keys": ["upload_kind", "file_path", "upload_mark", "content_type", "bucket_type", "path_id", "file_related_url"],
|
|
1922
|
+
"aliases": {},
|
|
1923
|
+
"allowed_values": {"upload_kind": ["attachment", "login"]},
|
|
1924
|
+
"execution_notes": [
|
|
1925
|
+
"returns upload metadata plus attachment-ready values for later builder or user writes",
|
|
1926
|
+
"upload_kind=attachment may fall back to login upload info when the backend rejects attachment upload info",
|
|
1927
|
+
"upload_mark is recommended for attachment uploads because it affects the remote storage path",
|
|
1928
|
+
],
|
|
1929
|
+
"minimal_example": {
|
|
1930
|
+
"profile": "default",
|
|
1931
|
+
"upload_kind": "attachment",
|
|
1932
|
+
"file_path": "/absolute/path/to/local-file.txt",
|
|
1933
|
+
"upload_mark": "APP_KEY",
|
|
1934
|
+
},
|
|
1935
|
+
},
|
|
1936
|
+
"feedback_submit": {
|
|
1937
|
+
"allowed_keys": [
|
|
1938
|
+
"category",
|
|
1939
|
+
"title",
|
|
1940
|
+
"description",
|
|
1941
|
+
"expected_behavior",
|
|
1942
|
+
"actual_behavior",
|
|
1943
|
+
"impact_scope",
|
|
1944
|
+
"tool_name",
|
|
1945
|
+
"app_key",
|
|
1946
|
+
"record_id",
|
|
1947
|
+
"workflow_node_id",
|
|
1948
|
+
"note",
|
|
1949
|
+
],
|
|
1950
|
+
"aliases": {},
|
|
1951
|
+
"allowed_values": {"category": ["bug", "missing_capability", "awkward_workflow", "ux", "docs"]},
|
|
1952
|
+
"execution_notes": [
|
|
1953
|
+
"submit feedback only after explicit user confirmation",
|
|
1954
|
+
"use this when the current builder capability is unsupported or awkward after reasonable attempts",
|
|
1955
|
+
"requires feedback qsource configuration but does not require Qingflow login or workspace selection",
|
|
1956
|
+
],
|
|
1957
|
+
"minimal_example": {
|
|
1958
|
+
"category": "missing_capability",
|
|
1959
|
+
"title": "builder chart data read gap",
|
|
1960
|
+
"description": "The current builder capability cannot satisfy the requested workflow.",
|
|
1961
|
+
"tool_name": "chart_get",
|
|
1962
|
+
},
|
|
1963
|
+
},
|
|
1906
1964
|
"package_list": {
|
|
1907
1965
|
"allowed_keys": ["trial_status"],
|
|
1908
1966
|
"aliases": {"trialStatus": "trial_status"},
|
|
@@ -2005,6 +2063,22 @@ _BUILDER_TOOL_CONTRACTS: dict[str, JSONObject] = {
|
|
|
2005
2063
|
"package_tag_id": 1001,
|
|
2006
2064
|
},
|
|
2007
2065
|
},
|
|
2066
|
+
"app_release_edit_lock_if_mine": {
|
|
2067
|
+
"allowed_keys": ["app_key", "lock_owner_email", "lock_owner_name"],
|
|
2068
|
+
"aliases": {},
|
|
2069
|
+
"allowed_values": {},
|
|
2070
|
+
"execution_notes": [
|
|
2071
|
+
"use this only after a builder write fails with APP_EDIT_LOCKED and the lock belongs to the current user",
|
|
2072
|
+
"supply the lock owner details from the failed write result for a safe release attempt",
|
|
2073
|
+
"after a successful release, retry the blocked builder write or publish verification call",
|
|
2074
|
+
],
|
|
2075
|
+
"minimal_example": {
|
|
2076
|
+
"profile": "default",
|
|
2077
|
+
"app_key": "APP_KEY",
|
|
2078
|
+
"lock_owner_email": "user@example.com",
|
|
2079
|
+
"lock_owner_name": "当前用户",
|
|
2080
|
+
},
|
|
2081
|
+
},
|
|
2008
2082
|
"app_custom_button_list": {
|
|
2009
2083
|
"allowed_keys": ["app_key"],
|
|
2010
2084
|
"aliases": {},
|
|
@@ -2461,6 +2535,9 @@ _BUILDER_TOOL_CONTRACTS: dict[str, JSONObject] = {
|
|
|
2461
2535
|
"view.buttons.button_type": ["SYSTEM", "CUSTOM"],
|
|
2462
2536
|
"view.buttons.config_type": ["TOP", "DETAIL"],
|
|
2463
2537
|
},
|
|
2538
|
+
"execution_notes": [
|
|
2539
|
+
"for multi-value operators such as in, pass values as a list; value may also be used as an alias when it already contains a list",
|
|
2540
|
+
],
|
|
2464
2541
|
"minimal_example": {
|
|
2465
2542
|
"profile": "default",
|
|
2466
2543
|
"app_key": "APP_KEY",
|
|
@@ -2517,9 +2594,10 @@ _BUILDER_TOOL_CONTRACTS: dict[str, JSONObject] = {
|
|
|
2517
2594
|
"execution_notes": [
|
|
2518
2595
|
"apply may return partial_success when some views land and others fail",
|
|
2519
2596
|
"when duplicate view names exist, supply view_key to target the exact view",
|
|
2520
|
-
"read back
|
|
2597
|
+
"read back app_get_views after any failed or partial view apply",
|
|
2521
2598
|
"view existence verification and saved-filter verification are separate; treat filters as unverified until verification.view_filters_verified is true",
|
|
2522
2599
|
"buttons omitted preserves existing button config; buttons=[] clears all buttons; buttons=[...] replaces the full button config",
|
|
2600
|
+
"for multi-value operators such as in, pass values as a list; value may also be used as an alias when it already contains a list",
|
|
2523
2601
|
],
|
|
2524
2602
|
"minimal_example": {
|
|
2525
2603
|
"profile": "default",
|
|
@@ -2546,7 +2624,73 @@ _BUILDER_TOOL_CONTRACTS: dict[str, JSONObject] = {
|
|
|
2546
2624
|
"remove_views": [],
|
|
2547
2625
|
},
|
|
2548
2626
|
},
|
|
2549
|
-
"
|
|
2627
|
+
"app_get": {
|
|
2628
|
+
"allowed_keys": ["app_key"],
|
|
2629
|
+
"aliases": {},
|
|
2630
|
+
"allowed_values": {},
|
|
2631
|
+
"execution_notes": [
|
|
2632
|
+
"returns builder-side app configuration summary and editability",
|
|
2633
|
+
"use this as the default builder discovery read before fields/layout/views/flow/charts detail reads",
|
|
2634
|
+
"editability reflects builder permissions, not end-user data visibility",
|
|
2635
|
+
],
|
|
2636
|
+
"minimal_example": {
|
|
2637
|
+
"profile": "default",
|
|
2638
|
+
"app_key": "APP_KEY",
|
|
2639
|
+
},
|
|
2640
|
+
},
|
|
2641
|
+
"app_get_fields": {
|
|
2642
|
+
"allowed_keys": ["app_key"],
|
|
2643
|
+
"aliases": {},
|
|
2644
|
+
"allowed_values": {},
|
|
2645
|
+
"execution_notes": [
|
|
2646
|
+
"returns compact current field configuration for one app",
|
|
2647
|
+
"use this before app_schema_apply when you need exact field definitions",
|
|
2648
|
+
],
|
|
2649
|
+
"minimal_example": {
|
|
2650
|
+
"profile": "default",
|
|
2651
|
+
"app_key": "APP_KEY",
|
|
2652
|
+
},
|
|
2653
|
+
},
|
|
2654
|
+
"app_get_layout": {
|
|
2655
|
+
"allowed_keys": ["app_key"],
|
|
2656
|
+
"aliases": {},
|
|
2657
|
+
"allowed_values": {},
|
|
2658
|
+
"execution_notes": [
|
|
2659
|
+
"returns compact current layout configuration for one app",
|
|
2660
|
+
"use this before app_layout_apply when you need paragraph and row structure",
|
|
2661
|
+
],
|
|
2662
|
+
"minimal_example": {
|
|
2663
|
+
"profile": "default",
|
|
2664
|
+
"app_key": "APP_KEY",
|
|
2665
|
+
},
|
|
2666
|
+
},
|
|
2667
|
+
"app_get_views": {
|
|
2668
|
+
"allowed_keys": ["app_key"],
|
|
2669
|
+
"aliases": {},
|
|
2670
|
+
"allowed_values": {},
|
|
2671
|
+
"execution_notes": [
|
|
2672
|
+
"returns compact current view inventory for one app",
|
|
2673
|
+
"use this before app_views_apply when you need exact current view keys",
|
|
2674
|
+
],
|
|
2675
|
+
"minimal_example": {
|
|
2676
|
+
"profile": "default",
|
|
2677
|
+
"app_key": "APP_KEY",
|
|
2678
|
+
},
|
|
2679
|
+
},
|
|
2680
|
+
"app_get_flow": {
|
|
2681
|
+
"allowed_keys": ["app_key"],
|
|
2682
|
+
"aliases": {},
|
|
2683
|
+
"allowed_values": {},
|
|
2684
|
+
"execution_notes": [
|
|
2685
|
+
"returns workflow configuration summary for one app",
|
|
2686
|
+
"use this before app_flow_apply when you need the current node structure",
|
|
2687
|
+
],
|
|
2688
|
+
"minimal_example": {
|
|
2689
|
+
"profile": "default",
|
|
2690
|
+
"app_key": "APP_KEY",
|
|
2691
|
+
},
|
|
2692
|
+
},
|
|
2693
|
+
"app_get_charts": {
|
|
2550
2694
|
"allowed_keys": ["app_key"],
|
|
2551
2695
|
"aliases": {},
|
|
2552
2696
|
"allowed_values": {},
|
|
@@ -2565,8 +2709,8 @@ _BUILDER_TOOL_CONTRACTS: dict[str, JSONObject] = {
|
|
|
2565
2709
|
"aliases": {},
|
|
2566
2710
|
"allowed_values": {},
|
|
2567
2711
|
"execution_notes": [
|
|
2568
|
-
"returns
|
|
2569
|
-
"use this as the portal discovery path before portal_get",
|
|
2712
|
+
"returns builder-configurable portal list items only",
|
|
2713
|
+
"use this as the builder portal discovery path before portal_get",
|
|
2570
2714
|
"results are compact list items, not raw dash payloads",
|
|
2571
2715
|
],
|
|
2572
2716
|
"minimal_example": {
|
|
@@ -2578,8 +2722,8 @@ _BUILDER_TOOL_CONTRACTS: dict[str, JSONObject] = {
|
|
|
2578
2722
|
"aliases": {"beingDraft": "being_draft"},
|
|
2579
2723
|
"allowed_values": {},
|
|
2580
2724
|
"execution_notes": [
|
|
2581
|
-
"returns
|
|
2582
|
-
"chart and view components are returned as refs only; use chart_get or view_get for
|
|
2725
|
+
"returns builder-side portal configuration detail plus a normalized component inventory",
|
|
2726
|
+
"chart and view components are returned as refs only; use builder chart_get or builder view_get for configuration detail",
|
|
2583
2727
|
"being_draft=true reads the current draft view; being_draft=false reads live",
|
|
2584
2728
|
],
|
|
2585
2729
|
"minimal_example": {
|
|
@@ -2616,69 +2760,32 @@ _BUILDER_TOOL_CONTRACTS: dict[str, JSONObject] = {
|
|
|
2616
2760
|
"reorder_chart_ids": [],
|
|
2617
2761
|
},
|
|
2618
2762
|
},
|
|
2619
|
-
"chart_apply": {
|
|
2620
|
-
"allowed_keys": ["app_key", "upsert_charts", "remove_chart_ids", "reorder_chart_ids"],
|
|
2621
|
-
"aliases": {
|
|
2622
|
-
"legacy_tool_name": "app_charts_apply",
|
|
2623
|
-
},
|
|
2624
|
-
"allowed_values": {
|
|
2625
|
-
"chart.chart_type": [member.value for member in PublicChartType],
|
|
2626
|
-
"chart.filter.operator": [member.value for member in ViewFilterOperator],
|
|
2627
|
-
},
|
|
2628
|
-
"execution_notes": [
|
|
2629
|
-
"legacy compatibility alias; prefer app_charts_apply in new builder flows",
|
|
2630
|
-
"behavior matches app_charts_apply exactly",
|
|
2631
|
-
],
|
|
2632
|
-
"minimal_example": {
|
|
2633
|
-
"profile": "default",
|
|
2634
|
-
"app_key": "APP_KEY",
|
|
2635
|
-
"upsert_charts": [{"name": "数据总量", "chart_type": "target", "indicator_field_ids": []}],
|
|
2636
|
-
"remove_chart_ids": [],
|
|
2637
|
-
"reorder_chart_ids": [],
|
|
2638
|
-
},
|
|
2639
|
-
},
|
|
2640
|
-
"portal_read_summary": {
|
|
2641
|
-
"allowed_keys": ["dash_key", "being_draft"],
|
|
2642
|
-
"aliases": {"beingDraft": "being_draft"},
|
|
2643
|
-
"allowed_values": {},
|
|
2644
|
-
"execution_notes": [
|
|
2645
|
-
"returns a compact portal summary instead of the raw dash payload",
|
|
2646
|
-
"being_draft=true reads the current draft view; being_draft=false reads live",
|
|
2647
|
-
"use this before portal_apply when you need the current section inventory or target dash metadata",
|
|
2648
|
-
],
|
|
2649
|
-
"minimal_example": {
|
|
2650
|
-
"profile": "default",
|
|
2651
|
-
"dash_key": "DASH_KEY",
|
|
2652
|
-
"being_draft": True,
|
|
2653
|
-
},
|
|
2654
|
-
},
|
|
2655
2763
|
"view_get": {
|
|
2656
|
-
"allowed_keys": ["
|
|
2657
|
-
"aliases": {
|
|
2764
|
+
"allowed_keys": ["view_key"],
|
|
2765
|
+
"aliases": {},
|
|
2658
2766
|
"allowed_values": {},
|
|
2659
2767
|
"execution_notes": [
|
|
2660
|
-
"returns one view
|
|
2661
|
-
"does not return record data; use
|
|
2662
|
-
"use this after portal_get when a component references a view_ref.view_key",
|
|
2768
|
+
"returns one builder-side view definition detail",
|
|
2769
|
+
"does not return record data; use user-side view_get or record_list for runtime rows",
|
|
2770
|
+
"use this after builder portal_get when a component references a view_ref.view_key",
|
|
2663
2771
|
],
|
|
2664
2772
|
"minimal_example": {
|
|
2665
2773
|
"profile": "default",
|
|
2666
|
-
"
|
|
2774
|
+
"view_key": "VIEW_KEY",
|
|
2667
2775
|
},
|
|
2668
2776
|
},
|
|
2669
2777
|
"chart_get": {
|
|
2670
|
-
"allowed_keys": ["chart_id"
|
|
2671
|
-
"aliases": {
|
|
2778
|
+
"allowed_keys": ["chart_id"],
|
|
2779
|
+
"aliases": {},
|
|
2672
2780
|
"allowed_values": {},
|
|
2673
2781
|
"execution_notes": [
|
|
2674
|
-
"returns chart base info
|
|
2782
|
+
"returns builder-side chart base info and chart config only",
|
|
2675
2783
|
"chart_id is required; chart names are not accepted here",
|
|
2676
|
-
"
|
|
2784
|
+
"does not return chart data; use user-side chart_get for runtime data access",
|
|
2677
2785
|
],
|
|
2678
2786
|
"minimal_example": {
|
|
2679
2787
|
"profile": "default",
|
|
2680
2788
|
"chart_id": "CHART_ID",
|
|
2681
|
-
"data_payload": {},
|
|
2682
2789
|
},
|
|
2683
2790
|
},
|
|
2684
2791
|
"portal_apply": {
|
|
@@ -2736,6 +2843,21 @@ _BUILDER_TOOL_CONTRACTS: dict[str, JSONObject] = {
|
|
|
2736
2843
|
},
|
|
2737
2844
|
},
|
|
2738
2845
|
},
|
|
2846
|
+
"app_publish_verify": {
|
|
2847
|
+
"allowed_keys": ["app_key", "expected_package_tag_id"],
|
|
2848
|
+
"aliases": {},
|
|
2849
|
+
"allowed_values": {},
|
|
2850
|
+
"execution_notes": [
|
|
2851
|
+
"verifies that the current app draft has been published and is readable through the builder surface",
|
|
2852
|
+
"expected_package_tag_id is optional and adds an extra package consistency check",
|
|
2853
|
+
"when verification fails because of an edit lock owned by the current user, retry after app_release_edit_lock_if_mine",
|
|
2854
|
+
],
|
|
2855
|
+
"minimal_example": {
|
|
2856
|
+
"profile": "default",
|
|
2857
|
+
"app_key": "APP_KEY",
|
|
2858
|
+
"expected_package_tag_id": 1001,
|
|
2859
|
+
},
|
|
2860
|
+
},
|
|
2739
2861
|
}
|
|
2740
2862
|
|
|
2741
2863
|
_PRIVATE_BUILDER_TOOL_CONTRACTS = {
|
|
@@ -2745,6 +2867,4 @@ _PRIVATE_BUILDER_TOOL_CONTRACTS = {
|
|
|
2745
2867
|
"app_views_plan",
|
|
2746
2868
|
}
|
|
2747
2869
|
|
|
2748
|
-
_BUILDER_TOOL_CONTRACT_ALIASES = {
|
|
2749
|
-
"chart_apply": "app_charts_apply",
|
|
2750
|
-
}
|
|
2870
|
+
_BUILDER_TOOL_CONTRACT_ALIASES = {}
|
|
@@ -179,9 +179,6 @@ class AppTools(ToolBase):
|
|
|
179
179
|
accessible_views.extend(self._resolve_accessible_custom_views(context, app_key))
|
|
180
180
|
import_capability, import_warnings = _derive_import_capability(base_info)
|
|
181
181
|
warnings.extend(import_warnings)
|
|
182
|
-
editability, editability_warnings = _derive_editability(base_info)
|
|
183
|
-
warnings.extend(editability_warnings)
|
|
184
|
-
|
|
185
182
|
return {
|
|
186
183
|
"profile": profile,
|
|
187
184
|
"ws_id": session_profile.selected_ws_id,
|
|
@@ -193,7 +190,6 @@ class AppTools(ToolBase):
|
|
|
193
190
|
"app_name": app_name,
|
|
194
191
|
"can_create": can_create,
|
|
195
192
|
"import_capability": import_capability,
|
|
196
|
-
"editability": editability,
|
|
197
193
|
"accessible_views": accessible_views,
|
|
198
194
|
},
|
|
199
195
|
}
|