@qingflow-tech/qingflow-app-builder-mcp 1.0.16 → 1.0.17
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/record.py +2 -0
- package/src/qingflow_mcp/cli/commands/task.py +28 -41
- package/src/qingflow_mcp/server.py +3 -3
- package/src/qingflow_mcp/server_app_user.py +3 -3
- package/src/qingflow_mcp/tools/record_tools.py +7 -2
- package/src/qingflow_mcp/tools/task_context_tools.py +39 -31
package/README.md
CHANGED
|
@@ -3,13 +3,13 @@
|
|
|
3
3
|
Install:
|
|
4
4
|
|
|
5
5
|
```bash
|
|
6
|
-
npm install @qingflow-tech/qingflow-app-builder-mcp@1.0.
|
|
6
|
+
npm install @qingflow-tech/qingflow-app-builder-mcp@1.0.17
|
|
7
7
|
```
|
|
8
8
|
|
|
9
9
|
Run:
|
|
10
10
|
|
|
11
11
|
```bash
|
|
12
|
-
npx -y -p @qingflow-tech/qingflow-app-builder-mcp@1.0.
|
|
12
|
+
npx -y -p @qingflow-tech/qingflow-app-builder-mcp@1.0.17 qingflow-app-builder-mcp
|
|
13
13
|
```
|
|
14
14
|
|
|
15
15
|
Environment:
|
package/package.json
CHANGED
package/pyproject.toml
CHANGED
|
@@ -110,6 +110,7 @@ def register(subparsers: argparse._SubParsersAction[argparse.ArgumentParser]) ->
|
|
|
110
110
|
list_parser.add_argument("--where-file")
|
|
111
111
|
list_parser.add_argument("--order-by-file")
|
|
112
112
|
list_parser.add_argument("--page", type=int, default=1)
|
|
113
|
+
list_parser.add_argument("--page-size", type=int, default=10)
|
|
113
114
|
list_parser.add_argument("--view-id")
|
|
114
115
|
list_parser.add_argument("--list-type", dest="legacy_list_type", type=int, help=argparse.SUPPRESS)
|
|
115
116
|
list_parser.add_argument("--view-key", dest="legacy_view_key", help=argparse.SUPPRESS)
|
|
@@ -367,6 +368,7 @@ def _handle_list(args: argparse.Namespace, context: CliContext) -> dict:
|
|
|
367
368
|
where=load_list_arg(args.where_file, option_name="--where-file"),
|
|
368
369
|
order_by=load_list_arg(args.order_by_file, option_name="--order-by-file"),
|
|
369
370
|
page=args.page,
|
|
371
|
+
page_size=args.page_size,
|
|
370
372
|
view_id=args.view_id,
|
|
371
373
|
)
|
|
372
374
|
|
|
@@ -47,20 +47,14 @@ def register(subparsers: argparse._SubParsersAction[argparse.ArgumentParser]) ->
|
|
|
47
47
|
list_parser.add_argument("--page-size", type=int, default=20)
|
|
48
48
|
list_parser.set_defaults(handler=_handle_list, format_hint="task_list")
|
|
49
49
|
|
|
50
|
-
get = task_subparsers.add_parser("get", help="
|
|
51
|
-
get.add_argument("--task-id")
|
|
52
|
-
get.add_argument("--app-key")
|
|
53
|
-
get.add_argument("--record-id")
|
|
54
|
-
get.add_argument("--workflow-node-id", type=int)
|
|
50
|
+
get = task_subparsers.add_parser("get", help="读取待办详情;--task-id 必须来自 task list 的 data.items[].task_id")
|
|
51
|
+
get.add_argument("--task-id", help="来自 `qingflow --json task list` 的 data.items[].task_id;不是列表序号")
|
|
55
52
|
get.add_argument("--include-candidates", action=argparse.BooleanOptionalAction, default=True)
|
|
56
53
|
get.add_argument("--include-associated-reports", action=argparse.BooleanOptionalAction, default=True)
|
|
57
|
-
get.set_defaults(handler=_handle_get, format_hint="task_get")
|
|
54
|
+
get.set_defaults(handler=_handle_get, format_hint="task_get", app_key="", record_id="", workflow_node_id=0)
|
|
58
55
|
|
|
59
|
-
action = task_subparsers.add_parser("action", help="
|
|
60
|
-
action.add_argument("--task-id")
|
|
61
|
-
action.add_argument("--app-key")
|
|
62
|
-
action.add_argument("--record-id")
|
|
63
|
-
action.add_argument("--workflow-node-id", type=int)
|
|
56
|
+
action = task_subparsers.add_parser("action", help="执行待办动作;--task-id 必须来自 task list 的 data.items[].task_id")
|
|
57
|
+
action.add_argument("--task-id", help="来自 `qingflow --json task list` 的 data.items[].task_id;不是列表序号")
|
|
64
58
|
action.add_argument("--action", help="不传时在交互终端中选择当前待办可执行动作")
|
|
65
59
|
action.add_argument("--payload-file")
|
|
66
60
|
action.add_argument("--fields-file")
|
|
@@ -68,24 +62,27 @@ def register(subparsers: argparse._SubParsersAction[argparse.ArgumentParser]) ->
|
|
|
68
62
|
handler=_handle_action,
|
|
69
63
|
format_hint="task_action_execute",
|
|
70
64
|
hide_effective_context_line=True,
|
|
65
|
+
app_key="",
|
|
66
|
+
record_id="",
|
|
67
|
+
workflow_node_id=0,
|
|
71
68
|
)
|
|
72
69
|
|
|
73
|
-
report = task_subparsers.add_parser("report", help="
|
|
74
|
-
report.add_argument("--task-id")
|
|
75
|
-
report.add_argument("--app-key")
|
|
76
|
-
report.add_argument("--record-id")
|
|
77
|
-
report.add_argument("--workflow-node-id", type=int)
|
|
70
|
+
report = task_subparsers.add_parser("report", help="读取待办关联报表详情;--task-id 必须来自 task list 的 data.items[].task_id")
|
|
71
|
+
report.add_argument("--task-id", help="来自 `qingflow --json task list` 的 data.items[].task_id;不是列表序号")
|
|
78
72
|
report.add_argument("--report-id", type=int, help="不传时在交互终端中选择关联报表")
|
|
79
73
|
report.add_argument("--page", type=int, default=1)
|
|
80
74
|
report.add_argument("--page-size", type=int, default=20)
|
|
81
|
-
report.set_defaults(
|
|
75
|
+
report.set_defaults(
|
|
76
|
+
handler=_handle_report,
|
|
77
|
+
format_hint="task_associated_report_detail_get",
|
|
78
|
+
app_key="",
|
|
79
|
+
record_id="",
|
|
80
|
+
workflow_node_id=0,
|
|
81
|
+
)
|
|
82
82
|
|
|
83
|
-
log = task_subparsers.add_parser("log", help="
|
|
84
|
-
log.add_argument("--task-id")
|
|
85
|
-
log.
|
|
86
|
-
log.add_argument("--record-id")
|
|
87
|
-
log.add_argument("--workflow-node-id", type=int)
|
|
88
|
-
log.set_defaults(handler=_handle_log, format_hint="")
|
|
83
|
+
log = task_subparsers.add_parser("log", help="读取流程日志;--task-id 必须来自 task list 的 data.items[].task_id")
|
|
84
|
+
log.add_argument("--task-id", help="来自 `qingflow --json task list` 的 data.items[].task_id;不是列表序号")
|
|
85
|
+
log.set_defaults(handler=_handle_log, format_hint="", app_key="", record_id="", workflow_node_id=0)
|
|
89
86
|
|
|
90
87
|
|
|
91
88
|
def _handle_list(args: argparse.Namespace, context: CliContext) -> dict:
|
|
@@ -243,30 +240,20 @@ def _run_task_workbench_task_loop(args: argparse.Namespace, context: CliContext)
|
|
|
243
240
|
def _resolve_task_locator_or_select(args: argparse.Namespace, context: CliContext, *, tool_name: str) -> dict | None:
|
|
244
241
|
if (args.task_id or "").strip():
|
|
245
242
|
return None
|
|
246
|
-
has_app_key = bool((args.app_key or "").strip())
|
|
247
|
-
has_record_id = bool((args.record_id or "").strip())
|
|
248
|
-
has_workflow_node_id = int(args.workflow_node_id or 0) > 0
|
|
249
|
-
if has_app_key and has_record_id and has_workflow_node_id:
|
|
250
|
-
return None
|
|
251
|
-
if has_app_key or has_record_id or has_workflow_node_id:
|
|
252
|
-
raise_config_error(
|
|
253
|
-
f"{tool_name} requires --task-id, or --app-key together with --record-id and --workflow-node-id",
|
|
254
|
-
fix_hint="Either pass `--task-id TASK_ID`, or provide the full locator triple `--app-key --record-id --workflow-node-id`.",
|
|
255
|
-
)
|
|
256
243
|
|
|
257
244
|
selection = _choose_todo_task_interactively(args, context, tool_name=tool_name)
|
|
258
245
|
if selection.status == "unavailable":
|
|
259
246
|
raise_config_error(
|
|
260
|
-
f"{tool_name} requires --task-id
|
|
247
|
+
f"{tool_name} requires --task-id from task list data.items[].task_id",
|
|
261
248
|
fix_hint=(
|
|
262
249
|
"Retry in an interactive terminal to choose from current todo tasks, "
|
|
263
|
-
"or pass `--task-id
|
|
250
|
+
"or pass `--task-id` from `task list` explicitly."
|
|
264
251
|
),
|
|
265
252
|
)
|
|
266
253
|
if selection.status == "empty":
|
|
267
254
|
raise_config_error(
|
|
268
255
|
selection.message or f"{tool_name} could not open a selector because no current todo tasks are available.",
|
|
269
|
-
fix_hint="Run `task list` to confirm current todo tasks,
|
|
256
|
+
fix_hint="Run `task list` to confirm current todo tasks, then pass the selected `data.items[].task_id`.",
|
|
270
257
|
)
|
|
271
258
|
if selection.status == "cancelled":
|
|
272
259
|
return cancelled_result(selection.message or "已取消")
|
|
@@ -327,7 +314,7 @@ def _choose_todo_task_interactively(
|
|
|
327
314
|
args,
|
|
328
315
|
title=title,
|
|
329
316
|
unavailable_message=(
|
|
330
|
-
f"{tool_name} requires --task-id
|
|
317
|
+
f"{tool_name} requires --task-id from task list data.items[].task_id"
|
|
331
318
|
),
|
|
332
319
|
empty_message=f"{tool_name} could not open a selector because no current todo tasks are available.",
|
|
333
320
|
load_options=load_options,
|
|
@@ -347,7 +334,7 @@ def _resolve_report_id_or_select(args: argparse.Namespace, context: CliContext)
|
|
|
347
334
|
if selection.status == "empty":
|
|
348
335
|
raise_config_error(
|
|
349
336
|
selection.message or "task report could not open a selector because the selected task has no visible associated reports.",
|
|
350
|
-
fix_hint="Run `task get --task-id
|
|
337
|
+
fix_hint="Run `task get --task-id <data.items[].task_id>` to inspect `extras.associated_reports`, or choose another task.",
|
|
351
338
|
)
|
|
352
339
|
if selection.status == "cancelled":
|
|
353
340
|
return cancelled_result(selection.message or "已取消")
|
|
@@ -395,7 +382,7 @@ def _resolve_task_action_or_select(
|
|
|
395
382
|
if selection.status == "empty":
|
|
396
383
|
raise_config_error(
|
|
397
384
|
selection.message or "task action could not open an action selector because no interactive actions are available.",
|
|
398
|
-
fix_hint="Run `task get --task-id
|
|
385
|
+
fix_hint="Run `task get --task-id <data.items[].task_id>` to inspect available_actions, or pass a supported `--action` explicitly.",
|
|
399
386
|
)
|
|
400
387
|
if selection.status == "cancelled":
|
|
401
388
|
return cancelled_result(selection.message or "已取消")
|
|
@@ -476,7 +463,7 @@ def _resolve_action_payload_or_select(
|
|
|
476
463
|
if selection.status == "empty":
|
|
477
464
|
raise_config_error(
|
|
478
465
|
selection.message or "task rollback could not open a selector because no rollback candidates are visible.",
|
|
479
|
-
fix_hint="Run `task get --task-id
|
|
466
|
+
fix_hint="Run `task get --task-id <data.items[].task_id>` to inspect rollback candidates, or choose another action.",
|
|
480
467
|
)
|
|
481
468
|
if selection.status == "cancelled":
|
|
482
469
|
return cancelled_result(selection.message or "已取消")
|
|
@@ -493,7 +480,7 @@ def _resolve_action_payload_or_select(
|
|
|
493
480
|
if selection.status == "empty":
|
|
494
481
|
raise_config_error(
|
|
495
482
|
selection.message or "task transfer could not open a selector because no transfer candidates are visible.",
|
|
496
|
-
fix_hint="Run `task get --task-id
|
|
483
|
+
fix_hint="Run `task get --task-id <data.items[].task_id>` to inspect transfer candidates, or choose another action.",
|
|
497
484
|
)
|
|
498
485
|
if selection.status == "cancelled":
|
|
499
486
|
return cancelled_result(selection.message or "已取消")
|
|
@@ -184,12 +184,12 @@ Use `record_code_block_run` when the user wants to execute a form code-block fie
|
|
|
184
184
|
`task_list -> task_get -> task_action_execute`
|
|
185
185
|
|
|
186
186
|
- `task_list` returns task-card summaries keyed by `task_id`.
|
|
187
|
-
-
|
|
188
|
-
- `
|
|
187
|
+
- For detail reads and actions, pass the exact `task_id` from `task_list.data.items[].task_id`.
|
|
188
|
+
- `task_id` is not a row number, list index, record id, or workflow node id.
|
|
189
|
+
- Do not reconstruct task actions from `app_key + record_id + workflow_node_id` unless the user explicitly provides that full locator for troubleshooting.
|
|
189
190
|
- `task_workflow_log_get(task_id=...)` and `task_associated_report_detail_get(task_id=...)` are also supported for the current todo context.
|
|
190
191
|
- Use `task_associated_report_detail_get` for associated view or report details.
|
|
191
192
|
- Use `task_workflow_log_get` for the current task context workflow log page. For full record-level data/workflow logs, first choose an accessible view with `app_get`, then call `record_logs_get(app_key, record_id, view_id)` with that same explicit `view_id`.
|
|
192
|
-
- Task actions operate on `app_key + record_id + workflow_node_id`, not `task_id`.
|
|
193
193
|
|
|
194
194
|
## Time Handling
|
|
195
195
|
|
|
@@ -189,12 +189,12 @@ Use export only when the user explicitly asks to export/download/generate an Exc
|
|
|
189
189
|
`task_list -> task_get -> task_action_execute`
|
|
190
190
|
|
|
191
191
|
- `task_list` returns task-card summaries keyed by `task_id`.
|
|
192
|
-
-
|
|
193
|
-
- `
|
|
192
|
+
- For detail reads and actions, pass the exact `task_id` from `task_list.data.items[].task_id`.
|
|
193
|
+
- `task_id` is not a row number, list index, record id, or workflow node id.
|
|
194
|
+
- Do not reconstruct task actions from `app_key + record_id + workflow_node_id` unless the user explicitly provides that full locator for troubleshooting.
|
|
194
195
|
- `task_workflow_log_get(task_id=...)` and `task_associated_report_detail_get(task_id=...)` are also supported for the current todo context.
|
|
195
196
|
- Use `task_associated_report_detail_get` for associated view or report details.
|
|
196
197
|
- Use `task_workflow_log_get` for the current task context workflow log page. For full record-level data/workflow logs, first choose an accessible view with `app_get`, then call `record_logs_get(app_key, record_id, view_id)` with that same explicit `view_id`.
|
|
197
|
-
- Task actions operate on `app_key + record_id + workflow_node_id`, not `task_id`.
|
|
198
198
|
- Treat `task_action_execute` as the tool-level action enum surface; the current task's real actions are only the ones listed in `task_get.capabilities.available_actions`.
|
|
199
199
|
- Use `task_action_execute(action="save_only", fields=...)` when the user wants to save editable field changes on the current node without advancing the workflow.
|
|
200
200
|
- `save_only` is exposed only when the backend current-node `editableQueIds` signal returns a non-empty result; MCP no longer infers `save_only` from local schema reconstruction.
|
|
@@ -438,6 +438,7 @@ class RecordTools(ToolBase):
|
|
|
438
438
|
where: list[JSONObject] | None = None,
|
|
439
439
|
order_by: list[JSONObject] | None = None,
|
|
440
440
|
page: int = 1,
|
|
441
|
+
page_size: int = DEFAULT_RECORD_LIST_RETURN_LIMIT,
|
|
441
442
|
view_id: str | None = None,
|
|
442
443
|
output_profile: str = "normal",
|
|
443
444
|
) -> JSONObject:
|
|
@@ -450,6 +451,7 @@ class RecordTools(ToolBase):
|
|
|
450
451
|
where=where or [],
|
|
451
452
|
order_by=order_by or [],
|
|
452
453
|
page=page,
|
|
454
|
+
page_size=page_size,
|
|
453
455
|
view_id=view_id,
|
|
454
456
|
list_type=None,
|
|
455
457
|
view_key=None,
|
|
@@ -1881,6 +1883,7 @@ class RecordTools(ToolBase):
|
|
|
1881
1883
|
order_by: list[JSONObject],
|
|
1882
1884
|
limit: int = DEFAULT_RECORD_LIST_RETURN_LIMIT,
|
|
1883
1885
|
page: int = 1,
|
|
1886
|
+
page_size: int = DEFAULT_RECORD_LIST_RETURN_LIMIT,
|
|
1884
1887
|
view_id: str | None = None,
|
|
1885
1888
|
list_type: int | None = None,
|
|
1886
1889
|
view_key: str | None = None,
|
|
@@ -1899,6 +1902,8 @@ class RecordTools(ToolBase):
|
|
|
1899
1902
|
raise_tool_error(QingflowApiError.config_error("limit must be positive"))
|
|
1900
1903
|
if page <= 0:
|
|
1901
1904
|
raise_tool_error(QingflowApiError.config_error("page must be positive"))
|
|
1905
|
+
if page_size <= 0:
|
|
1906
|
+
raise_tool_error(QingflowApiError.config_error("page_size must be positive"))
|
|
1902
1907
|
if not (
|
|
1903
1908
|
_normalize_optional_text(view_id)
|
|
1904
1909
|
or list_type is not None
|
|
@@ -1971,12 +1976,12 @@ class RecordTools(ToolBase):
|
|
|
1971
1976
|
app_key=app_key,
|
|
1972
1977
|
view_route=view_route,
|
|
1973
1978
|
page_num=page,
|
|
1974
|
-
page_size=
|
|
1979
|
+
page_size=page_size,
|
|
1975
1980
|
query_key=normalized_query,
|
|
1976
1981
|
search_que_ids=resolved_query_fields or None,
|
|
1977
1982
|
match_rules=match_rules,
|
|
1978
1983
|
sort_rules=sort_rules,
|
|
1979
|
-
max_rows=limit,
|
|
1984
|
+
max_rows=min(limit, page_size),
|
|
1980
1985
|
selected_fields=selected_fields,
|
|
1981
1986
|
output_profile="verbose" if normalized_output_profile in {"verbose", "normalized"} else DEFAULT_OUTPUT_PROFILE,
|
|
1982
1987
|
)
|
|
@@ -85,33 +85,37 @@ class TaskContextTools(ToolBase):
|
|
|
85
85
|
page_size=page_size,
|
|
86
86
|
)
|
|
87
87
|
|
|
88
|
-
@mcp.tool(
|
|
88
|
+
@mcp.tool(
|
|
89
|
+
description=(
|
|
90
|
+
"Read one workflow task. Prefer task_id from task_list.data.items[].task_id; "
|
|
91
|
+
"task_id is not a row number, list index, record id, or workflow node id."
|
|
92
|
+
)
|
|
93
|
+
)
|
|
89
94
|
def task_get(
|
|
90
95
|
profile: str = DEFAULT_PROFILE,
|
|
91
96
|
task_id: str = "",
|
|
92
|
-
app_key: str = "",
|
|
93
|
-
record_id: str = "",
|
|
94
|
-
workflow_node_id: int = 0,
|
|
95
97
|
include_candidates: bool = True,
|
|
96
98
|
include_associated_reports: bool = True,
|
|
97
99
|
) -> dict[str, Any]:
|
|
98
100
|
return self.task_get(
|
|
99
101
|
profile=profile,
|
|
100
102
|
task_id=task_id,
|
|
101
|
-
app_key=
|
|
102
|
-
record_id=
|
|
103
|
-
workflow_node_id=
|
|
103
|
+
app_key="",
|
|
104
|
+
record_id="",
|
|
105
|
+
workflow_node_id=0,
|
|
104
106
|
include_candidates=include_candidates,
|
|
105
107
|
include_associated_reports=include_associated_reports,
|
|
106
108
|
)
|
|
107
109
|
|
|
108
|
-
@mcp.tool(
|
|
110
|
+
@mcp.tool(
|
|
111
|
+
description=(
|
|
112
|
+
self._high_risk_tool_description(operation="execute", target="workflow task action")
|
|
113
|
+
+ " Pass task_id from task_list.data.items[].task_id. Do not pass a row number, list index, record id, or workflow node id as task_id."
|
|
114
|
+
)
|
|
115
|
+
)
|
|
109
116
|
def task_action_execute(
|
|
110
117
|
profile: str = DEFAULT_PROFILE,
|
|
111
118
|
task_id: str = "",
|
|
112
|
-
app_key: str = "",
|
|
113
|
-
record_id: str = "",
|
|
114
|
-
workflow_node_id: int = 0,
|
|
115
119
|
action: str = "",
|
|
116
120
|
payload: dict[str, Any] | None = None,
|
|
117
121
|
fields: dict[str, Any] | None = None,
|
|
@@ -119,21 +123,23 @@ class TaskContextTools(ToolBase):
|
|
|
119
123
|
return self.task_action_execute(
|
|
120
124
|
profile=profile,
|
|
121
125
|
task_id=task_id,
|
|
122
|
-
app_key=
|
|
123
|
-
record_id=
|
|
124
|
-
workflow_node_id=
|
|
126
|
+
app_key="",
|
|
127
|
+
record_id="",
|
|
128
|
+
workflow_node_id=0,
|
|
125
129
|
action=action,
|
|
126
130
|
payload=payload or {},
|
|
127
131
|
fields=fields or {},
|
|
128
132
|
)
|
|
129
133
|
|
|
130
|
-
@mcp.tool(
|
|
134
|
+
@mcp.tool(
|
|
135
|
+
description=(
|
|
136
|
+
"Read a task-associated report. Pass task_id from task_list.data.items[].task_id; "
|
|
137
|
+
"task_id is not a row number, list index, record id, or workflow node id."
|
|
138
|
+
)
|
|
139
|
+
)
|
|
131
140
|
def task_associated_report_detail_get(
|
|
132
141
|
profile: str = DEFAULT_PROFILE,
|
|
133
142
|
task_id: str = "",
|
|
134
|
-
app_key: str = "",
|
|
135
|
-
record_id: str = "",
|
|
136
|
-
workflow_node_id: int = 0,
|
|
137
143
|
report_id: int = 0,
|
|
138
144
|
page: int = 1,
|
|
139
145
|
page_size: int = 20,
|
|
@@ -141,28 +147,30 @@ class TaskContextTools(ToolBase):
|
|
|
141
147
|
return self.task_associated_report_detail_get(
|
|
142
148
|
profile=profile,
|
|
143
149
|
task_id=task_id,
|
|
144
|
-
app_key=
|
|
145
|
-
record_id=
|
|
146
|
-
workflow_node_id=
|
|
150
|
+
app_key="",
|
|
151
|
+
record_id="",
|
|
152
|
+
workflow_node_id=0,
|
|
147
153
|
report_id=report_id,
|
|
148
154
|
page=page,
|
|
149
155
|
page_size=page_size,
|
|
150
156
|
)
|
|
151
157
|
|
|
152
|
-
@mcp.tool(
|
|
158
|
+
@mcp.tool(
|
|
159
|
+
description=(
|
|
160
|
+
"Read workflow log for one task context. Pass task_id from task_list.data.items[].task_id; "
|
|
161
|
+
"task_id is not a row number, list index, record id, or workflow node id."
|
|
162
|
+
)
|
|
163
|
+
)
|
|
153
164
|
def task_workflow_log_get(
|
|
154
165
|
profile: str = DEFAULT_PROFILE,
|
|
155
166
|
task_id: str = "",
|
|
156
|
-
app_key: str = "",
|
|
157
|
-
record_id: str = "",
|
|
158
|
-
workflow_node_id: int = 0,
|
|
159
167
|
) -> dict[str, Any]:
|
|
160
168
|
return self.task_workflow_log_get(
|
|
161
169
|
profile=profile,
|
|
162
170
|
task_id=task_id,
|
|
163
|
-
app_key=
|
|
164
|
-
record_id=
|
|
165
|
-
workflow_node_id=
|
|
171
|
+
app_key="",
|
|
172
|
+
record_id="",
|
|
173
|
+
workflow_node_id=0,
|
|
166
174
|
)
|
|
167
175
|
|
|
168
176
|
@tool_cn_name("任务上下文列表")
|
|
@@ -1302,14 +1310,14 @@ class TaskContextTools(ToolBase):
|
|
|
1302
1310
|
searched = ", ".join(incomplete_task_boxes)
|
|
1303
1311
|
raise_tool_error(
|
|
1304
1312
|
QingflowApiError.config_error(
|
|
1305
|
-
f"task_id={task_id_text} resolved to an incomplete task locator in task_box={searched};
|
|
1313
|
+
f"task_id={task_id_text} resolved to an incomplete task locator in task_box={searched}; rerun task_list and pass the exact data.items[].task_id. Do not substitute a row number or rebuild the locator from app_key/record_id/workflow_node_id."
|
|
1306
1314
|
)
|
|
1307
1315
|
)
|
|
1308
1316
|
if inaccessible_task_boxes:
|
|
1309
1317
|
searched = ", ".join(str(item.get("task_box")) for item in inaccessible_task_boxes)
|
|
1310
1318
|
raise_tool_error(
|
|
1311
1319
|
QingflowApiError.config_error(
|
|
1312
|
-
f"task_id={task_id_text} was not found in visible task boxes; some task boxes were not searchable in the current permission context: {searched}",
|
|
1320
|
+
f"task_id={task_id_text} was not found in visible task boxes; some task boxes were not searchable in the current permission context: {searched}. Rerun task_list and use data.items[].task_id; do not substitute a row number or rebuild the locator.",
|
|
1313
1321
|
details={
|
|
1314
1322
|
"task_id": task_id_text,
|
|
1315
1323
|
"searched_task_boxes": list(searched_task_boxes),
|
|
@@ -1319,7 +1327,7 @@ class TaskContextTools(ToolBase):
|
|
|
1319
1327
|
)
|
|
1320
1328
|
raise_tool_error(
|
|
1321
1329
|
QingflowApiError.config_error(
|
|
1322
|
-
f"task_id={task_id_text} was not found in the current visible task boxes (todo, initiated, cc, done)"
|
|
1330
|
+
f"task_id={task_id_text} was not found in the current visible task boxes (todo, initiated, cc, done). Rerun task_list and pass data.items[].task_id; do not use the displayed row number or guess app_key/record_id/workflow_node_id."
|
|
1323
1331
|
)
|
|
1324
1332
|
)
|
|
1325
1333
|
|