@josephyan/qingflow-app-builder-mcp 0.2.0-beta.3 → 0.2.0-beta.4
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
CHANGED
|
@@ -3,13 +3,13 @@
|
|
|
3
3
|
Install:
|
|
4
4
|
|
|
5
5
|
```bash
|
|
6
|
-
npm install @josephyan/qingflow-app-builder-mcp@0.2.0-beta.
|
|
6
|
+
npm install @josephyan/qingflow-app-builder-mcp@0.2.0-beta.4
|
|
7
7
|
```
|
|
8
8
|
|
|
9
9
|
Run:
|
|
10
10
|
|
|
11
11
|
```bash
|
|
12
|
-
npx -y -p @josephyan/qingflow-app-builder-mcp@0.2.0-beta.
|
|
12
|
+
npx -y -p @josephyan/qingflow-app-builder-mcp@0.2.0-beta.4 qingflow-app-builder-mcp
|
|
13
13
|
```
|
|
14
14
|
|
|
15
15
|
Environment:
|
package/package.json
CHANGED
package/pyproject.toml
CHANGED
|
@@ -762,16 +762,7 @@ class AiBuilderFacade:
|
|
|
762
762
|
app_name=str(resolved["app_name"]),
|
|
763
763
|
tag_ids=_coerce_int_list(resolved.get("tag_ids")),
|
|
764
764
|
)
|
|
765
|
-
|
|
766
|
-
profile=profile,
|
|
767
|
-
app_key=target.app_key,
|
|
768
|
-
form_type=1,
|
|
769
|
-
being_draft=True,
|
|
770
|
-
being_apply=None,
|
|
771
|
-
audit_node_id=None,
|
|
772
|
-
include_raw=True,
|
|
773
|
-
)
|
|
774
|
-
schema_result = schema.get("result") if isinstance(schema.get("result"), dict) else {}
|
|
765
|
+
schema_result, _schema_source = self._read_schema_with_fallback(profile=profile, app_key=target.app_key)
|
|
775
766
|
parsed = _parse_schema(schema_result)
|
|
776
767
|
current_fields = parsed["fields"]
|
|
777
768
|
layout = parsed["layout"]
|
|
@@ -938,16 +929,7 @@ class AiBuilderFacade:
|
|
|
938
929
|
"sections": [section.model_dump(mode="json") for section in sections],
|
|
939
930
|
"publish": publish,
|
|
940
931
|
}
|
|
941
|
-
|
|
942
|
-
profile=profile,
|
|
943
|
-
app_key=app_key,
|
|
944
|
-
form_type=1,
|
|
945
|
-
being_draft=True,
|
|
946
|
-
being_apply=None,
|
|
947
|
-
audit_node_id=None,
|
|
948
|
-
include_raw=True,
|
|
949
|
-
)
|
|
950
|
-
schema_result = schema.get("result") if isinstance(schema.get("result"), dict) else {}
|
|
932
|
+
schema_result, _schema_source = self._read_schema_with_fallback(profile=profile, app_key=app_key)
|
|
951
933
|
parsed = _parse_schema(schema_result)
|
|
952
934
|
current_fields = parsed["fields"]
|
|
953
935
|
fields_by_name = {field["name"]: field for field in current_fields}
|
|
@@ -1130,15 +1112,7 @@ class AiBuilderFacade:
|
|
|
1130
1112
|
suggested_next_call={"tool_name": "app_flow_plan", "arguments": {"profile": profile, **normalized_args}},
|
|
1131
1113
|
)
|
|
1132
1114
|
base = self.apps.app_get_base(profile=profile, app_key=app_key, include_raw=True).get("result") or {}
|
|
1133
|
-
schema = self.
|
|
1134
|
-
profile=profile,
|
|
1135
|
-
app_key=app_key,
|
|
1136
|
-
form_type=1,
|
|
1137
|
-
being_draft=True,
|
|
1138
|
-
being_apply=None,
|
|
1139
|
-
audit_node_id=None,
|
|
1140
|
-
include_raw=True,
|
|
1141
|
-
).get("result") or {}
|
|
1115
|
+
schema, _schema_source = self._read_schema_with_fallback(profile=profile, app_key=app_key)
|
|
1142
1116
|
entity = _entity_spec_from_app(base_info=base, schema=schema, views=None)
|
|
1143
1117
|
workflow_spec = _build_public_workflow_spec(nodes=nodes, transitions=transitions)
|
|
1144
1118
|
if workflow_spec.get("status") == "failed":
|
|
@@ -1246,15 +1220,7 @@ class AiBuilderFacade:
|
|
|
1246
1220
|
}
|
|
1247
1221
|
return self._append_publish_result(profile=profile, app_key=app_key, publish=publish, response=response)
|
|
1248
1222
|
base = self.apps.app_get_base(profile=profile, app_key=app_key, include_raw=True).get("result") or {}
|
|
1249
|
-
schema = self.
|
|
1250
|
-
profile=profile,
|
|
1251
|
-
app_key=app_key,
|
|
1252
|
-
form_type=1,
|
|
1253
|
-
being_draft=True,
|
|
1254
|
-
being_apply=None,
|
|
1255
|
-
audit_node_id=None,
|
|
1256
|
-
include_raw=True,
|
|
1257
|
-
).get("result") or {}
|
|
1223
|
+
schema, _schema_source = self._read_schema_with_fallback(profile=profile, app_key=app_key)
|
|
1258
1224
|
existing_views = self.views.view_list_flat(profile=profile, app_key=app_key).get("result") or []
|
|
1259
1225
|
existing_by_name = {}
|
|
1260
1226
|
for view in existing_views if isinstance(existing_views, list) else []:
|
|
@@ -1527,27 +1493,49 @@ class AiBuilderFacade:
|
|
|
1527
1493
|
|
|
1528
1494
|
def _load_app_state(self, *, profile: str, app_key: str) -> dict[str, Any]:
|
|
1529
1495
|
base = self.apps.app_get_base(profile=profile, app_key=app_key, include_raw=True)
|
|
1530
|
-
|
|
1531
|
-
profile=profile,
|
|
1532
|
-
app_key=app_key,
|
|
1533
|
-
form_type=1,
|
|
1534
|
-
being_draft=True,
|
|
1535
|
-
being_apply=None,
|
|
1536
|
-
audit_node_id=None,
|
|
1537
|
-
include_raw=True,
|
|
1538
|
-
)
|
|
1496
|
+
schema_result, schema_source = self._read_schema_with_fallback(profile=profile, app_key=app_key)
|
|
1539
1497
|
views = self.views.view_list_flat(profile=profile, app_key=app_key)
|
|
1540
1498
|
workflow = self.workflows.workflow_list_nodes(profile=profile, app_key=app_key)
|
|
1541
1499
|
base_result = base.get("result") if isinstance(base.get("result"), dict) else {}
|
|
1542
|
-
schema_result = schema.get("result") if isinstance(schema.get("result"), dict) else {}
|
|
1543
1500
|
return {
|
|
1544
1501
|
"base": base_result,
|
|
1545
1502
|
"schema": schema_result,
|
|
1546
1503
|
"parsed": _parse_schema(schema_result),
|
|
1547
1504
|
"views": views.get("result"),
|
|
1548
1505
|
"workflow": workflow.get("result"),
|
|
1506
|
+
"schema_source": schema_source,
|
|
1549
1507
|
}
|
|
1550
1508
|
|
|
1509
|
+
def _read_schema_with_fallback(self, *, profile: str, app_key: str) -> tuple[dict[str, Any], str]:
|
|
1510
|
+
attempts = (
|
|
1511
|
+
("draft", True),
|
|
1512
|
+
("current", None),
|
|
1513
|
+
("published", False),
|
|
1514
|
+
)
|
|
1515
|
+
last_error: Exception | None = None
|
|
1516
|
+
for label, being_draft in attempts:
|
|
1517
|
+
try:
|
|
1518
|
+
schema = self.apps.app_get_form_schema(
|
|
1519
|
+
profile=profile,
|
|
1520
|
+
app_key=app_key,
|
|
1521
|
+
form_type=1,
|
|
1522
|
+
being_draft=being_draft,
|
|
1523
|
+
being_apply=None,
|
|
1524
|
+
audit_node_id=None,
|
|
1525
|
+
include_raw=True,
|
|
1526
|
+
)
|
|
1527
|
+
result = schema.get("result")
|
|
1528
|
+
return (result if isinstance(result, dict) else {}), label
|
|
1529
|
+
except (QingflowApiError, RuntimeError) as error:
|
|
1530
|
+
api_error = _coerce_api_error(error)
|
|
1531
|
+
last_error = error
|
|
1532
|
+
if api_error.http_status == 404:
|
|
1533
|
+
continue
|
|
1534
|
+
raise
|
|
1535
|
+
if last_error is not None:
|
|
1536
|
+
raise last_error
|
|
1537
|
+
return {}, "unknown"
|
|
1538
|
+
|
|
1551
1539
|
def _preview_target_app(
|
|
1552
1540
|
self,
|
|
1553
1541
|
*,
|