@josephyan/qingflow-cli 0.2.0-beta.55 → 0.2.0-beta.56
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/cli/commands/app.py +16 -16
- package/src/qingflow_mcp/cli/commands/auth.py +16 -19
- package/src/qingflow_mcp/cli/commands/builder.py +139 -124
- package/src/qingflow_mcp/cli/commands/common.py +95 -21
- package/src/qingflow_mcp/cli/commands/imports.py +34 -42
- package/src/qingflow_mcp/cli/commands/record.py +133 -131
- package/src/qingflow_mcp/cli/commands/task.py +44 -43
- package/src/qingflow_mcp/cli/commands/workspace.py +10 -10
- package/src/qingflow_mcp/cli/context.py +32 -35
- package/src/qingflow_mcp/cli/formatters.py +121 -124
- package/src/qingflow_mcp/cli/main.py +17 -52
- package/src/qingflow_mcp/ops/__init__.py +3 -0
- package/src/qingflow_mcp/ops/apps.py +64 -0
- package/src/qingflow_mcp/ops/auth.py +121 -0
- package/src/qingflow_mcp/ops/base.py +290 -0
- package/src/qingflow_mcp/ops/builder.py +323 -0
- package/src/qingflow_mcp/ops/context.py +120 -0
- package/src/qingflow_mcp/ops/directory.py +171 -0
- package/src/qingflow_mcp/ops/feedback.py +49 -0
- package/src/qingflow_mcp/ops/files.py +78 -0
- package/src/qingflow_mcp/ops/imports.py +140 -0
- package/src/qingflow_mcp/ops/records.py +415 -0
- package/src/qingflow_mcp/ops/tasks.py +171 -0
- package/src/qingflow_mcp/ops/workspace.py +76 -0
- package/src/qingflow_mcp/server_app_builder.py +190 -122
- package/src/qingflow_mcp/server_app_user.py +662 -63
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import Any
|
|
4
|
+
|
|
5
|
+
from .base import normalize_exception, success_result, tool_payload
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class FileOperations:
|
|
9
|
+
def __init__(self, tools: Any) -> None:
|
|
10
|
+
self._tools = tools
|
|
11
|
+
|
|
12
|
+
def get_upload_info(
|
|
13
|
+
self,
|
|
14
|
+
*,
|
|
15
|
+
profile: str,
|
|
16
|
+
upload_kind: str,
|
|
17
|
+
file_name: str,
|
|
18
|
+
file_size: int,
|
|
19
|
+
upload_mark: str | None,
|
|
20
|
+
content_type: str | None,
|
|
21
|
+
bucket_type: str | None,
|
|
22
|
+
path_id: int | None,
|
|
23
|
+
file_related_url: str | None,
|
|
24
|
+
) -> dict:
|
|
25
|
+
try:
|
|
26
|
+
raw = self._tools.file.file_get_upload_info(
|
|
27
|
+
profile=profile,
|
|
28
|
+
upload_kind=upload_kind,
|
|
29
|
+
file_name=file_name,
|
|
30
|
+
file_size=file_size,
|
|
31
|
+
upload_mark=upload_mark,
|
|
32
|
+
content_type=content_type,
|
|
33
|
+
bucket_type=bucket_type,
|
|
34
|
+
path_id=path_id,
|
|
35
|
+
file_related_url=file_related_url,
|
|
36
|
+
)
|
|
37
|
+
except Exception as error: # noqa: BLE001
|
|
38
|
+
return normalize_exception(error)
|
|
39
|
+
return success_result(
|
|
40
|
+
"UPLOAD_INFO_READY",
|
|
41
|
+
"已获取上传信息",
|
|
42
|
+
data=tool_payload(raw) if isinstance(tool_payload(raw), dict) else raw,
|
|
43
|
+
meta={"profile": profile, "request_route": raw.get("request_route") if isinstance(raw, dict) else None},
|
|
44
|
+
legacy=raw,
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
def upload_local(
|
|
48
|
+
self,
|
|
49
|
+
*,
|
|
50
|
+
profile: str,
|
|
51
|
+
upload_kind: str,
|
|
52
|
+
file_path: str,
|
|
53
|
+
upload_mark: str | None,
|
|
54
|
+
content_type: str | None,
|
|
55
|
+
bucket_type: str | None,
|
|
56
|
+
path_id: int | None,
|
|
57
|
+
file_related_url: str | None,
|
|
58
|
+
) -> dict:
|
|
59
|
+
try:
|
|
60
|
+
raw = self._tools.file.file_upload_local(
|
|
61
|
+
profile=profile,
|
|
62
|
+
upload_kind=upload_kind,
|
|
63
|
+
file_path=file_path,
|
|
64
|
+
upload_mark=upload_mark,
|
|
65
|
+
content_type=content_type,
|
|
66
|
+
bucket_type=bucket_type,
|
|
67
|
+
path_id=path_id,
|
|
68
|
+
file_related_url=file_related_url,
|
|
69
|
+
)
|
|
70
|
+
except Exception as error: # noqa: BLE001
|
|
71
|
+
return normalize_exception(error)
|
|
72
|
+
return success_result(
|
|
73
|
+
"FILE_UPLOADED",
|
|
74
|
+
"已完成本地文件上传",
|
|
75
|
+
data=tool_payload(raw) if isinstance(tool_payload(raw), dict) else raw,
|
|
76
|
+
meta={"profile": profile, "request_route": raw.get("request_route") if isinstance(raw, dict) else None},
|
|
77
|
+
legacy=raw,
|
|
78
|
+
)
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import Any
|
|
4
|
+
|
|
5
|
+
from .base import normalize_exception, success_result, tool_payload
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class ImportOperations:
|
|
9
|
+
def __init__(self, tools: Any) -> None:
|
|
10
|
+
self._tools = tools
|
|
11
|
+
|
|
12
|
+
def schema(self, *, profile: str, app_key: str, output_profile: str = "normal") -> dict:
|
|
13
|
+
try:
|
|
14
|
+
raw = self._tools.imports.record_import_schema_get(
|
|
15
|
+
profile=profile,
|
|
16
|
+
app_key=app_key,
|
|
17
|
+
output_profile=output_profile,
|
|
18
|
+
)
|
|
19
|
+
except Exception as error: # noqa: BLE001
|
|
20
|
+
return normalize_exception(error)
|
|
21
|
+
return success_result(
|
|
22
|
+
"IMPORT_SCHEMA_READY",
|
|
23
|
+
"已读取导入字段结构",
|
|
24
|
+
data=tool_payload(raw) if isinstance(tool_payload(raw), dict) else raw,
|
|
25
|
+
warnings=raw.get("warnings") if isinstance(raw, dict) and isinstance(raw.get("warnings"), list) else [],
|
|
26
|
+
meta={"profile": profile},
|
|
27
|
+
legacy=raw,
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
def template(self, *, profile: str, app_key: str, download_to_path: str | None) -> dict:
|
|
31
|
+
try:
|
|
32
|
+
raw = self._tools.imports.record_import_template_get(
|
|
33
|
+
profile=profile,
|
|
34
|
+
app_key=app_key,
|
|
35
|
+
download_to_path=download_to_path,
|
|
36
|
+
)
|
|
37
|
+
except Exception as error: # noqa: BLE001
|
|
38
|
+
return normalize_exception(error)
|
|
39
|
+
return success_result(
|
|
40
|
+
"IMPORT_TEMPLATE_READY",
|
|
41
|
+
"已获取导入模板",
|
|
42
|
+
data=tool_payload(raw),
|
|
43
|
+
warnings=raw.get("warnings") if isinstance(raw, dict) and isinstance(raw.get("warnings"), list) else [],
|
|
44
|
+
meta={"profile": profile},
|
|
45
|
+
legacy=raw,
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
def verify(self, *, profile: str, app_key: str, file_path: str) -> dict:
|
|
49
|
+
try:
|
|
50
|
+
raw = self._tools.imports.record_import_verify(profile=profile, app_key=app_key, file_path=file_path)
|
|
51
|
+
except Exception as error: # noqa: BLE001
|
|
52
|
+
return normalize_exception(error)
|
|
53
|
+
return success_result(
|
|
54
|
+
"IMPORT_VERIFIED",
|
|
55
|
+
"已完成导入预检",
|
|
56
|
+
data=tool_payload(raw) if isinstance(tool_payload(raw), dict) else raw,
|
|
57
|
+
warnings=raw.get("warnings") if isinstance(raw, dict) and isinstance(raw.get("warnings"), list) else [],
|
|
58
|
+
meta={"profile": profile, "verification": raw.get("verification") if isinstance(raw, dict) else None},
|
|
59
|
+
legacy=raw,
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
def repair(
|
|
63
|
+
self,
|
|
64
|
+
*,
|
|
65
|
+
profile: str,
|
|
66
|
+
verification_id: str,
|
|
67
|
+
authorized_file_modification: bool,
|
|
68
|
+
output_path: str | None,
|
|
69
|
+
selected_repairs: list[str],
|
|
70
|
+
) -> dict:
|
|
71
|
+
try:
|
|
72
|
+
raw = self._tools.imports.record_import_repair_local(
|
|
73
|
+
profile=profile,
|
|
74
|
+
verification_id=verification_id,
|
|
75
|
+
authorized_file_modification=authorized_file_modification,
|
|
76
|
+
output_path=output_path,
|
|
77
|
+
selected_repairs=selected_repairs,
|
|
78
|
+
)
|
|
79
|
+
except Exception as error: # noqa: BLE001
|
|
80
|
+
return normalize_exception(error)
|
|
81
|
+
return success_result(
|
|
82
|
+
"IMPORT_FILE_REPAIRED",
|
|
83
|
+
"已完成导入文件修复",
|
|
84
|
+
data=tool_payload(raw) if isinstance(tool_payload(raw), dict) else raw,
|
|
85
|
+
warnings=raw.get("warnings") if isinstance(raw, dict) and isinstance(raw.get("warnings"), list) else [],
|
|
86
|
+
meta={"profile": profile},
|
|
87
|
+
legacy=raw,
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
def start(
|
|
91
|
+
self,
|
|
92
|
+
*,
|
|
93
|
+
profile: str,
|
|
94
|
+
app_key: str,
|
|
95
|
+
verification_id: str,
|
|
96
|
+
being_enter_auditing: bool | None,
|
|
97
|
+
view_key: str | None,
|
|
98
|
+
) -> dict:
|
|
99
|
+
try:
|
|
100
|
+
raw = self._tools.imports.record_import_start(
|
|
101
|
+
profile=profile,
|
|
102
|
+
app_key=app_key,
|
|
103
|
+
verification_id=verification_id,
|
|
104
|
+
being_enter_auditing=being_enter_auditing,
|
|
105
|
+
view_key=view_key,
|
|
106
|
+
)
|
|
107
|
+
except Exception as error: # noqa: BLE001
|
|
108
|
+
return normalize_exception(error)
|
|
109
|
+
return success_result(
|
|
110
|
+
"IMPORT_STARTED",
|
|
111
|
+
"已启动导入任务",
|
|
112
|
+
data=tool_payload(raw) if isinstance(tool_payload(raw), dict) else raw,
|
|
113
|
+
warnings=raw.get("warnings") if isinstance(raw, dict) and isinstance(raw.get("warnings"), list) else [],
|
|
114
|
+
meta={"profile": profile, "verification": raw.get("verification") if isinstance(raw, dict) else None},
|
|
115
|
+
legacy=raw,
|
|
116
|
+
)
|
|
117
|
+
|
|
118
|
+
def status(self, *, profile: str, app_key: str, import_id: str | None, process_id_str: str | None) -> dict:
|
|
119
|
+
try:
|
|
120
|
+
raw = self._tools.imports.record_import_status_get(
|
|
121
|
+
profile=profile,
|
|
122
|
+
app_key=app_key,
|
|
123
|
+
import_id=import_id,
|
|
124
|
+
process_id_str=process_id_str,
|
|
125
|
+
)
|
|
126
|
+
except Exception as error: # noqa: BLE001
|
|
127
|
+
return normalize_exception(error)
|
|
128
|
+
data = tool_payload(raw) if isinstance(tool_payload(raw), dict) else raw
|
|
129
|
+
if isinstance(data, dict) and raw.get("status") is not None:
|
|
130
|
+
data = dict(data)
|
|
131
|
+
data["status"] = raw.get("status")
|
|
132
|
+
data["raw_status"] = raw.get("status")
|
|
133
|
+
return success_result(
|
|
134
|
+
"IMPORT_STATUS_READY",
|
|
135
|
+
"已读取导入状态",
|
|
136
|
+
data=data,
|
|
137
|
+
warnings=raw.get("warnings") if isinstance(raw, dict) and isinstance(raw.get("warnings"), list) else [],
|
|
138
|
+
meta={"profile": profile, "verification": raw.get("verification") if isinstance(raw, dict) else None},
|
|
139
|
+
legacy=raw,
|
|
140
|
+
)
|
|
@@ -0,0 +1,415 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import Any
|
|
4
|
+
|
|
5
|
+
from .base import normalize_exception, success_result, tool_payload
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class RecordOperations:
|
|
9
|
+
def __init__(self, tools: Any) -> None:
|
|
10
|
+
self._tools = tools
|
|
11
|
+
|
|
12
|
+
def schema(
|
|
13
|
+
self,
|
|
14
|
+
*,
|
|
15
|
+
profile: str,
|
|
16
|
+
app_key: str,
|
|
17
|
+
mode: str,
|
|
18
|
+
view_id: str | None,
|
|
19
|
+
record_id: int | None,
|
|
20
|
+
output_profile: str = "normal",
|
|
21
|
+
) -> dict:
|
|
22
|
+
try:
|
|
23
|
+
if mode == "applicant":
|
|
24
|
+
raw = self._tools.record.record_schema_get(
|
|
25
|
+
profile=profile,
|
|
26
|
+
app_key=app_key,
|
|
27
|
+
schema_mode="applicant",
|
|
28
|
+
output_profile=output_profile,
|
|
29
|
+
)
|
|
30
|
+
elif mode == "browse":
|
|
31
|
+
raw = self._tools.record.record_browse_schema_get_public(
|
|
32
|
+
profile=profile,
|
|
33
|
+
app_key=app_key,
|
|
34
|
+
view_id=view_id,
|
|
35
|
+
output_profile=output_profile,
|
|
36
|
+
)
|
|
37
|
+
elif mode == "insert":
|
|
38
|
+
raw = self._tools.record.record_insert_schema_get_public(
|
|
39
|
+
profile=profile,
|
|
40
|
+
app_key=app_key,
|
|
41
|
+
output_profile=output_profile,
|
|
42
|
+
)
|
|
43
|
+
elif mode == "update":
|
|
44
|
+
raw = self._tools.record.record_update_schema_get_public(
|
|
45
|
+
profile=profile,
|
|
46
|
+
app_key=app_key,
|
|
47
|
+
record_id=record_id,
|
|
48
|
+
output_profile=output_profile,
|
|
49
|
+
)
|
|
50
|
+
elif mode == "import":
|
|
51
|
+
raw = self._tools.imports.record_import_schema_get(
|
|
52
|
+
profile=profile,
|
|
53
|
+
app_key=app_key,
|
|
54
|
+
output_profile=output_profile,
|
|
55
|
+
)
|
|
56
|
+
else:
|
|
57
|
+
raw = self._tools.code_block.record_code_block_schema_get_public(
|
|
58
|
+
profile=profile,
|
|
59
|
+
app_key=app_key,
|
|
60
|
+
output_profile=output_profile,
|
|
61
|
+
)
|
|
62
|
+
except Exception as error: # noqa: BLE001
|
|
63
|
+
return normalize_exception(error)
|
|
64
|
+
return success_result(
|
|
65
|
+
"RECORD_SCHEMA_READY",
|
|
66
|
+
"已读取表结构",
|
|
67
|
+
data={"mode": mode, "schema": tool_payload(raw)},
|
|
68
|
+
warnings=raw.get("warnings") if isinstance(raw, dict) and isinstance(raw.get("warnings"), list) else [],
|
|
69
|
+
meta={"profile": profile},
|
|
70
|
+
legacy=raw,
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
def list(
|
|
74
|
+
self,
|
|
75
|
+
*,
|
|
76
|
+
profile: str,
|
|
77
|
+
app_key: str,
|
|
78
|
+
columns: list[Any],
|
|
79
|
+
where: list[Any],
|
|
80
|
+
order_by: list[Any],
|
|
81
|
+
limit: int,
|
|
82
|
+
page: int,
|
|
83
|
+
view_id: str | None,
|
|
84
|
+
list_type: int | None,
|
|
85
|
+
view_key: str | None,
|
|
86
|
+
view_name: str | None,
|
|
87
|
+
output_profile: str = "normal",
|
|
88
|
+
) -> dict:
|
|
89
|
+
try:
|
|
90
|
+
raw = self._tools.record.record_list(
|
|
91
|
+
profile=profile,
|
|
92
|
+
app_key=app_key,
|
|
93
|
+
columns=columns,
|
|
94
|
+
where=where,
|
|
95
|
+
order_by=order_by,
|
|
96
|
+
limit=limit,
|
|
97
|
+
page=page,
|
|
98
|
+
view_id=view_id,
|
|
99
|
+
list_type=list_type,
|
|
100
|
+
view_key=view_key,
|
|
101
|
+
view_name=view_name,
|
|
102
|
+
output_profile=output_profile,
|
|
103
|
+
)
|
|
104
|
+
except Exception as error: # noqa: BLE001
|
|
105
|
+
return normalize_exception(error)
|
|
106
|
+
data = tool_payload(raw)
|
|
107
|
+
return success_result(
|
|
108
|
+
"RECORDS_LISTED",
|
|
109
|
+
"已读取记录列表",
|
|
110
|
+
data=data if isinstance(data, dict) else {"items": data},
|
|
111
|
+
warnings=raw.get("warnings") if isinstance(raw, dict) and isinstance(raw.get("warnings"), list) else [],
|
|
112
|
+
meta={"profile": profile},
|
|
113
|
+
legacy=raw,
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
def get(
|
|
117
|
+
self,
|
|
118
|
+
*,
|
|
119
|
+
profile: str,
|
|
120
|
+
app_key: str,
|
|
121
|
+
record_id: int,
|
|
122
|
+
columns: list[Any],
|
|
123
|
+
view_id: str | None,
|
|
124
|
+
workflow_node_id: int | None,
|
|
125
|
+
output_profile: str = "normal",
|
|
126
|
+
) -> dict:
|
|
127
|
+
try:
|
|
128
|
+
raw = self._tools.record.record_get_public(
|
|
129
|
+
profile=profile,
|
|
130
|
+
app_key=app_key,
|
|
131
|
+
record_id=record_id,
|
|
132
|
+
columns=columns,
|
|
133
|
+
view_id=view_id,
|
|
134
|
+
workflow_node_id=workflow_node_id,
|
|
135
|
+
output_profile=output_profile,
|
|
136
|
+
)
|
|
137
|
+
except Exception as error: # noqa: BLE001
|
|
138
|
+
return normalize_exception(error)
|
|
139
|
+
return success_result(
|
|
140
|
+
"RECORD_SHOWN",
|
|
141
|
+
"已读取单条记录",
|
|
142
|
+
data={"record": tool_payload(raw), "record_id": record_id},
|
|
143
|
+
warnings=raw.get("warnings") if isinstance(raw, dict) and isinstance(raw.get("warnings"), list) else [],
|
|
144
|
+
meta={"profile": profile},
|
|
145
|
+
legacy=raw,
|
|
146
|
+
)
|
|
147
|
+
|
|
148
|
+
def create(
|
|
149
|
+
self,
|
|
150
|
+
*,
|
|
151
|
+
profile: str,
|
|
152
|
+
app_key: str,
|
|
153
|
+
fields: dict[str, Any],
|
|
154
|
+
verify_write: bool,
|
|
155
|
+
output_profile: str = "normal",
|
|
156
|
+
) -> dict:
|
|
157
|
+
try:
|
|
158
|
+
raw = self._tools.record.record_insert_public(
|
|
159
|
+
profile=profile,
|
|
160
|
+
app_key=app_key,
|
|
161
|
+
fields=fields,
|
|
162
|
+
verify_write=verify_write,
|
|
163
|
+
output_profile=output_profile,
|
|
164
|
+
)
|
|
165
|
+
except Exception as error: # noqa: BLE001
|
|
166
|
+
return normalize_exception(error)
|
|
167
|
+
data = tool_payload(raw)
|
|
168
|
+
return success_result(
|
|
169
|
+
"RECORD_CREATED",
|
|
170
|
+
"已新增记录",
|
|
171
|
+
data={
|
|
172
|
+
"record_id": _extract_record_id(data),
|
|
173
|
+
"record_ids": _extract_record_ids(data),
|
|
174
|
+
"result": data,
|
|
175
|
+
},
|
|
176
|
+
warnings=raw.get("warnings") if isinstance(raw, dict) and isinstance(raw.get("warnings"), list) else [],
|
|
177
|
+
meta={"profile": profile, "verification": raw.get("verification") if isinstance(raw, dict) else None},
|
|
178
|
+
legacy=raw,
|
|
179
|
+
)
|
|
180
|
+
|
|
181
|
+
def update(
|
|
182
|
+
self,
|
|
183
|
+
*,
|
|
184
|
+
profile: str,
|
|
185
|
+
app_key: str,
|
|
186
|
+
record_id: int | None,
|
|
187
|
+
fields: dict[str, Any],
|
|
188
|
+
verify_write: bool,
|
|
189
|
+
output_profile: str = "normal",
|
|
190
|
+
) -> dict:
|
|
191
|
+
try:
|
|
192
|
+
raw = self._tools.record.record_update_public(
|
|
193
|
+
profile=profile,
|
|
194
|
+
app_key=app_key,
|
|
195
|
+
record_id=record_id,
|
|
196
|
+
fields=fields,
|
|
197
|
+
verify_write=verify_write,
|
|
198
|
+
output_profile=output_profile,
|
|
199
|
+
)
|
|
200
|
+
except Exception as error: # noqa: BLE001
|
|
201
|
+
return normalize_exception(error)
|
|
202
|
+
data = tool_payload(raw)
|
|
203
|
+
return success_result(
|
|
204
|
+
"RECORD_UPDATED",
|
|
205
|
+
"已更新记录",
|
|
206
|
+
data={
|
|
207
|
+
"record_id": _extract_record_id(data) or record_id,
|
|
208
|
+
"record_ids": _extract_record_ids(data) or [record_id],
|
|
209
|
+
"result": data,
|
|
210
|
+
},
|
|
211
|
+
warnings=raw.get("warnings") if isinstance(raw, dict) and isinstance(raw.get("warnings"), list) else [],
|
|
212
|
+
meta={"profile": profile, "verification": raw.get("verification") if isinstance(raw, dict) else None},
|
|
213
|
+
legacy=raw,
|
|
214
|
+
)
|
|
215
|
+
|
|
216
|
+
def delete(
|
|
217
|
+
self,
|
|
218
|
+
*,
|
|
219
|
+
profile: str,
|
|
220
|
+
app_key: str,
|
|
221
|
+
record_id: int | None,
|
|
222
|
+
record_ids: list[int],
|
|
223
|
+
output_profile: str = "normal",
|
|
224
|
+
) -> dict:
|
|
225
|
+
try:
|
|
226
|
+
raw = self._tools.record.record_delete_public(
|
|
227
|
+
profile=profile,
|
|
228
|
+
app_key=app_key,
|
|
229
|
+
record_id=record_id,
|
|
230
|
+
record_ids=record_ids,
|
|
231
|
+
output_profile=output_profile,
|
|
232
|
+
)
|
|
233
|
+
except Exception as error: # noqa: BLE001
|
|
234
|
+
return normalize_exception(error)
|
|
235
|
+
data = tool_payload(raw)
|
|
236
|
+
removed = _extract_record_ids(data) or ([record_id] if record_id else record_ids)
|
|
237
|
+
return success_result(
|
|
238
|
+
"RECORDS_DELETED",
|
|
239
|
+
"已删除记录",
|
|
240
|
+
data={"record_ids": removed, "result": data},
|
|
241
|
+
warnings=raw.get("warnings") if isinstance(raw, dict) and isinstance(raw.get("warnings"), list) else [],
|
|
242
|
+
meta={"profile": profile, "verification": raw.get("verification") if isinstance(raw, dict) else None},
|
|
243
|
+
legacy=raw,
|
|
244
|
+
)
|
|
245
|
+
|
|
246
|
+
def analyze(
|
|
247
|
+
self,
|
|
248
|
+
*,
|
|
249
|
+
profile: str,
|
|
250
|
+
app_key: str,
|
|
251
|
+
dimensions: list[Any],
|
|
252
|
+
metrics: list[Any],
|
|
253
|
+
filters: list[Any],
|
|
254
|
+
sort: list[Any],
|
|
255
|
+
limit: int,
|
|
256
|
+
strict_full: bool,
|
|
257
|
+
view_id: str | None,
|
|
258
|
+
list_type: int | None,
|
|
259
|
+
view_key: str | None,
|
|
260
|
+
view_name: str | None,
|
|
261
|
+
output_profile: str = "normal",
|
|
262
|
+
) -> dict:
|
|
263
|
+
try:
|
|
264
|
+
raw = self._tools.record.record_analyze(
|
|
265
|
+
profile=profile,
|
|
266
|
+
app_key=app_key,
|
|
267
|
+
dimensions=dimensions,
|
|
268
|
+
metrics=metrics,
|
|
269
|
+
filters=filters,
|
|
270
|
+
sort=sort,
|
|
271
|
+
limit=limit,
|
|
272
|
+
strict_full=strict_full,
|
|
273
|
+
view_id=view_id,
|
|
274
|
+
list_type=list_type,
|
|
275
|
+
view_key=view_key,
|
|
276
|
+
view_name=view_name,
|
|
277
|
+
output_profile=output_profile,
|
|
278
|
+
)
|
|
279
|
+
except Exception as error: # noqa: BLE001
|
|
280
|
+
return normalize_exception(error)
|
|
281
|
+
return success_result(
|
|
282
|
+
"RECORDS_ANALYZED",
|
|
283
|
+
"已完成数据分析",
|
|
284
|
+
data=tool_payload(raw),
|
|
285
|
+
warnings=raw.get("warnings") if isinstance(raw, dict) and isinstance(raw.get("warnings"), list) else [],
|
|
286
|
+
meta={"profile": profile},
|
|
287
|
+
legacy=raw,
|
|
288
|
+
)
|
|
289
|
+
|
|
290
|
+
def run_code(
|
|
291
|
+
self,
|
|
292
|
+
*,
|
|
293
|
+
profile: str,
|
|
294
|
+
app_key: str,
|
|
295
|
+
record_id: int,
|
|
296
|
+
code_block_field: str,
|
|
297
|
+
role: int,
|
|
298
|
+
workflow_node_id: int | None,
|
|
299
|
+
answers: list[Any],
|
|
300
|
+
fields: dict[str, Any],
|
|
301
|
+
manual: bool,
|
|
302
|
+
verify_writeback: bool,
|
|
303
|
+
force_refresh_form: bool,
|
|
304
|
+
output_profile: str = "normal",
|
|
305
|
+
) -> dict:
|
|
306
|
+
try:
|
|
307
|
+
raw = self._tools.code_block.record_code_block_run(
|
|
308
|
+
profile=profile,
|
|
309
|
+
app_key=app_key,
|
|
310
|
+
record_id=record_id,
|
|
311
|
+
code_block_field=code_block_field,
|
|
312
|
+
role=role,
|
|
313
|
+
workflow_node_id=workflow_node_id,
|
|
314
|
+
answers=answers,
|
|
315
|
+
fields=fields,
|
|
316
|
+
manual=manual,
|
|
317
|
+
verify_writeback=verify_writeback,
|
|
318
|
+
force_refresh_form=force_refresh_form,
|
|
319
|
+
output_profile=output_profile,
|
|
320
|
+
)
|
|
321
|
+
except Exception as error: # noqa: BLE001
|
|
322
|
+
return normalize_exception(error)
|
|
323
|
+
return success_result(
|
|
324
|
+
"CODE_BLOCK_EXECUTED",
|
|
325
|
+
"已执行代码块字段",
|
|
326
|
+
data=tool_payload(raw),
|
|
327
|
+
warnings=raw.get("warnings") if isinstance(raw, dict) and isinstance(raw.get("warnings"), list) else [],
|
|
328
|
+
meta={"profile": profile, "verification": raw.get("verification") if isinstance(raw, dict) else None},
|
|
329
|
+
legacy=raw,
|
|
330
|
+
)
|
|
331
|
+
|
|
332
|
+
def member_candidates(
|
|
333
|
+
self,
|
|
334
|
+
*,
|
|
335
|
+
profile: str,
|
|
336
|
+
app_key: str,
|
|
337
|
+
field_id: int,
|
|
338
|
+
keyword: str,
|
|
339
|
+
page_num: int,
|
|
340
|
+
page_size: int,
|
|
341
|
+
) -> dict:
|
|
342
|
+
try:
|
|
343
|
+
raw = self._tools.record.record_member_candidates(
|
|
344
|
+
profile=profile,
|
|
345
|
+
app_key=app_key,
|
|
346
|
+
field_id=field_id,
|
|
347
|
+
keyword=keyword,
|
|
348
|
+
page_num=page_num,
|
|
349
|
+
page_size=page_size,
|
|
350
|
+
)
|
|
351
|
+
except Exception as error: # noqa: BLE001
|
|
352
|
+
return normalize_exception(error)
|
|
353
|
+
return success_result(
|
|
354
|
+
"RECORD_MEMBER_CANDIDATES_READY",
|
|
355
|
+
"已读取成员候选范围",
|
|
356
|
+
data=tool_payload(raw),
|
|
357
|
+
warnings=raw.get("warnings") if isinstance(raw, dict) and isinstance(raw.get("warnings"), list) else [],
|
|
358
|
+
meta={"profile": profile},
|
|
359
|
+
legacy=raw,
|
|
360
|
+
)
|
|
361
|
+
|
|
362
|
+
def department_candidates(
|
|
363
|
+
self,
|
|
364
|
+
*,
|
|
365
|
+
profile: str,
|
|
366
|
+
app_key: str,
|
|
367
|
+
field_id: int,
|
|
368
|
+
keyword: str,
|
|
369
|
+
page_num: int,
|
|
370
|
+
page_size: int,
|
|
371
|
+
) -> dict:
|
|
372
|
+
try:
|
|
373
|
+
raw = self._tools.record.record_department_candidates(
|
|
374
|
+
profile=profile,
|
|
375
|
+
app_key=app_key,
|
|
376
|
+
field_id=field_id,
|
|
377
|
+
keyword=keyword,
|
|
378
|
+
page_num=page_num,
|
|
379
|
+
page_size=page_size,
|
|
380
|
+
)
|
|
381
|
+
except Exception as error: # noqa: BLE001
|
|
382
|
+
return normalize_exception(error)
|
|
383
|
+
return success_result(
|
|
384
|
+
"RECORD_DEPARTMENT_CANDIDATES_READY",
|
|
385
|
+
"已读取部门候选范围",
|
|
386
|
+
data=tool_payload(raw),
|
|
387
|
+
warnings=raw.get("warnings") if isinstance(raw, dict) and isinstance(raw.get("warnings"), list) else [],
|
|
388
|
+
meta={"profile": profile},
|
|
389
|
+
legacy=raw,
|
|
390
|
+
)
|
|
391
|
+
|
|
392
|
+
|
|
393
|
+
def _extract_record_id(data: Any) -> int | None:
|
|
394
|
+
if not isinstance(data, dict):
|
|
395
|
+
return None
|
|
396
|
+
value = data.get("record_id")
|
|
397
|
+
if isinstance(value, int):
|
|
398
|
+
return value
|
|
399
|
+
resource = data.get("resource")
|
|
400
|
+
if isinstance(resource, dict) and isinstance(resource.get("record_id"), int):
|
|
401
|
+
return resource.get("record_id")
|
|
402
|
+
return None
|
|
403
|
+
|
|
404
|
+
|
|
405
|
+
def _extract_record_ids(data: Any) -> list[int]:
|
|
406
|
+
if not isinstance(data, dict):
|
|
407
|
+
return []
|
|
408
|
+
value = data.get("record_ids")
|
|
409
|
+
if isinstance(value, list):
|
|
410
|
+
return [item for item in value if isinstance(item, int)]
|
|
411
|
+
resource = data.get("resource")
|
|
412
|
+
if isinstance(resource, dict) and isinstance(resource.get("record_ids"), list):
|
|
413
|
+
return [item for item in resource["record_ids"] if isinstance(item, int)]
|
|
414
|
+
record_id = _extract_record_id(data)
|
|
415
|
+
return [record_id] if record_id is not None else []
|