@josephyan/qingflow-cli 0.2.0-beta.985 → 0.2.0-beta.987
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/docs/local-agent-install.md +70 -11
- 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 +376 -19
- package/src/qingflow_mcp/cli/commands/auth.py +14 -43
- package/src/qingflow_mcp/cli/commands/workspace.py +8 -5
- package/src/qingflow_mcp/cli/formatters.py +19 -22
- package/src/qingflow_mcp/config.py +39 -0
- package/src/qingflow_mcp/errors.py +2 -2
- package/src/qingflow_mcp/public_surface.py +4 -6
- package/src/qingflow_mcp/response_trim.py +1 -8
- package/src/qingflow_mcp/server.py +1 -1
- package/src/qingflow_mcp/server_app_builder.py +4 -28
- package/src/qingflow_mcp/server_app_user.py +4 -28
- package/src/qingflow_mcp/session_store.py +31 -5
- package/src/qingflow_mcp/solution/compiler/form_compiler.py +2 -2
- package/src/qingflow_mcp/solution/executor.py +2 -2
- package/src/qingflow_mcp/tools/ai_builder_tools.py +117 -1
- package/src/qingflow_mcp/tools/app_tools.py +51 -1
- package/src/qingflow_mcp/tools/approval_tools.py +82 -1
- package/src/qingflow_mcp/tools/auth_tools.py +306 -288
- package/src/qingflow_mcp/tools/base.py +204 -4
- package/src/qingflow_mcp/tools/code_block_tools.py +21 -0
- package/src/qingflow_mcp/tools/custom_button_tools.py +24 -1
- package/src/qingflow_mcp/tools/directory_tools.py +28 -1
- package/src/qingflow_mcp/tools/feedback_tools.py +8 -0
- package/src/qingflow_mcp/tools/file_tools.py +25 -1
- package/src/qingflow_mcp/tools/import_tools.py +40 -1
- package/src/qingflow_mcp/tools/navigation_tools.py +34 -1
- package/src/qingflow_mcp/tools/package_tools.py +37 -1
- package/src/qingflow_mcp/tools/portal_tools.py +28 -1
- package/src/qingflow_mcp/tools/qingbi_report_tools.py +38 -1
- package/src/qingflow_mcp/tools/record_tools.py +255 -2
- package/src/qingflow_mcp/tools/repository_dev_tools.py +21 -2
- package/src/qingflow_mcp/tools/resource_read_tools.py +23 -1
- package/src/qingflow_mcp/tools/role_tools.py +19 -1
- package/src/qingflow_mcp/tools/solution_tools.py +56 -1
- package/src/qingflow_mcp/tools/task_context_tools.py +72 -1
- package/src/qingflow_mcp/tools/task_tools.py +49 -3
- package/src/qingflow_mcp/tools/view_tools.py +56 -1
- package/src/qingflow_mcp/tools/workflow_tools.py +65 -1
- package/src/qingflow_mcp/tools/workspace_tools.py +100 -217
|
@@ -19,7 +19,7 @@ from ..errors import QingflowApiError, raise_tool_error
|
|
|
19
19
|
from ..json_types import JSONObject, JSONValue
|
|
20
20
|
from ..repository_store import RepositoryMetadataStore
|
|
21
21
|
from ..session_store import SessionProfile
|
|
22
|
-
from .base import ToolBase
|
|
22
|
+
from .base import ToolBase, tool_cn_name
|
|
23
23
|
|
|
24
24
|
|
|
25
25
|
_STREAM_EVENT_RE = re.compile(r"^type=(?P<type>[^,]+),timestamp=(?P<timestamp>[^,]+),data=(?P<data>.*)$")
|
|
@@ -27,11 +27,23 @@ _STREAM_NEWLINE_TOKEN = "<wingsBr>"
|
|
|
27
27
|
|
|
28
28
|
|
|
29
29
|
class RepositoryDevTools(ToolBase):
|
|
30
|
+
"""仓库开发工具(中文名:仓库初始化与绑定)。
|
|
31
|
+
|
|
32
|
+
类型:开发辅助工具。
|
|
33
|
+
主要职责:
|
|
34
|
+
1. 初始化仓库开发元数据;
|
|
35
|
+
2. 维护仓库模板与分组映射;
|
|
36
|
+
3. 为 AI Builder 的仓库流程提供状态读写。
|
|
37
|
+
"""
|
|
38
|
+
|
|
30
39
|
def __init__(self, sessions, backend, *, metadata_store: RepositoryMetadataStore | None = None) -> None:
|
|
40
|
+
"""执行内部辅助逻辑。"""
|
|
31
41
|
super().__init__(sessions, backend)
|
|
32
42
|
self._metadata = metadata_store or RepositoryMetadataStore()
|
|
33
43
|
|
|
44
|
+
@tool_cn_name("仓库初始化")
|
|
34
45
|
def repository_init(self, *, profile: str, group_name: str, repo_template: str) -> JSONObject:
|
|
46
|
+
"""执行工具方法逻辑。"""
|
|
35
47
|
normalized_group = str(group_name or "").strip()
|
|
36
48
|
normalized_template = str(repo_template or "").strip()
|
|
37
49
|
if not normalized_group:
|
|
@@ -69,6 +81,7 @@ class RepositoryDevTools(ToolBase):
|
|
|
69
81
|
|
|
70
82
|
return self._run(profile, runner, require_workspace=True)
|
|
71
83
|
|
|
84
|
+
@tool_cn_name("仓库生成")
|
|
72
85
|
def repository_generate(
|
|
73
86
|
self,
|
|
74
87
|
*,
|
|
@@ -87,6 +100,7 @@ class RepositoryDevTools(ToolBase):
|
|
|
87
100
|
session_id: str | None = None,
|
|
88
101
|
round_version: int | None = None,
|
|
89
102
|
) -> JSONObject:
|
|
103
|
+
"""执行工具方法逻辑。"""
|
|
90
104
|
normalized_repo = str(repo_name or "").strip()
|
|
91
105
|
normalized_query = str(query or "").strip()
|
|
92
106
|
if not normalized_repo:
|
|
@@ -162,6 +176,7 @@ class RepositoryDevTools(ToolBase):
|
|
|
162
176
|
|
|
163
177
|
return self._run(profile, runner, require_workspace=True)
|
|
164
178
|
|
|
179
|
+
@tool_cn_name("仓库发布生产")
|
|
165
180
|
def repository_publish_prod(
|
|
166
181
|
self,
|
|
167
182
|
*,
|
|
@@ -169,6 +184,7 @@ class RepositoryDevTools(ToolBase):
|
|
|
169
184
|
repo_name: str,
|
|
170
185
|
confirm: bool = False,
|
|
171
186
|
) -> JSONObject:
|
|
187
|
+
"""执行工具方法逻辑。"""
|
|
172
188
|
normalized_repo = str(repo_name or "").strip()
|
|
173
189
|
if not normalized_repo:
|
|
174
190
|
raise_tool_error(QingflowApiError.config_error("repo_name is required"))
|
|
@@ -200,6 +216,7 @@ class RepositoryDevTools(ToolBase):
|
|
|
200
216
|
return self._run(profile, runner, require_workspace=True)
|
|
201
217
|
|
|
202
218
|
def _custom_page_route_warning(self) -> list[JSONObject]:
|
|
219
|
+
"""执行内部辅助逻辑。"""
|
|
203
220
|
if get_repository_internal_base_url() and get_repository_internal_share_token():
|
|
204
221
|
return []
|
|
205
222
|
return [
|
|
@@ -223,6 +240,7 @@ class RepositoryDevTools(ToolBase):
|
|
|
223
240
|
params: JSONObject | None = None,
|
|
224
241
|
json_body: JSONValue = None,
|
|
225
242
|
) -> JSONValue:
|
|
243
|
+
"""执行内部辅助逻辑。"""
|
|
226
244
|
internal_route = _resolve_internal_custom_page_route(session_profile)
|
|
227
245
|
if internal_route is not None:
|
|
228
246
|
return self.backend.public_request_with_headers(
|
|
@@ -246,6 +264,7 @@ class RepositoryDevTools(ToolBase):
|
|
|
246
264
|
params: JSONObject | None = None,
|
|
247
265
|
json_body: JSONValue = None,
|
|
248
266
|
) -> list[str]:
|
|
267
|
+
"""执行内部辅助逻辑。"""
|
|
249
268
|
internal_route = _resolve_internal_custom_page_route(session_profile)
|
|
250
269
|
if internal_route is not None:
|
|
251
270
|
return self.backend.public_stream_request(
|
|
@@ -302,7 +321,7 @@ def _resolve_internal_custom_page_route(session_profile: SessionProfile) -> dict
|
|
|
302
321
|
)
|
|
303
322
|
if session_profile.selected_ws_id is None:
|
|
304
323
|
raise_tool_error(
|
|
305
|
-
QingflowApiError.config_error("
|
|
324
|
+
QingflowApiError.config_error("auth_use_credential must return a valid wsId before using the internal custom-page route")
|
|
306
325
|
)
|
|
307
326
|
return {
|
|
308
327
|
"base_url": base_url,
|
|
@@ -8,17 +8,29 @@ from ..json_types import JSONObject
|
|
|
8
8
|
from ..list_type_labels import SYSTEM_VIEW_DEFINITIONS
|
|
9
9
|
from .app_tools import _analysis_supported_for_view_type
|
|
10
10
|
from .app_tools import AppTools
|
|
11
|
-
from .base import ToolBase
|
|
11
|
+
from .base import ToolBase, tool_cn_name
|
|
12
12
|
from .qingbi_report_tools import QingbiReportTools
|
|
13
13
|
|
|
14
14
|
|
|
15
15
|
class ResourceReadTools(ToolBase):
|
|
16
|
+
"""资源读取工具(中文名:统一只读聚合)。
|
|
17
|
+
|
|
18
|
+
类型:只读聚合工具。
|
|
19
|
+
主要职责:
|
|
20
|
+
1. 聚合应用、视图、图表等读取能力;
|
|
21
|
+
2. 为上层流程提供统一资源读取入口;
|
|
22
|
+
3. 避免多工具重复初始化造成的调用复杂度。
|
|
23
|
+
"""
|
|
24
|
+
|
|
16
25
|
def __init__(self, sessions, backend) -> None:
|
|
26
|
+
"""执行内部辅助逻辑。"""
|
|
17
27
|
super().__init__(sessions, backend)
|
|
18
28
|
self.apps = AppTools(sessions, backend)
|
|
19
29
|
self.charts = QingbiReportTools(sessions, backend)
|
|
20
30
|
|
|
31
|
+
@tool_cn_name("资源读取-门户列表")
|
|
21
32
|
def portal_list(self, *, profile: str) -> JSONObject:
|
|
33
|
+
"""执行门户相关逻辑。"""
|
|
22
34
|
def runner(session_profile, context):
|
|
23
35
|
raw_items = self.backend.request("GET", context, "/dash")
|
|
24
36
|
items = _normalize_portal_list_items(raw_items)
|
|
@@ -36,7 +48,9 @@ class ResourceReadTools(ToolBase):
|
|
|
36
48
|
|
|
37
49
|
return self._run(profile, runner)
|
|
38
50
|
|
|
51
|
+
@tool_cn_name("资源读取-门户详情")
|
|
39
52
|
def portal_get(self, *, profile: str, dash_key: str) -> JSONObject:
|
|
53
|
+
"""执行门户相关逻辑。"""
|
|
40
54
|
self._require_dash_key(dash_key)
|
|
41
55
|
|
|
42
56
|
def runner(session_profile, context):
|
|
@@ -71,7 +85,9 @@ class ResourceReadTools(ToolBase):
|
|
|
71
85
|
|
|
72
86
|
return self._run(profile, runner)
|
|
73
87
|
|
|
88
|
+
@tool_cn_name("资源读取-视图详情")
|
|
74
89
|
def view_get(self, *, profile: str, view_id: str) -> JSONObject:
|
|
90
|
+
"""执行视图相关逻辑。"""
|
|
75
91
|
self._require_view_id(view_id)
|
|
76
92
|
view_key = _extract_custom_view_key(view_id)
|
|
77
93
|
system_view = _lookup_system_view_descriptor(view_id)
|
|
@@ -175,7 +191,9 @@ class ResourceReadTools(ToolBase):
|
|
|
175
191
|
|
|
176
192
|
return self._run(profile, runner)
|
|
177
193
|
|
|
194
|
+
@tool_cn_name("资源读取-报表详情")
|
|
178
195
|
def chart_get(self, *, profile: str, chart_id: str) -> JSONObject:
|
|
196
|
+
"""执行图表相关逻辑。"""
|
|
179
197
|
self._require_chart_id(chart_id)
|
|
180
198
|
|
|
181
199
|
def runner(session_profile, _context):
|
|
@@ -204,18 +222,22 @@ class ResourceReadTools(ToolBase):
|
|
|
204
222
|
return self._run(profile, runner)
|
|
205
223
|
|
|
206
224
|
def _require_dash_key(self, dash_key: str) -> None:
|
|
225
|
+
"""执行内部辅助逻辑。"""
|
|
207
226
|
if not dash_key:
|
|
208
227
|
raise_tool_error(QingflowApiError.config_error("dash_key is required"))
|
|
209
228
|
|
|
210
229
|
def _require_view_id(self, view_id: str) -> None:
|
|
230
|
+
"""执行内部辅助逻辑。"""
|
|
211
231
|
if not view_id:
|
|
212
232
|
raise_tool_error(QingflowApiError.config_error("view_id is required"))
|
|
213
233
|
|
|
214
234
|
def _require_chart_id(self, chart_id: str) -> None:
|
|
235
|
+
"""执行内部辅助逻辑。"""
|
|
215
236
|
if not chart_id:
|
|
216
237
|
raise_tool_error(QingflowApiError.config_error("chart_id is required"))
|
|
217
238
|
|
|
218
239
|
def _resolve_app_key_from_form_id(self, *, profile: str, form_id: int | None) -> str | None:
|
|
240
|
+
"""执行内部辅助逻辑。"""
|
|
219
241
|
if form_id is None:
|
|
220
242
|
return None
|
|
221
243
|
try:
|
|
@@ -5,11 +5,21 @@ from mcp.server.fastmcp import FastMCP
|
|
|
5
5
|
from ..config import DEFAULT_PROFILE
|
|
6
6
|
from ..errors import QingflowApiError, raise_tool_error
|
|
7
7
|
from ..json_types import JSONObject
|
|
8
|
-
from .base import ToolBase
|
|
8
|
+
from .base import ToolBase, tool_cn_name
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
class RoleTools(ToolBase):
|
|
12
|
+
"""角色工具(中文名:角色检索与创建)。
|
|
13
|
+
|
|
14
|
+
类型:组织权限工具。
|
|
15
|
+
主要职责:
|
|
16
|
+
1. 搜索角色并提供候选列表;
|
|
17
|
+
2. 创建角色并返回标准角色信息;
|
|
18
|
+
3. 服务流程节点与权限配置场景。
|
|
19
|
+
"""
|
|
20
|
+
|
|
12
21
|
def register(self, mcp: FastMCP) -> None:
|
|
22
|
+
"""注册当前工具到 MCP 服务。"""
|
|
13
23
|
@mcp.tool()
|
|
14
24
|
def role_search(
|
|
15
25
|
profile: str = DEFAULT_PROFILE,
|
|
@@ -35,7 +45,9 @@ class RoleTools(ToolBase):
|
|
|
35
45
|
def role_delete(profile: str = DEFAULT_PROFILE, role_ids: list[int] | None = None) -> JSONObject:
|
|
36
46
|
return self.role_delete(profile=profile, role_ids=role_ids or [])
|
|
37
47
|
|
|
48
|
+
@tool_cn_name("角色搜索")
|
|
38
49
|
def role_search(self, *, profile: str, keyword: str, page_num: int, page_size: int) -> JSONObject:
|
|
50
|
+
"""执行角色相关逻辑。"""
|
|
39
51
|
if page_num <= 0 or page_size <= 0:
|
|
40
52
|
raise_tool_error(QingflowApiError.config_error("page_num and page_size must be positive"))
|
|
41
53
|
|
|
@@ -55,7 +67,9 @@ class RoleTools(ToolBase):
|
|
|
55
67
|
|
|
56
68
|
return self._run(profile, runner)
|
|
57
69
|
|
|
70
|
+
@tool_cn_name("创建角色")
|
|
58
71
|
def role_create(self, *, profile: str, payload: JSONObject) -> JSONObject:
|
|
72
|
+
"""执行角色相关逻辑。"""
|
|
59
73
|
body = self._require_dict(payload)
|
|
60
74
|
|
|
61
75
|
def runner(session_profile, context):
|
|
@@ -64,7 +78,9 @@ class RoleTools(ToolBase):
|
|
|
64
78
|
|
|
65
79
|
return self._run(profile, runner)
|
|
66
80
|
|
|
81
|
+
@tool_cn_name("更新角色")
|
|
67
82
|
def role_update(self, *, profile: str, role_id: int, payload: JSONObject) -> JSONObject:
|
|
83
|
+
"""执行角色相关逻辑。"""
|
|
68
84
|
if role_id <= 0:
|
|
69
85
|
raise_tool_error(QingflowApiError.config_error("role_id must be positive"))
|
|
70
86
|
body = self._require_dict(payload)
|
|
@@ -79,7 +95,9 @@ class RoleTools(ToolBase):
|
|
|
79
95
|
|
|
80
96
|
return self._run(profile, runner)
|
|
81
97
|
|
|
98
|
+
@tool_cn_name("删除角色")
|
|
82
99
|
def role_delete(self, *, profile: str, role_ids: list[int]) -> JSONObject:
|
|
100
|
+
"""执行角色相关逻辑。"""
|
|
83
101
|
if not role_ids or any(role_id <= 0 for role_id in role_ids):
|
|
84
102
|
raise_tool_error(QingflowApiError.config_error("role_ids must be a non-empty array of positive integers"))
|
|
85
103
|
|
|
@@ -30,7 +30,7 @@ from ..solution.spec_models import (
|
|
|
30
30
|
ViewsBuildSpec,
|
|
31
31
|
)
|
|
32
32
|
from .app_tools import AppTools
|
|
33
|
-
from .base import ToolBase
|
|
33
|
+
from .base import ToolBase, tool_cn_name
|
|
34
34
|
from .navigation_tools import NavigationTools
|
|
35
35
|
from .package_tools import PackageTools
|
|
36
36
|
from .portal_tools import PortalTools
|
|
@@ -126,7 +126,17 @@ SOLUTION_SCHEMA_INTENT_ALIASES = {
|
|
|
126
126
|
|
|
127
127
|
|
|
128
128
|
class SolutionTools(ToolBase):
|
|
129
|
+
"""解决方案工具(中文名:方案会话与安装执行)。
|
|
130
|
+
|
|
131
|
+
类型:解决方案编排工具。
|
|
132
|
+
主要职责:
|
|
133
|
+
1. 管理设计会话与运行会话;
|
|
134
|
+
2. 安装与应用 SolutionSpec;
|
|
135
|
+
3. 输出安装结果、阶段状态与故障信息。
|
|
136
|
+
"""
|
|
137
|
+
|
|
129
138
|
def register(self, mcp: FastMCP) -> None:
|
|
139
|
+
"""注册当前工具到 MCP 服务。"""
|
|
130
140
|
@mcp.tool()
|
|
131
141
|
def solution_design_session(
|
|
132
142
|
action: str = "get",
|
|
@@ -347,6 +357,7 @@ class SolutionTools(ToolBase):
|
|
|
347
357
|
def solution_build_status(build_id: str = "") -> dict[str, Any]:
|
|
348
358
|
return self.solution_build_status(build_id=build_id)
|
|
349
359
|
|
|
360
|
+
@tool_cn_name("方案设计会话")
|
|
350
361
|
def solution_design_session(
|
|
351
362
|
self,
|
|
352
363
|
*,
|
|
@@ -356,6 +367,7 @@ class SolutionTools(ToolBase):
|
|
|
356
367
|
design_patch: dict[str, Any],
|
|
357
368
|
metadata: dict[str, Any],
|
|
358
369
|
) -> dict[str, Any]:
|
|
370
|
+
"""执行方案相关逻辑。"""
|
|
359
371
|
try:
|
|
360
372
|
if action == "start" and not session_id:
|
|
361
373
|
session_id = _generate_session_id(metadata=metadata, stage=stage)
|
|
@@ -416,6 +428,7 @@ class SolutionTools(ToolBase):
|
|
|
416
428
|
except Exception as exc: # noqa: BLE001
|
|
417
429
|
return self._design_failure_response(session_id, action, "runtime", str(exc))
|
|
418
430
|
|
|
431
|
+
@tool_cn_name("方案启动搭建")
|
|
419
432
|
def solution_bootstrap(
|
|
420
433
|
self,
|
|
421
434
|
*,
|
|
@@ -428,6 +441,7 @@ class SolutionTools(ToolBase):
|
|
|
428
441
|
target: dict[str, Any],
|
|
429
442
|
repair_patch: dict[str, Any],
|
|
430
443
|
) -> dict[str, Any]:
|
|
444
|
+
"""执行方案相关逻辑。"""
|
|
431
445
|
mode = _normalize_staged_build_mode(mode)
|
|
432
446
|
if mode not in {"preflight", "plan", "apply", "repair"}:
|
|
433
447
|
return self._failure_response(mode, idempotency_key, "config", "mode must be one of: preflight, plan, apply, repair")
|
|
@@ -515,6 +529,7 @@ class SolutionTools(ToolBase):
|
|
|
515
529
|
return runner()
|
|
516
530
|
return self._run(profile, lambda _session_profile, _context: runner())
|
|
517
531
|
|
|
532
|
+
@tool_cn_name("搭建应用流程")
|
|
518
533
|
def solution_build_app_flow(
|
|
519
534
|
self,
|
|
520
535
|
*,
|
|
@@ -527,6 +542,7 @@ class SolutionTools(ToolBase):
|
|
|
527
542
|
target: dict[str, Any],
|
|
528
543
|
repair_patch: dict[str, Any],
|
|
529
544
|
) -> dict[str, Any]:
|
|
545
|
+
"""执行方案相关逻辑。"""
|
|
530
546
|
mode = _normalize_staged_build_mode(mode)
|
|
531
547
|
return self._stage_build(
|
|
532
548
|
profile=profile,
|
|
@@ -541,6 +557,7 @@ class SolutionTools(ToolBase):
|
|
|
541
557
|
repair_patch=repair_patch,
|
|
542
558
|
)
|
|
543
559
|
|
|
560
|
+
@tool_cn_name("搭建应用")
|
|
544
561
|
def solution_build_app(
|
|
545
562
|
self,
|
|
546
563
|
*,
|
|
@@ -556,6 +573,7 @@ class SolutionTools(ToolBase):
|
|
|
556
573
|
target: dict[str, Any],
|
|
557
574
|
repair_patch: dict[str, Any],
|
|
558
575
|
) -> dict[str, Any]:
|
|
576
|
+
"""执行方案相关逻辑。"""
|
|
559
577
|
mode = _normalize_staged_build_mode(mode)
|
|
560
578
|
resolved_app_spec = deepcopy(app_spec) if isinstance(app_spec, dict) else {}
|
|
561
579
|
if not resolved_app_spec and build_id:
|
|
@@ -582,6 +600,7 @@ class SolutionTools(ToolBase):
|
|
|
582
600
|
projection_name="app",
|
|
583
601
|
)
|
|
584
602
|
|
|
603
|
+
@tool_cn_name("从需求搭建应用")
|
|
585
604
|
def solution_build_app_from_requirements(
|
|
586
605
|
self,
|
|
587
606
|
*,
|
|
@@ -599,6 +618,7 @@ class SolutionTools(ToolBase):
|
|
|
599
618
|
run_label: str | None,
|
|
600
619
|
include_generated_spec: bool,
|
|
601
620
|
) -> dict[str, Any]:
|
|
621
|
+
"""执行方案相关逻辑。"""
|
|
602
622
|
mode = _normalize_staged_build_mode(mode)
|
|
603
623
|
if mode in {"preflight", "plan"} and not build_id:
|
|
604
624
|
build_id = _generate_build_id(run_label=run_label, stage_name="app")
|
|
@@ -703,6 +723,7 @@ class SolutionTools(ToolBase):
|
|
|
703
723
|
include_generated_spec=include_generated_spec,
|
|
704
724
|
)
|
|
705
725
|
|
|
726
|
+
@tool_cn_name("搭建流程")
|
|
706
727
|
def solution_build_flow(
|
|
707
728
|
self,
|
|
708
729
|
*,
|
|
@@ -714,6 +735,7 @@ class SolutionTools(ToolBase):
|
|
|
714
735
|
run_label: str | None,
|
|
715
736
|
repair_patch: dict[str, Any],
|
|
716
737
|
) -> dict[str, Any]:
|
|
738
|
+
"""执行方案相关逻辑。"""
|
|
717
739
|
mode = _normalize_staged_build_mode(mode)
|
|
718
740
|
return self._stage_build(
|
|
719
741
|
profile=profile,
|
|
@@ -731,6 +753,7 @@ class SolutionTools(ToolBase):
|
|
|
731
753
|
projection_name="flow",
|
|
732
754
|
)
|
|
733
755
|
|
|
756
|
+
@tool_cn_name("一键搭建全部")
|
|
734
757
|
def solution_build_all(
|
|
735
758
|
self,
|
|
736
759
|
*,
|
|
@@ -744,6 +767,7 @@ class SolutionTools(ToolBase):
|
|
|
744
767
|
repair_patch: dict[str, Any],
|
|
745
768
|
verify: bool,
|
|
746
769
|
) -> dict[str, Any]:
|
|
770
|
+
"""执行方案相关逻辑。"""
|
|
747
771
|
mode = _normalize_staged_build_mode(mode)
|
|
748
772
|
if mode in {"preflight", "plan"} and not build_id:
|
|
749
773
|
build_id = _generate_build_id(run_label=run_label, stage_name="all")
|
|
@@ -918,6 +942,7 @@ class SolutionTools(ToolBase):
|
|
|
918
942
|
return runner()
|
|
919
943
|
return self._run(profile, lambda _session_profile, _context: runner())
|
|
920
944
|
|
|
945
|
+
@tool_cn_name("搭建视图")
|
|
921
946
|
def solution_build_views(
|
|
922
947
|
self,
|
|
923
948
|
*,
|
|
@@ -929,6 +954,7 @@ class SolutionTools(ToolBase):
|
|
|
929
954
|
run_label: str | None,
|
|
930
955
|
repair_patch: dict[str, Any],
|
|
931
956
|
) -> dict[str, Any]:
|
|
957
|
+
"""执行方案相关逻辑。"""
|
|
932
958
|
mode = _normalize_staged_build_mode(mode)
|
|
933
959
|
return self._stage_build(
|
|
934
960
|
profile=profile,
|
|
@@ -943,6 +969,7 @@ class SolutionTools(ToolBase):
|
|
|
943
969
|
repair_patch=repair_patch,
|
|
944
970
|
)
|
|
945
971
|
|
|
972
|
+
@tool_cn_name("方案 Schema 示例")
|
|
946
973
|
def solution_schema_example(
|
|
947
974
|
self,
|
|
948
975
|
*,
|
|
@@ -951,6 +978,7 @@ class SolutionTools(ToolBase):
|
|
|
951
978
|
include_examples: bool = False,
|
|
952
979
|
include_selected_example: bool = False,
|
|
953
980
|
) -> dict[str, Any]:
|
|
981
|
+
"""执行方案相关逻辑。"""
|
|
954
982
|
resolved_stage = _normalize_solution_schema_stage(stage)
|
|
955
983
|
resolved_intent = _normalize_solution_schema_intent(intent)
|
|
956
984
|
if resolved_stage is None:
|
|
@@ -991,6 +1019,7 @@ class SolutionTools(ToolBase):
|
|
|
991
1019
|
response["resolved_intent"] = resolved_intent
|
|
992
1020
|
return response
|
|
993
1021
|
|
|
1022
|
+
@tool_cn_name("搭建分析门户")
|
|
994
1023
|
def solution_build_analytics_portal(
|
|
995
1024
|
self,
|
|
996
1025
|
*,
|
|
@@ -1002,6 +1031,7 @@ class SolutionTools(ToolBase):
|
|
|
1002
1031
|
run_label: str | None,
|
|
1003
1032
|
repair_patch: dict[str, Any],
|
|
1004
1033
|
) -> dict[str, Any]:
|
|
1034
|
+
"""执行方案相关逻辑。"""
|
|
1005
1035
|
mode = _normalize_staged_build_mode(mode)
|
|
1006
1036
|
return self._stage_build(
|
|
1007
1037
|
profile=profile,
|
|
@@ -1016,6 +1046,7 @@ class SolutionTools(ToolBase):
|
|
|
1016
1046
|
repair_patch=repair_patch,
|
|
1017
1047
|
)
|
|
1018
1048
|
|
|
1049
|
+
@tool_cn_name("搭建导航")
|
|
1019
1050
|
def solution_build_navigation(
|
|
1020
1051
|
self,
|
|
1021
1052
|
*,
|
|
@@ -1027,6 +1058,7 @@ class SolutionTools(ToolBase):
|
|
|
1027
1058
|
run_label: str | None,
|
|
1028
1059
|
repair_patch: dict[str, Any],
|
|
1029
1060
|
) -> dict[str, Any]:
|
|
1061
|
+
"""执行方案相关逻辑。"""
|
|
1030
1062
|
mode = _normalize_staged_build_mode(mode)
|
|
1031
1063
|
return self._stage_build(
|
|
1032
1064
|
profile=profile,
|
|
@@ -1041,7 +1073,9 @@ class SolutionTools(ToolBase):
|
|
|
1041
1073
|
repair_patch=repair_patch,
|
|
1042
1074
|
)
|
|
1043
1075
|
|
|
1076
|
+
@tool_cn_name("搭建状态")
|
|
1044
1077
|
def solution_build_status(self, *, build_id: str) -> dict[str, Any]:
|
|
1078
|
+
"""执行方案相关逻辑。"""
|
|
1045
1079
|
if not build_id:
|
|
1046
1080
|
error_fields = _solution_error_fields(
|
|
1047
1081
|
category="config",
|
|
@@ -1077,6 +1111,7 @@ class SolutionTools(ToolBase):
|
|
|
1077
1111
|
tool_name: str | None = None,
|
|
1078
1112
|
projection_name: str | None = None,
|
|
1079
1113
|
) -> dict[str, Any]:
|
|
1114
|
+
"""执行内部辅助逻辑。"""
|
|
1080
1115
|
mode = _normalize_staged_build_mode(mode)
|
|
1081
1116
|
public_stage_name = public_stage_name or stage_name
|
|
1082
1117
|
tool_name = tool_name or STAGE_TOOL_NAMES.get(stage_name, "solution_build_app_flow")
|
|
@@ -1133,6 +1168,7 @@ class SolutionTools(ToolBase):
|
|
|
1133
1168
|
tool_name: str,
|
|
1134
1169
|
projection_name: str,
|
|
1135
1170
|
) -> dict[str, Any]:
|
|
1171
|
+
"""执行内部辅助逻辑。"""
|
|
1136
1172
|
try:
|
|
1137
1173
|
resolved_stage_payload = self._resolve_stage_payload(
|
|
1138
1174
|
assembly=assembly,
|
|
@@ -1320,6 +1356,7 @@ class SolutionTools(ToolBase):
|
|
|
1320
1356
|
stage_model: type[BaseModel],
|
|
1321
1357
|
projection_name: str,
|
|
1322
1358
|
) -> dict[str, Any]:
|
|
1359
|
+
"""执行内部辅助逻辑。"""
|
|
1323
1360
|
existing_stage_payload = (assembly.data.get("stage_specs", {}) or {}).get(stage_name, {}) or {}
|
|
1324
1361
|
base_payload: dict[str, Any] = {}
|
|
1325
1362
|
if mode == "repair":
|
|
@@ -1357,6 +1394,7 @@ class SolutionTools(ToolBase):
|
|
|
1357
1394
|
mode: str,
|
|
1358
1395
|
repair_patch: dict[str, Any],
|
|
1359
1396
|
) -> dict[str, Any]:
|
|
1397
|
+
"""执行内部辅助逻辑。"""
|
|
1360
1398
|
base_payload = deepcopy(solution_spec)
|
|
1361
1399
|
if mode == "repair" and repair_patch:
|
|
1362
1400
|
base_payload = deep_merge(base_payload, repair_patch)
|
|
@@ -1364,6 +1402,7 @@ class SolutionTools(ToolBase):
|
|
|
1364
1402
|
return parsed.model_dump(mode="json", exclude_unset=True)
|
|
1365
1403
|
|
|
1366
1404
|
def _build_executor(self) -> SolutionExecutor:
|
|
1405
|
+
"""执行内部辅助逻辑。"""
|
|
1367
1406
|
return SolutionExecutor(
|
|
1368
1407
|
workspace_tools=WorkspaceTools(self.sessions, self.backend),
|
|
1369
1408
|
package_tools=PackageTools(self.sessions, self.backend),
|
|
@@ -1385,6 +1424,7 @@ class SolutionTools(ToolBase):
|
|
|
1385
1424
|
artifacts: dict[str, Any],
|
|
1386
1425
|
solution_spec: dict[str, Any],
|
|
1387
1426
|
) -> dict[str, Any]:
|
|
1427
|
+
"""执行内部辅助逻辑。"""
|
|
1388
1428
|
verification = {
|
|
1389
1429
|
"build_id": build_id,
|
|
1390
1430
|
"status": "success",
|
|
@@ -1507,6 +1547,7 @@ class SolutionTools(ToolBase):
|
|
|
1507
1547
|
solution_spec: dict[str, Any],
|
|
1508
1548
|
target: dict[str, Any],
|
|
1509
1549
|
) -> dict[str, Any] | None:
|
|
1550
|
+
"""执行内部辅助逻辑。"""
|
|
1510
1551
|
if public_stage_name != "app":
|
|
1511
1552
|
return None
|
|
1512
1553
|
app_tools = AppTools(self.sessions, self.backend)
|
|
@@ -1592,6 +1633,7 @@ class SolutionTools(ToolBase):
|
|
|
1592
1633
|
return verification
|
|
1593
1634
|
|
|
1594
1635
|
def _failure_response(self, mode: str, idempotency_key: str, category: str, detail: Any) -> dict[str, Any]:
|
|
1636
|
+
"""执行内部辅助逻辑。"""
|
|
1595
1637
|
error_fields = _solution_error_fields(
|
|
1596
1638
|
category=category,
|
|
1597
1639
|
detail=detail,
|
|
@@ -1624,6 +1666,7 @@ class SolutionTools(ToolBase):
|
|
|
1624
1666
|
*,
|
|
1625
1667
|
tool_name: str,
|
|
1626
1668
|
) -> dict[str, Any]:
|
|
1669
|
+
"""执行内部辅助逻辑。"""
|
|
1627
1670
|
error_fields = _solution_error_fields(
|
|
1628
1671
|
category=category,
|
|
1629
1672
|
detail=detail,
|
|
@@ -1662,6 +1705,7 @@ class SolutionTools(ToolBase):
|
|
|
1662
1705
|
assembly: BuildAssemblyStore,
|
|
1663
1706
|
tool_name: str,
|
|
1664
1707
|
) -> dict[str, Any]:
|
|
1708
|
+
"""执行内部辅助逻辑。"""
|
|
1665
1709
|
return {
|
|
1666
1710
|
"build_id": build_id,
|
|
1667
1711
|
"stage": stage_name,
|
|
@@ -1701,6 +1745,7 @@ class SolutionTools(ToolBase):
|
|
|
1701
1745
|
tool_name: str,
|
|
1702
1746
|
verification: dict[str, Any] | None = None,
|
|
1703
1747
|
) -> dict[str, Any]:
|
|
1748
|
+
"""执行内部辅助逻辑。"""
|
|
1704
1749
|
response = {
|
|
1705
1750
|
"build_id": build_id,
|
|
1706
1751
|
"stage": stage_name,
|
|
@@ -1729,6 +1774,7 @@ class SolutionTools(ToolBase):
|
|
|
1729
1774
|
return response
|
|
1730
1775
|
|
|
1731
1776
|
def _design_failure_response(self, session_id: str, action: str, category: str, detail: Any) -> dict[str, Any]:
|
|
1777
|
+
"""执行内部辅助逻辑。"""
|
|
1732
1778
|
error_fields = _solution_error_fields(
|
|
1733
1779
|
category=category,
|
|
1734
1780
|
detail=detail,
|
|
@@ -1750,6 +1796,7 @@ class SolutionTools(ToolBase):
|
|
|
1750
1796
|
}
|
|
1751
1797
|
|
|
1752
1798
|
def _design_summary(self, store: DesignSessionStore) -> dict[str, Any]:
|
|
1799
|
+
"""执行内部辅助逻辑。"""
|
|
1753
1800
|
summary = store.summary()
|
|
1754
1801
|
current_stage = summary["current_stage"]
|
|
1755
1802
|
summary["next_stage"] = None if summary["status"] == "finalized" else current_stage
|
|
@@ -1758,6 +1805,7 @@ class SolutionTools(ToolBase):
|
|
|
1758
1805
|
return summary
|
|
1759
1806
|
|
|
1760
1807
|
def _all_failure_response(self, build_id: str, mode: str, category: str, detail: Any) -> dict[str, Any]:
|
|
1808
|
+
"""执行内部辅助逻辑。"""
|
|
1761
1809
|
error_fields = _solution_error_fields(
|
|
1762
1810
|
category=category,
|
|
1763
1811
|
detail=detail,
|
|
@@ -1780,6 +1828,7 @@ class SolutionTools(ToolBase):
|
|
|
1780
1828
|
}
|
|
1781
1829
|
|
|
1782
1830
|
def _load_generated_app_spec(self, build_id: str) -> dict[str, Any] | None:
|
|
1831
|
+
"""执行内部辅助逻辑。"""
|
|
1783
1832
|
if not build_id:
|
|
1784
1833
|
return None
|
|
1785
1834
|
try:
|
|
@@ -1802,6 +1851,7 @@ class SolutionTools(ToolBase):
|
|
|
1802
1851
|
requirement_text: str,
|
|
1803
1852
|
layout_style: str,
|
|
1804
1853
|
) -> None:
|
|
1854
|
+
"""执行内部辅助逻辑。"""
|
|
1805
1855
|
assembly = BuildAssemblyStore.open(build_id=build_id)
|
|
1806
1856
|
builder_state = assembly.get_builder_state()
|
|
1807
1857
|
generated_specs = builder_state.get("generated_specs", {})
|
|
@@ -1826,6 +1876,7 @@ class SolutionTools(ToolBase):
|
|
|
1826
1876
|
stage_payload: dict[str, Any],
|
|
1827
1877
|
errors: list[dict[str, Any]],
|
|
1828
1878
|
) -> tuple[str | None, int]:
|
|
1879
|
+
"""执行内部辅助逻辑。"""
|
|
1829
1880
|
signature = _failure_signature_for_stage(stage_name=stage_name, stage_payload=stage_payload, errors=errors)
|
|
1830
1881
|
if signature is None:
|
|
1831
1882
|
return None, 0
|
|
@@ -1849,6 +1900,7 @@ class SolutionTools(ToolBase):
|
|
|
1849
1900
|
package_tag_id: int,
|
|
1850
1901
|
package_name: str,
|
|
1851
1902
|
) -> dict[str, Any]:
|
|
1903
|
+
"""执行内部辅助逻辑。"""
|
|
1852
1904
|
packages = PackageTools(self.sessions, self.backend)
|
|
1853
1905
|
normalized_name = package_name.strip()
|
|
1854
1906
|
if package_tag_id > 0:
|
|
@@ -1998,6 +2050,7 @@ class SolutionTools(ToolBase):
|
|
|
1998
2050
|
package_resolution: dict[str, Any],
|
|
1999
2051
|
update_only: bool,
|
|
2000
2052
|
) -> dict[str, Any]:
|
|
2053
|
+
"""执行内部辅助逻辑。"""
|
|
2001
2054
|
normalized_app_key = str(app_key or "").strip()
|
|
2002
2055
|
if not normalized_app_key:
|
|
2003
2056
|
if update_only:
|
|
@@ -2120,6 +2173,7 @@ class SolutionTools(ToolBase):
|
|
|
2120
2173
|
invalid_field_types: list[str] | None = None,
|
|
2121
2174
|
error_details: dict[str, Any] | None = None,
|
|
2122
2175
|
) -> dict[str, Any]:
|
|
2176
|
+
"""执行内部辅助逻辑。"""
|
|
2123
2177
|
suggested_next_call = (
|
|
2124
2178
|
{"tool_name": "solution_build_app", "arguments": {"mode": "plan", "build_id": build_id}}
|
|
2125
2179
|
if build_id and self._load_generated_app_spec(build_id)
|
|
@@ -2185,6 +2239,7 @@ class SolutionTools(ToolBase):
|
|
|
2185
2239
|
stage_result: dict[str, Any],
|
|
2186
2240
|
include_generated_spec: bool,
|
|
2187
2241
|
) -> dict[str, Any]:
|
|
2242
|
+
"""执行内部辅助逻辑。"""
|
|
2188
2243
|
next_call = stage_result.get("suggested_next_call")
|
|
2189
2244
|
response = {
|
|
2190
2245
|
"status": stage_result.get("status"),
|