@josephyan/qingflow-cli 0.2.0-beta.984 → 0.2.0-beta.986

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.
Files changed (43) hide show
  1. package/README.md +2 -2
  2. package/docs/local-agent-install.md +70 -11
  3. package/package.json +1 -1
  4. package/pyproject.toml +1 -1
  5. package/src/qingflow_mcp/__init__.py +1 -1
  6. package/src/qingflow_mcp/builder_facade/service.py +47 -21
  7. package/src/qingflow_mcp/cli/commands/auth.py +14 -43
  8. package/src/qingflow_mcp/cli/commands/task.py +4 -1
  9. package/src/qingflow_mcp/cli/commands/workspace.py +0 -8
  10. package/src/qingflow_mcp/cli/formatters.py +0 -21
  11. package/src/qingflow_mcp/config.py +39 -0
  12. package/src/qingflow_mcp/errors.py +2 -2
  13. package/src/qingflow_mcp/public_surface.py +2 -6
  14. package/src/qingflow_mcp/response_trim.py +1 -8
  15. package/src/qingflow_mcp/server.py +1 -1
  16. package/src/qingflow_mcp/server_app_builder.py +4 -28
  17. package/src/qingflow_mcp/server_app_user.py +4 -28
  18. package/src/qingflow_mcp/session_store.py +31 -5
  19. package/src/qingflow_mcp/tools/ai_builder_tools.py +117 -1
  20. package/src/qingflow_mcp/tools/app_tools.py +51 -1
  21. package/src/qingflow_mcp/tools/approval_tools.py +82 -1
  22. package/src/qingflow_mcp/tools/auth_tools.py +258 -288
  23. package/src/qingflow_mcp/tools/base.py +204 -4
  24. package/src/qingflow_mcp/tools/code_block_tools.py +21 -0
  25. package/src/qingflow_mcp/tools/custom_button_tools.py +24 -1
  26. package/src/qingflow_mcp/tools/directory_tools.py +28 -1
  27. package/src/qingflow_mcp/tools/feedback_tools.py +8 -0
  28. package/src/qingflow_mcp/tools/file_tools.py +25 -1
  29. package/src/qingflow_mcp/tools/import_tools.py +40 -1
  30. package/src/qingflow_mcp/tools/navigation_tools.py +34 -1
  31. package/src/qingflow_mcp/tools/package_tools.py +37 -1
  32. package/src/qingflow_mcp/tools/portal_tools.py +28 -1
  33. package/src/qingflow_mcp/tools/qingbi_report_tools.py +38 -1
  34. package/src/qingflow_mcp/tools/record_tools.py +255 -2
  35. package/src/qingflow_mcp/tools/repository_dev_tools.py +21 -2
  36. package/src/qingflow_mcp/tools/resource_read_tools.py +23 -1
  37. package/src/qingflow_mcp/tools/role_tools.py +19 -1
  38. package/src/qingflow_mcp/tools/solution_tools.py +56 -1
  39. package/src/qingflow_mcp/tools/task_context_tools.py +205 -6
  40. package/src/qingflow_mcp/tools/task_tools.py +49 -3
  41. package/src/qingflow_mcp/tools/view_tools.py +56 -1
  42. package/src/qingflow_mcp/tools/workflow_tools.py +65 -1
  43. package/src/qingflow_mcp/tools/workspace_tools.py +14 -225
@@ -8,15 +8,26 @@ from ..config import DEFAULT_PROFILE
8
8
  from ..errors import QingflowApiError, raise_tool_error
9
9
  from ..json_types import JSONObject
10
10
  from ..list_type_labels import get_record_list_type_label
11
- from .base import ToolBase
11
+ from .base import ToolBase, tool_cn_name
12
12
 
13
13
 
14
14
  class ApprovalTools(ToolBase):
15
+ """审批工具(中文名:审批数据与候选范围)。
16
+
17
+ 类型:审批辅助工具。
18
+ 主要职责:
19
+ 1. 查询审批相关列表与详情;
20
+ 2. 提供审批节点候选范围与运行时上下文辅助;
21
+ 3. 为任务执行类工具提供审批侧数据支撑。
22
+ """
23
+
15
24
  def __init__(self, sessions, backend) -> None: # type: ignore[no-untyped-def]
25
+ """执行内部辅助逻辑。"""
16
26
  super().__init__(sessions, backend)
17
27
  self._form_id_cache: dict[str, int] = {}
18
28
 
19
29
  def register(self, mcp: FastMCP) -> None:
30
+ """注册当前工具到 MCP 服务。"""
20
31
  @mcp.tool()
21
32
  def record_comment_write(
22
33
  profile: str = DEFAULT_PROFILE,
@@ -137,7 +148,9 @@ class ApprovalTools(ToolBase):
137
148
  keyword=keyword,
138
149
  )
139
150
 
151
+ @tool_cn_name("写评论")
140
152
  def record_comment_write(self, *, profile: str, app_key: str, record_id: int, payload: dict[str, Any]) -> dict[str, Any]:
153
+ """执行记录相关逻辑。"""
141
154
  raw = self.record_comment_add(profile=profile, app_key=app_key, apply_id=record_id, payload=payload)
142
155
  return self._public_action_response(
143
156
  raw,
@@ -146,6 +159,7 @@ class ApprovalTools(ToolBase):
146
159
  selection={},
147
160
  )
148
161
 
162
+ @tool_cn_name("评论提及")
149
163
  def record_comment_mentions(
150
164
  self,
151
165
  *,
@@ -157,6 +171,7 @@ class ApprovalTools(ToolBase):
157
171
  list_type: int | None = None,
158
172
  keyword: str | None = None,
159
173
  ) -> dict[str, Any]:
174
+ """执行记录相关逻辑。"""
160
175
  raw = self.record_comment_mention_candidates(
161
176
  profile=profile,
162
177
  app_key=app_key,
@@ -180,7 +195,9 @@ class ApprovalTools(ToolBase):
180
195
  selection={"app_key": app_key, "record_id": record_id, "list_type": list_type, "keyword": keyword},
181
196
  )
182
197
 
198
+ @tool_cn_name("任务通过")
183
199
  def task_approve(self, *, profile: str, app_key: str, record_id: int, payload: dict[str, Any], fields: dict[str, Any] | None = None) -> dict[str, Any]:
200
+ """执行任务相关逻辑。"""
184
201
  if fields:
185
202
  return self._delegate_task_action(
186
203
  profile=profile,
@@ -200,7 +217,9 @@ class ApprovalTools(ToolBase):
200
217
  human_review=True,
201
218
  )
202
219
 
220
+ @tool_cn_name("任务拒绝")
203
221
  def task_reject(self, *, profile: str, app_key: str, record_id: int, payload: dict[str, Any], fields: dict[str, Any] | None = None) -> dict[str, Any]:
222
+ """执行任务相关逻辑。"""
204
223
  if fields:
205
224
  return self._delegate_task_action(
206
225
  profile=profile,
@@ -220,7 +239,9 @@ class ApprovalTools(ToolBase):
220
239
  human_review=True,
221
240
  )
222
241
 
242
+ @tool_cn_name("任务退回候选")
223
243
  def task_rollback_candidates(self, *, profile: str, app_key: str, record_id: int, workflow_node_id: int) -> dict[str, Any]:
244
+ """执行任务相关逻辑。"""
224
245
  raw = self.record_rollback_candidates(profile=profile, app_key=app_key, apply_id=record_id, audit_node_id=workflow_node_id)
225
246
  items = _approval_page_items(raw.get("result"))
226
247
  return self._public_page_response(
@@ -230,7 +251,9 @@ class ApprovalTools(ToolBase):
230
251
  selection={"app_key": app_key, "record_id": record_id, "workflow_node_id": workflow_node_id},
231
252
  )
232
253
 
254
+ @tool_cn_name("任务退回")
233
255
  def task_rollback(self, *, profile: str, app_key: str, record_id: int, payload: dict[str, Any], fields: dict[str, Any] | None = None) -> dict[str, Any]:
256
+ """执行任务相关逻辑。"""
234
257
  if fields:
235
258
  return self._delegate_task_action(
236
259
  profile=profile,
@@ -250,7 +273,9 @@ class ApprovalTools(ToolBase):
250
273
  human_review=True,
251
274
  )
252
275
 
276
+ @tool_cn_name("任务转交")
253
277
  def task_transfer(self, *, profile: str, app_key: str, record_id: int, payload: dict[str, Any], fields: dict[str, Any] | None = None) -> dict[str, Any]:
278
+ """执行任务相关逻辑。"""
254
279
  if fields:
255
280
  return self._delegate_task_action(
256
281
  profile=profile,
@@ -271,6 +296,7 @@ class ApprovalTools(ToolBase):
271
296
  human_review=True,
272
297
  )
273
298
 
299
+ @tool_cn_name("任务仅保存")
274
300
  def task_save_only(
275
301
  self,
276
302
  *,
@@ -280,6 +306,7 @@ class ApprovalTools(ToolBase):
280
306
  workflow_node_id: int,
281
307
  fields: dict[str, Any],
282
308
  ) -> dict[str, Any]:
309
+ """执行任务相关逻辑。"""
283
310
  return self._delegate_task_action(
284
311
  profile=profile,
285
312
  app_key=app_key,
@@ -291,6 +318,7 @@ class ApprovalTools(ToolBase):
291
318
  workflow_node_id=workflow_node_id,
292
319
  )
293
320
 
321
+ @tool_cn_name("任务转交候选")
294
322
  def task_transfer_candidates(
295
323
  self,
296
324
  *,
@@ -302,6 +330,7 @@ class ApprovalTools(ToolBase):
302
330
  workflow_node_id: int = 0,
303
331
  keyword: str | None = None,
304
332
  ) -> dict[str, Any]:
333
+ """执行任务相关逻辑。"""
305
334
  raw = self.record_transfer_candidates(
306
335
  profile=profile,
307
336
  app_key=app_key,
@@ -327,7 +356,9 @@ class ApprovalTools(ToolBase):
327
356
  selection={"app_key": app_key, "record_id": record_id, "workflow_node_id": workflow_node_id, "keyword": keyword},
328
357
  )
329
358
 
359
+ @tool_cn_name("新增评论")
330
360
  def record_comment_add(self, *, profile: str, app_key: str, apply_id: int, payload: dict[str, Any]) -> dict[str, Any]:
361
+ """执行记录相关逻辑。"""
331
362
  self._require_app_and_apply(app_key, apply_id)
332
363
  self._validate_comment_payload(payload)
333
364
 
@@ -344,7 +375,9 @@ class ApprovalTools(ToolBase):
344
375
 
345
376
  return self._run(profile, runner)
346
377
 
378
+ @tool_cn_name("评论列表")
347
379
  def record_comment_list(self, *, profile: str, app_key: str, apply_id: int, page_size: int = 20, list_type: int | None = None, page_num: int | None = 1) -> dict[str, Any]:
380
+ """执行记录相关逻辑。"""
348
381
  self._require_app_and_apply(app_key, apply_id)
349
382
 
350
383
  def runner(session_profile, context):
@@ -380,6 +413,7 @@ class ApprovalTools(ToolBase):
380
413
  selection={"app_key": app_key, "record_id": apply_id, "list_type": list_type},
381
414
  )
382
415
 
416
+ @tool_cn_name("评论提及候选")
383
417
  def record_comment_mention_candidates(
384
418
  self,
385
419
  *,
@@ -391,6 +425,7 @@ class ApprovalTools(ToolBase):
391
425
  list_type: int | None = None,
392
426
  keyword: str | None = None,
393
427
  ) -> dict[str, Any]:
428
+ """执行记录相关逻辑。"""
394
429
  self._require_app_and_apply(app_key, apply_id)
395
430
 
396
431
  def runner(session_profile, context):
@@ -413,7 +448,9 @@ class ApprovalTools(ToolBase):
413
448
 
414
449
  return self._run(profile, runner)
415
450
 
451
+ @tool_cn_name("评论标记已读")
416
452
  def record_comment_mark_read(self, *, profile: str, app_key: str, apply_id: int) -> dict[str, Any]:
453
+ """执行记录相关逻辑。"""
417
454
  self._require_app_and_apply(app_key, apply_id)
418
455
 
419
456
  def runner(session_profile, context):
@@ -435,7 +472,9 @@ class ApprovalTools(ToolBase):
435
472
  selection={},
436
473
  )
437
474
 
475
+ @tool_cn_name("评论统计")
438
476
  def record_comment_stats(self, *, profile: str, app_key: str, apply_id: int) -> dict[str, Any]:
477
+ """执行记录相关逻辑。"""
439
478
  self._require_app_and_apply(app_key, apply_id)
440
479
 
441
480
  def runner(session_profile, context):
@@ -451,7 +490,9 @@ class ApprovalTools(ToolBase):
451
490
 
452
491
  return self._run(profile, runner)
453
492
 
493
+ @tool_cn_name("记录通过")
454
494
  def record_approve(self, *, profile: str, app_key: str, apply_id: int, payload: dict[str, Any]) -> dict[str, Any]:
495
+ """执行记录相关逻辑。"""
455
496
  self._require_app_and_apply(app_key, apply_id)
456
497
  body = self._require_dict(payload)
457
498
 
@@ -471,7 +512,9 @@ class ApprovalTools(ToolBase):
471
512
 
472
513
  return self._run(profile, runner)
473
514
 
515
+ @tool_cn_name("记录拒绝")
474
516
  def record_reject(self, *, profile: str, app_key: str, apply_id: int, payload: dict[str, Any]) -> dict[str, Any]:
517
+ """执行记录相关逻辑。"""
475
518
  self._require_app_and_apply(app_key, apply_id)
476
519
  body = self._require_dict(payload)
477
520
 
@@ -491,7 +534,9 @@ class ApprovalTools(ToolBase):
491
534
 
492
535
  return self._run(profile, runner)
493
536
 
537
+ @tool_cn_name("记录退回候选")
494
538
  def record_rollback_candidates(self, *, profile: str, app_key: str, apply_id: int, audit_node_id: int) -> dict[str, Any]:
539
+ """执行记录相关逻辑。"""
495
540
  self._require_app_and_apply(app_key, apply_id)
496
541
  if audit_node_id <= 0:
497
542
  raise_tool_error(QingflowApiError.config_error("audit_node_id must be positive"))
@@ -514,7 +559,9 @@ class ApprovalTools(ToolBase):
514
559
 
515
560
  return self._run(profile, runner)
516
561
 
562
+ @tool_cn_name("记录退回")
517
563
  def record_rollback(self, *, profile: str, app_key: str, apply_id: int, payload: dict[str, Any]) -> dict[str, Any]:
564
+ """执行记录相关逻辑。"""
518
565
  self._require_app_and_apply(app_key, apply_id)
519
566
  body = self._require_dict(payload)
520
567
  self._validate_audit_payload(body)
@@ -532,7 +579,9 @@ class ApprovalTools(ToolBase):
532
579
 
533
580
  return self._run(profile, runner)
534
581
 
582
+ @tool_cn_name("记录转交")
535
583
  def record_transfer(self, *, profile: str, app_key: str, apply_id: int, payload: dict[str, Any]) -> dict[str, Any]:
584
+ """执行记录相关逻辑。"""
536
585
  self._require_app_and_apply(app_key, apply_id)
537
586
  body = self._require_dict(payload)
538
587
  self._validate_audit_payload(body, require_uid=True)
@@ -550,6 +599,7 @@ class ApprovalTools(ToolBase):
550
599
 
551
600
  return self._run(profile, runner)
552
601
 
602
+ @tool_cn_name("记录转交候选")
553
603
  def record_transfer_candidates(
554
604
  self,
555
605
  *,
@@ -561,6 +611,7 @@ class ApprovalTools(ToolBase):
561
611
  audit_node_id: int = 0,
562
612
  keyword: str | None = None,
563
613
  ) -> dict[str, Any]:
614
+ """执行记录相关逻辑。"""
564
615
  self._require_app_and_apply(app_key, apply_id)
565
616
  if audit_node_id <= 0:
566
617
  raise_tool_error(QingflowApiError.config_error("audit_node_id must be positive"))
@@ -581,7 +632,9 @@ class ApprovalTools(ToolBase):
581
632
 
582
633
  return self._run(profile, runner)
583
634
 
635
+ @tool_cn_name("记录改派信息")
584
636
  def record_reassign_get(self, *, profile: str, app_key: str, apply_id: int) -> dict[str, Any]:
637
+ """执行记录相关逻辑。"""
585
638
  self._require_app_and_apply(app_key, apply_id)
586
639
 
587
640
  def runner(session_profile, context):
@@ -597,7 +650,9 @@ class ApprovalTools(ToolBase):
597
650
 
598
651
  return self._run(profile, runner)
599
652
 
653
+ @tool_cn_name("记录改派")
600
654
  def record_reassign(self, *, profile: str, app_key: str, apply_id: int, payload: dict[str, Any]) -> dict[str, Any]:
655
+ """执行记录相关逻辑。"""
601
656
  self._require_app_and_apply(app_key, apply_id)
602
657
  body = self._require_dict(payload)
603
658
 
@@ -614,6 +669,7 @@ class ApprovalTools(ToolBase):
614
669
 
615
670
  return self._run(profile, runner)
616
671
 
672
+ @tool_cn_name("会签候选")
617
673
  def record_countersign_candidates(
618
674
  self,
619
675
  *,
@@ -625,6 +681,7 @@ class ApprovalTools(ToolBase):
625
681
  audit_node_id: int = 0,
626
682
  search_key: str | None = None,
627
683
  ) -> dict[str, Any]:
684
+ """执行记录相关逻辑。"""
628
685
  self._require_app_and_apply(app_key, apply_id)
629
686
  if audit_node_id <= 0:
630
687
  raise_tool_error(QingflowApiError.config_error("audit_node_id must be positive"))
@@ -645,7 +702,9 @@ class ApprovalTools(ToolBase):
645
702
 
646
703
  return self._run(profile, runner)
647
704
 
705
+ @tool_cn_name("会签")
648
706
  def record_countersign(self, *, profile: str, app_key: str, apply_id: int, payload: dict[str, Any]) -> dict[str, Any]:
707
+ """执行记录相关逻辑。"""
649
708
  self._require_app_and_apply(app_key, apply_id)
650
709
  body = self._require_dict(payload)
651
710
  self._validate_countersign_payload(body)
@@ -664,6 +723,7 @@ class ApprovalTools(ToolBase):
664
723
  return self._run(profile, runner)
665
724
 
666
725
  def _request_route_payload(self, context) -> JSONObject: # type: ignore[no-untyped-def]
726
+ """执行内部辅助逻辑。"""
667
727
  describe_route = getattr(self.backend, "describe_route", None)
668
728
  if callable(describe_route):
669
729
  payload = describe_route(context)
@@ -676,12 +736,14 @@ class ApprovalTools(ToolBase):
676
736
  }
677
737
 
678
738
  def _require_app_and_apply(self, app_key: str, apply_id: int) -> None:
739
+ """执行内部辅助逻辑。"""
679
740
  if not app_key:
680
741
  raise_tool_error(QingflowApiError.config_error("app_key is required"))
681
742
  if apply_id <= 0:
682
743
  raise_tool_error(QingflowApiError.config_error("apply_id must be positive"))
683
744
 
684
745
  def _validate_comment_payload(self, payload: dict[str, Any]) -> None:
746
+ """执行内部辅助逻辑。"""
685
747
  comment_detail = payload.get("commentDetail")
686
748
  if not isinstance(comment_detail, dict):
687
749
  raise_tool_error(QingflowApiError.config_error("payload.commentDetail must be an object"))
@@ -689,6 +751,7 @@ class ApprovalTools(ToolBase):
689
751
  raise_tool_error(QingflowApiError.config_error("payload.commentDetail.commentMsg is required"))
690
752
 
691
753
  def _normalize_approval_payload(self, profile: str, context, app_key: str, apply_id: int, payload: dict[str, Any]) -> JSONObject: # type: ignore[no-untyped-def]
754
+ """执行内部辅助逻辑。"""
692
755
  body: JSONObject = dict(payload)
693
756
  self._normalize_alias(body, "auditFeedback", "audit_feedback")
694
757
  self._normalize_alias(body, "uploadFileSize", "upload_file_size")
@@ -708,6 +771,7 @@ class ApprovalTools(ToolBase):
708
771
  return body
709
772
 
710
773
  def _extract_node_id(self, payload: JSONObject) -> int:
774
+ """执行内部辅助逻辑。"""
711
775
  node_id = payload.get("nodeId")
712
776
  audit_node_id = payload.pop("auditNodeId", None)
713
777
  if node_id is None:
@@ -719,6 +783,7 @@ class ApprovalTools(ToolBase):
719
783
  return node_id
720
784
 
721
785
  def _resolve_form_id(self, profile: str, context, app_key: str, *, explicit_form_id: Any | None) -> int: # type: ignore[no-untyped-def]
786
+ """执行内部辅助逻辑。"""
722
787
  if explicit_form_id is not None:
723
788
  if not isinstance(explicit_form_id, int) or explicit_form_id <= 0:
724
789
  raise_tool_error(QingflowApiError.config_error("payload.formId must be a positive integer"))
@@ -733,6 +798,7 @@ class ApprovalTools(ToolBase):
733
798
  return self._get_form_id(profile, context, app_key)
734
799
 
735
800
  def _get_form_id(self, profile: str, context, app_key: str) -> int: # type: ignore[no-untyped-def]
801
+ """执行内部辅助逻辑。"""
736
802
  cache_key = f"{profile}:{app_key}"
737
803
  cached = self._form_id_cache.get(cache_key)
738
804
  if cached is not None:
@@ -745,6 +811,7 @@ class ApprovalTools(ToolBase):
745
811
  return form_id
746
812
 
747
813
  def _match_or_fill_int(self, payload: JSONObject, *, field_name: str, expected_value: int) -> int:
814
+ """执行内部辅助逻辑。"""
748
815
  current = payload.get(field_name)
749
816
  if current is None:
750
817
  return expected_value
@@ -755,6 +822,7 @@ class ApprovalTools(ToolBase):
755
822
  return current
756
823
 
757
824
  def _normalize_alias(self, payload: JSONObject, canonical_key: str, alias_key: str) -> None:
825
+ """执行内部辅助逻辑。"""
758
826
  alias_value = payload.pop(alias_key, None)
759
827
  if canonical_key not in payload and alias_value is not None:
760
828
  payload[canonical_key] = alias_value
@@ -762,6 +830,7 @@ class ApprovalTools(ToolBase):
762
830
  raise_tool_error(QingflowApiError.config_error(f"payload.{canonical_key} and payload.{alias_key} must match when both are provided"))
763
831
 
764
832
  def _resolve_actionable_node_id(self, context, app_key: str, apply_id: int, node_id: int) -> int: # type: ignore[no-untyped-def]
833
+ """执行内部辅助逻辑。"""
765
834
  infos = self.backend.request(
766
835
  "GET",
767
836
  context,
@@ -790,6 +859,7 @@ class ApprovalTools(ToolBase):
790
859
  return node_id
791
860
 
792
861
  def _fetch_current_todo_answers(self, context, app_key: str, apply_id: int, node_id: int) -> list[dict[str, Any]]: # type: ignore[no-untyped-def]
862
+ """执行内部辅助逻辑。"""
793
863
  detail = self.backend.request(
794
864
  "GET",
795
865
  context,
@@ -810,6 +880,7 @@ class ApprovalTools(ToolBase):
810
880
  return normalized_answers
811
881
 
812
882
  def _validate_approval_payload(self, payload: dict[str, Any]) -> None:
883
+ """执行内部辅助逻辑。"""
813
884
  self._reject_unsupported_fields(payload)
814
885
  if not isinstance(payload.get("formId"), int) or payload["formId"] <= 0:
815
886
  raise_tool_error(QingflowApiError.config_error("payload.formId must be a positive integer"))
@@ -822,21 +893,25 @@ class ApprovalTools(ToolBase):
822
893
  raise_tool_error(QingflowApiError.config_error("payload.answers must be an array when provided"))
823
894
 
824
895
  def _validate_audit_payload(self, payload: dict[str, Any], *, require_uid: bool = False) -> None:
896
+ """执行内部辅助逻辑。"""
825
897
  self._reject_unsupported_fields(payload)
826
898
  if require_uid and not payload.get("uid"):
827
899
  raise_tool_error(QingflowApiError.config_error("payload.uid is required"))
828
900
 
829
901
  def _validate_countersign_payload(self, payload: dict[str, Any]) -> None:
902
+ """执行内部辅助逻辑。"""
830
903
  self._reject_unsupported_fields(payload)
831
904
  members = payload.get("countersignMembers")
832
905
  if not isinstance(members, list) or not members:
833
906
  raise_tool_error(QingflowApiError.config_error("payload.countersignMembers must be a non-empty array"))
834
907
 
835
908
  def _reject_unsupported_fields(self, payload: dict[str, Any]) -> None:
909
+ """执行内部辅助逻辑。"""
836
910
  if payload.get("handSignImageUrl"):
837
911
  raise_tool_error(QingflowApiError.not_supported("NOT_SUPPORTED_IN_V1: handSignImageUrl is not supported"))
838
912
 
839
913
  def _extract_transfer_target_uid(self, payload: dict[str, Any]) -> int | None:
914
+ """执行内部辅助逻辑。"""
840
915
  for key in ("uid", "target_member_id", "targetMemberId"):
841
916
  value = payload.get(key)
842
917
  if isinstance(value, int) and value > 0:
@@ -844,6 +919,7 @@ class ApprovalTools(ToolBase):
844
919
  return None
845
920
 
846
921
  def _raise_if_self_transfer(self, *, profile: str, payload: dict[str, Any]) -> None:
922
+ """执行内部辅助逻辑。"""
847
923
  target_uid = self._extract_transfer_target_uid(payload)
848
924
  if target_uid is None:
849
925
  return
@@ -856,6 +932,7 @@ class ApprovalTools(ToolBase):
856
932
  )
857
933
 
858
934
  def _filter_self_transfer_candidates(self, *, profile: str, items: list[dict[str, Any]]) -> list[dict[str, Any]]:
935
+ """执行内部辅助逻辑。"""
859
936
  session_profile = self.sessions.get_profile(profile)
860
937
  if session_profile is None:
861
938
  return items
@@ -874,6 +951,7 @@ class ApprovalTools(ToolBase):
874
951
  public_action: str,
875
952
  workflow_node_id: int | None = None,
876
953
  ) -> dict[str, Any]:
954
+ """执行内部辅助逻辑。"""
877
955
  from .task_context_tools import TaskContextTools
878
956
 
879
957
  node_id = workflow_node_id
@@ -905,6 +983,7 @@ class ApprovalTools(ToolBase):
905
983
  pagination: dict[str, Any],
906
984
  selection: dict[str, Any],
907
985
  ) -> dict[str, Any]:
986
+ """执行内部辅助逻辑。"""
908
987
  response = dict(raw)
909
988
  response["ok"] = bool(raw.get("ok", True))
910
989
  response["warnings"] = []
@@ -925,6 +1004,7 @@ class ApprovalTools(ToolBase):
925
1004
  selection: dict[str, Any],
926
1005
  human_review: bool = False,
927
1006
  ) -> dict[str, Any]:
1007
+ """执行内部辅助逻辑。"""
928
1008
  response = dict(raw)
929
1009
  response["ok"] = bool(raw.get("ok", True))
930
1010
  response["warnings"] = []
@@ -939,6 +1019,7 @@ class ApprovalTools(ToolBase):
939
1019
  return response
940
1020
 
941
1021
  def _request_route_payload(self, context) -> JSONObject: # type: ignore[no-untyped-def]
1022
+ """执行内部辅助逻辑。"""
942
1023
  describe_route = getattr(self.backend, "describe_route", None)
943
1024
  if callable(describe_route):
944
1025
  payload = describe_route(context)