@josephyan/qingflow-app-user-mcp 0.2.0-beta.4 → 0.2.0-beta.41

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 (49) hide show
  1. package/README.md +6 -3
  2. package/package.json +1 -1
  3. package/pyproject.toml +3 -1
  4. package/skills/qingflow-app-user/SKILL.md +45 -146
  5. package/skills/qingflow-app-user/agents/openai.yaml +2 -2
  6. package/skills/qingflow-app-user/references/data-gotchas.md +22 -21
  7. package/skills/qingflow-app-user/references/environments.md +1 -1
  8. package/skills/qingflow-app-user/references/record-patterns.md +85 -46
  9. package/skills/qingflow-app-user/references/workflow-usage.md +10 -8
  10. package/skills/qingflow-record-analysis/SKILL.md +158 -0
  11. package/skills/qingflow-record-analysis/agents/openai.yaml +4 -0
  12. package/skills/qingflow-record-analysis/references/analysis-gotchas.md +145 -0
  13. package/skills/qingflow-record-analysis/references/analysis-patterns.md +125 -0
  14. package/skills/qingflow-record-analysis/references/confidence-reporting.md +92 -0
  15. package/skills/qingflow-record-analysis/references/dsl-templates.md +93 -0
  16. package/skills/qingflow-record-crud/SKILL.md +182 -0
  17. package/skills/qingflow-record-crud/agents/openai.yaml +5 -0
  18. package/skills/qingflow-record-crud/references/data-gotchas.md +44 -0
  19. package/skills/qingflow-record-crud/references/environments.md +58 -0
  20. package/skills/qingflow-record-crud/references/record-patterns.md +146 -0
  21. package/skills/qingflow-task-ops/SKILL.md +123 -0
  22. package/skills/qingflow-task-ops/agents/openai.yaml +4 -0
  23. package/skills/qingflow-task-ops/references/environments.md +44 -0
  24. package/skills/qingflow-task-ops/references/workflow-usage.md +27 -0
  25. package/src/qingflow_mcp/__init__.py +1 -1
  26. package/src/qingflow_mcp/backend_client.py +189 -0
  27. package/src/qingflow_mcp/builder_facade/models.py +584 -1
  28. package/src/qingflow_mcp/builder_facade/service.py +4698 -262
  29. package/src/qingflow_mcp/config.py +39 -0
  30. package/src/qingflow_mcp/import_store.py +121 -0
  31. package/src/qingflow_mcp/list_type_labels.py +24 -0
  32. package/src/qingflow_mcp/server.py +131 -16
  33. package/src/qingflow_mcp/server_app_builder.py +132 -72
  34. package/src/qingflow_mcp/server_app_user.py +143 -187
  35. package/src/qingflow_mcp/solution/compiler/form_compiler.py +14 -4
  36. package/src/qingflow_mcp/solution/compiler/workflow_compiler.py +41 -2
  37. package/src/qingflow_mcp/solution/executor.py +44 -7
  38. package/src/qingflow_mcp/tools/ai_builder_tools.py +1567 -144
  39. package/src/qingflow_mcp/tools/app_tools.py +243 -14
  40. package/src/qingflow_mcp/tools/approval_tools.py +411 -76
  41. package/src/qingflow_mcp/tools/directory_tools.py +203 -31
  42. package/src/qingflow_mcp/tools/feedback_tools.py +230 -0
  43. package/src/qingflow_mcp/tools/file_tools.py +1 -0
  44. package/src/qingflow_mcp/tools/import_tools.py +1164 -0
  45. package/src/qingflow_mcp/tools/portal_tools.py +31 -0
  46. package/src/qingflow_mcp/tools/record_tools.py +4943 -1025
  47. package/src/qingflow_mcp/tools/task_context_tools.py +1335 -0
  48. package/src/qingflow_mcp/tools/task_tools.py +376 -225
  49. package/src/qingflow_mcp/tools/workflow_tools.py +78 -4
package/README.md CHANGED
@@ -3,13 +3,13 @@
3
3
  Install:
4
4
 
5
5
  ```bash
6
- npm install @josephyan/qingflow-app-user-mcp@0.2.0-beta.4
6
+ npm install @josephyan/qingflow-app-user-mcp@0.2.0-beta.41
7
7
  ```
8
8
 
9
9
  Run:
10
10
 
11
11
  ```bash
12
- npx -y -p @josephyan/qingflow-app-user-mcp@0.2.0-beta.4 qingflow-app-user-mcp
12
+ npx -y -p @josephyan/qingflow-app-user-mcp@0.2.0-beta.41 qingflow-app-user-mcp
13
13
  ```
14
14
 
15
15
  Environment:
@@ -20,9 +20,12 @@ Environment:
20
20
 
21
21
  This package bootstraps a local Python runtime on first install and then starts the `qingflow-app-user-mcp` stdio MCP server.
22
22
 
23
- Bundled skill:
23
+ Bundled skills:
24
24
 
25
25
  - `skills/qingflow-app-user`
26
+ - `skills/qingflow-record-crud`
27
+ - `skills/qingflow-task-ops`
28
+ - `skills/qingflow-record-analysis`
26
29
 
27
30
  Note:
28
31
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@josephyan/qingflow-app-user-mcp",
3
- "version": "0.2.0-beta.4",
3
+ "version": "0.2.0-beta.41",
4
4
  "description": "Operational end-user MCP for Qingflow records, tasks, comments, and directory workflows.",
5
5
  "license": "MIT",
6
6
  "type": "module",
package/pyproject.toml CHANGED
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "qingflow-mcp"
7
- version = "0.2.0b4"
7
+ version = "0.2.0b41"
8
8
  description = "User-authenticated MCP server for Qingflow"
9
9
  readme = "README.md"
10
10
  license = "MIT"
@@ -26,8 +26,10 @@ dependencies = [
26
26
  "mcp>=1.9.4,<2.0.0",
27
27
  "httpx>=0.27,<1.0",
28
28
  "keyring>=25.5,<26.0",
29
+ "openpyxl>=3.1,<4.0",
29
30
  "pydantic>=2.8,<3.0",
30
31
  "pycryptodome>=3.20,<4.0",
32
+ "python-socketio[client]>=5.11,<6.0",
31
33
  ]
32
34
 
33
35
  [project.optional-dependencies]
@@ -1,158 +1,57 @@
1
1
  ---
2
2
  name: qingflow-app-user
3
- description: Use Qingflow apps as an operational end user after the MCP is already connected and authenticated. Use when the user wants to create, search, read, update, or delete business records, inspect or manage task-center work, add comments, or perform workflow usage actions inside an existing app. Do not use this skill to design apps, modify schemas, or build a brand new SolutionSpec.
3
+ description: Route Qingflow end-user requests to the right specialized operational skill after the MCP is already connected and authenticated. Use when the task is operational but it is not yet clear whether it is record CRUD or final analysis.
4
4
  metadata:
5
- short-description: Use Qingflow apps for business data and task operations
5
+ short-description: Router for Qingflow operational skills
6
6
  ---
7
7
 
8
8
  # Qingflow App User
9
9
 
10
10
  ## Overview
11
11
 
12
- This skill is for business-user operations inside existing Qingflow apps. It focuses on records, task-center usage, comments, and usage-side workflow actions, not app design or system configuration. If the task is about building or changing app structure, switch to `$qingflow-app-builder`.
13
-
14
- Before operating on data, identify whether the task targets `test` or `prod` and read [references/environments.md](references/environments.md). If the user did not specify one, default to `prod`.
15
- When the task is in `prod`, browser parity matters, or the user says "the page has data but MCP does not", restate the expected `base_url` and `qf_version`, then prefer tools that expose `request_route` so you can confirm the live route before concluding.
16
-
17
- ## Tool Scope
18
-
19
- Primary record and data tools:
20
-
21
- - `record_query`
22
- - `record_query_plan`
23
- - `record_write_plan`
24
- - `record_field_resolve`
25
- - `record_aggregate`
26
- - `record_create`
27
- - `record_get`
28
- - `record_update`
29
- - `record_delete`
30
-
31
- Directory and organization lookup tools when the user is asking about internal members, departments, org structure, ownership, approver candidates, or wants full contact exports:
32
-
33
- - `directory_search`
34
- - `directory_list_internal_users`
35
- - `directory_list_all_internal_users`
36
- - `directory_list_internal_departments`
37
- - `directory_list_all_departments`
38
- - `directory_list_sub_departments`
39
- - `directory_list_external_members`
40
-
41
- Usage-side collaboration and flow tools when needed:
42
-
43
- - `record_comment_*`
44
- - `task_approve`
45
- - `task_reject`
46
- - `task_rollback*`
47
- - `task_transfer*`
48
-
49
- Task-center and inbox tools when the user is asking about pending work, processed work, cc, or workflow workload:
50
-
51
- - `task_list`
52
- - `task_list_grouped`
53
- - `task_statistics`
54
- - `task_urge`
55
-
56
- Do not use builder-side tools here:
57
-
58
- - `app_*`
59
- - `view_*`
60
- - `workflow_*`
61
- - `portal_*`
62
- - `navigation_*`
63
- - `package_*`
64
- - `solution_*`
65
-
66
- ## Standard Operating Order
67
-
68
- 1. Ensure auth exists
69
- 2. Ensure workspace is selected
70
- 3. Confirm target app, task scope, and operation type
71
- 4. For org, member, department, approver, or ownership questions, start with `directory_*`
72
- 5. For inbox, pending, processed, cc, or workload questions, start with `task_statistics`, `task_list`, or `task_list_grouped`
73
- 6. When a task query identifies the target record, switch to `record_get` or `record_query` for business data details
74
- 7. For non-trivial record reads, start with `record_query` and use `record_query_plan` first when field ids, filters, or scan scope are uncertain
75
- 8. For non-trivial writes, start with `record_write_plan`, especially when using `fields`
76
- 9. Prefer read-first when changing existing records
77
- 10. Report the affected task ids, record ids, member ids, department ids, or counts after actions
78
- 11. For `prod`, complex forms, attachments, or any unfamiliar schema, prefer `record_create(..., verify_write=true)` or read back immediately after create/update
79
-
80
- ## Data Rules
81
-
82
- - Prefer `record_query` as the default read entry
83
- - Treat `record_query(list)` as the default wide-table browse and export endpoint; pass explicit `select_columns`, do not expect raw answer arrays there, and let the tool auto-batch columns when the backend per-request field cap is hit
84
- - Use `request_route` from tool responses to verify the active `base_url` and `qf_version` whenever route mismatches are plausible
85
- - Use `directory_search` for fuzzy internal lookup across both members and departments
86
- - Use `directory_list_all_internal_users` when the user explicitly wants a complete internal member list within the current workspace or within a specific department or role
87
- - Use `directory_list_all_departments` when the user explicitly wants the full department tree or all departments under a root
88
- - Use `directory_list_internal_departments` for keyword-based department search, not full exports
89
- - Use `task_statistics` before `task_list` when the user only needs counts
90
- - Use `task_list_grouped` when worksheet or group buckets matter
91
- - Use `task_urge` only when the user clearly wants a reminder sent for a pending task
92
- - Use `record_query_plan` before final statistics or when field selectors are ambiguous
93
- - For precise record lookup, use `record_get` when `apply_id` is known
94
- - Use `record_field_resolve` when the user gives field titles and you are not fully sure about the exact schema; do not guess ambiguous fields silently
95
- - Treat field selectors as schema-first and platform-generic. Prefer exact field titles, then neutral aliases such as `创建时间`, `新增时间`, `负责人`, `部门`, `时间`, or `阶段` only when the tool resolves them clearly. Do not assume CRM shorthand like `销售`, `商机阶段`, `客户全称`, or similar domain shortcuts apply across arbitrary Qingflow apps
96
- - For updates, inspect current data first unless the user already provided the exact target and patch
97
- - For deletes, confirm the exact record scope and report the deleted ids
98
- - When validating business data volume, use `effective_count` over raw backend totals
99
- - For summary or aggregate conclusions, prefer `strict_full=true`
100
- - In `prod`, prefer read-first even more strictly and avoid deletes unless the record scope is explicit in the conversation
101
- - For attachments, first run `file_upload_local`, then pass the returned `attachment_value` into `record_create` or `record_update`; do not try to write local file paths directly into attachment fields
102
- - For relation fields, first query the target app and resolve the referenced record `apply_id`; do not assume titles, numbers, or business keys can be written directly into a relation field
103
- - For subtable fields, write a list of row objects keyed by the subfield titles. When updating existing rows, include `rowId` / `row_id` / `__row_id__` only if the source record already exposes it
104
- - Treat `14/34/35/36` as unsupported direct-write field types in app-user flows:
105
- - `14`: time range
106
- - `34`: image recognition
107
- - `35`: image generation
108
- - `36`: document parsing
109
- - For those unsupported types, stop and explain the limitation instead of inventing payloads
110
- - Use `record_write_plan` to inspect `write_format.support_level` before non-trivial writes:
111
- - `full`: generic scalar/select/date writes are directly supported
112
- - `restricted`: member/department/attachment/relation/subtable writes need the documented presteps
113
- - `unsupported`: stop and explain the limitation
114
- - For relation-heavy, attachment, subtable, or production writes, default to `verify_write=true` so field drops are surfaced immediately instead of being reported as success
115
-
116
- ## Mock and Demo Data
117
-
118
- When the user asks for demo data, seed, smoke data, or mock data:
119
-
120
- - default to at least `5` records for the relevant entity unless the user asks for fewer
121
- - keep titles realistic and business-like
122
- - vary statuses, dates, and categories enough to make views and charts useful
123
- - if the task is `prod`, do not create mock or smoke data unless the user explicitly asks for it
124
-
125
- ## Response Interpretation
126
-
127
- - low-level list totals from the backend may report `0` while rows are present; prefer `record_query(summary)` or `record_aggregate` for final conclusions
128
- - `record_query(summary)` and `record_aggregate` expose `completeness`; do not treat partial scans as final conclusions
129
- - `record_write_plan` is static preflight, not a guarantee that submit will pass runtime linkage or visibility checks
130
- - `record_create` now returns integer `apply_id`; you can pass that id directly into `record_get`, `record_update`, or `record_delete`
131
- - `verify_write=true` means the tool read the record back and compared the written fields; if it returns `status=verification_failed` or `ok=false`, do not report the create or update as successful
132
- - Relation writes are `apply_id`-based; if the user only gives a title, number, or business key, query the target app first and resolve the real record id before writing
133
- - Task counts and record counts are not interchangeable; a task query reflects task-center workload, not the underlying record total
134
- - When reporting task results, include the task dimension that was used, such as pending, processed, cc, node, or worksheet
135
- - Prefer summarizing titles and counts instead of dumping raw answer arrays
136
- - When records reference other entities, verify references are coherent before reporting success
137
- - `file_upload_local` may transparently change `effective_upload_kind` and `upload_protocol`; surface those fields when debugging production upload behavior instead of assuming all uploads are direct `PUT`
138
-
139
- ## Practical Patterns
140
-
141
- - Bulk mock data creation: query current data first, run `record_write_plan`, then create missing records
142
- - Data correction: query, inspect, preflight, update, and re-read
143
- - Inbox triage: use `task_statistics` first, then `task_list` or `task_list_grouped`, then switch to `record_*` for the underlying record when needed
144
- - Bottleneck analysis: start with `task_statistics` and `task_list_grouped` before drilling into specific records
145
- - Workflow collaboration: comment, transfer, or reassign only after identifying the exact record
146
- - Approval actions: identify the exact record and current node first, then use `task_approve` or `task_reject`; do not guess `nodeId`
147
- - Demo validation: create at least `5` rows and confirm they are queryable
148
- - Org export: use `directory_list_all_internal_users` for full member exports and `directory_list_all_departments` for full org-tree exports before mapping owners or departments into record operations
149
- - Attachment write: upload first, write the returned URL object second, and prefer `verify_write=true`
150
- - Relation write: query the target app first, capture the referenced record `apply_id`, then write the relation field and verify the readback
151
- - Production discrepancy triage: compare the response `request_route` with the browser environment before assuming the data query is wrong
12
+ This skill is a lightweight router for operational Qingflow work.
13
+ Assumes MCP is connected, authenticated, and on the correct workspace.
14
+
15
+ ## Default Paths
16
+
17
+ Route to exactly one of these specialized paths:
18
+
19
+ 1. Record CRUD and import
20
+ Switch to [$qingflow-record-crud](/Users/yanqidong/Documents/qingflow-next/.codex/skills/qingflow-record-crud/SKILL.md)
21
+
22
+ 2. Task workflow operations
23
+ Switch to [$qingflow-task-ops](/Users/yanqidong/Documents/qingflow-next/.codex/skills/qingflow-task-ops/SKILL.md)
24
+
25
+ 3. Analysis
26
+ Switch to [$qingflow-record-analysis](/Users/yanqidong/Documents/qingflow-next/.codex/skills/qingflow-record-analysis/SKILL.md)
27
+
28
+ 4. MCP connection / auth / workspace selection
29
+ Switch to [$qingflow-mcp-setup](/Users/yanqidong/.codex/skills/qingflow-mcp-setup/SKILL.md)
30
+
31
+ ## Routing Rules
32
+
33
+ - If the user does not know the target `app_key`, discover apps first with `app_list` or `app_search`, then route to the specialized skill
34
+ - If the app is known but the available data range is unclear, call `app_get` first and inspect `accessible_views`
35
+ - If the task is about browsing, reading, creating, updating, deleting, attachments, relations, subtable writes, member/department-field candidate lookup, import templates, import-file verification, authorized local file repair, import execution, or import status, switch to `$qingflow-record-crud`
36
+ - If the task is about todo discovery, task context, approval actions, rollback or transfer, associated report review, or workflow log review, switch to `$qingflow-task-ops`
37
+ - If the task is about grouped distributions, ratios, rankings, trends, insights, or any final statistical conclusion, switch to `$qingflow-record-analysis`
38
+ - If the MCP is not connected, authenticated, or bound to the right workspace, switch to `$qingflow-mcp-setup`
39
+
40
+ ## Shared Preconditions
41
+
42
+ - prefer canonical app ids, record ids, task ids, and workflow node ids over guessed names
43
+ - if a field or target is still ambiguous after schema/task lookup, ask the user to confirm from a short candidate list instead of guessing
44
+ - if the task can stay read-only, do not write or act
45
+ - if the task involves a user-uploaded import file, do not modify the file unless the user explicitly authorizes repair or normalization
46
+ - if the current MCP capability is unsupported, the workflow is awkward, or the user's need still cannot be satisfied after reasonable use, summarize the gap, ask whether to submit feedback, and call `feedback_submit` only after explicit user confirmation
47
+
48
+ ## Shared Helper
49
+
50
+ - `feedback_submit` is a cross-cutting helper for product feedback submission
51
+ - It does not require Qingflow login or workspace selection
52
+ - Use it only after the user explicitly confirms they want to submit feedback
152
53
 
153
54
  ## Resources
154
55
 
155
- - Environment switching: [references/environments.md](references/environments.md)
156
- - Record operation patterns: [references/record-patterns.md](references/record-patterns.md)
157
- - Workflow usage actions: [references/workflow-usage.md](references/workflow-usage.md)
158
- - Data gotchas: [references/data-gotchas.md](references/data-gotchas.md)
56
+ - Record CRUD: [$qingflow-record-crud](/Users/yanqidong/Documents/qingflow-next/.codex/skills/qingflow-record-crud/SKILL.md)
57
+ - Dedicated analysis workflow: [$qingflow-record-analysis](/Users/yanqidong/Documents/qingflow-next/.codex/skills/qingflow-record-analysis/SKILL.md)
@@ -1,4 +1,4 @@
1
1
  interface:
2
2
  display_name: "Qingflow App User"
3
- short_description: "Use Qingflow apps for business data and task operations"
4
- default_prompt: "Use $qingflow-app-user to query members or departments, inspect workload, and safely create, query, update, validate, approve, reject, or otherwise operate records in an existing Qingflow app, paying attention to request_route, verify_write, nodeId accuracy, and attachment upload flows when needed."
3
+ short_description: "Route Qingflow operational tasks to CRUD, task ops, or analysis"
4
+ default_prompt: "Use $qingflow-app-user as a router: switch to $qingflow-record-crud for record browse/read/write, switch to $qingflow-task-ops for task-center, comments, directory, and workflow usage actions, and switch to $qingflow-record-analysis for grouped analysis or final statistical conclusions."
@@ -1,30 +1,31 @@
1
1
  # Data Gotchas
2
2
 
3
- ## Counts
3
+ For final statistics, grouped distributions, rankings, trends, or insight-style conclusions, use [$qingflow-record-analysis](/Users/yanqidong/Documents/qingflow-next/.codex/skills/qingflow-record-analysis/SKILL.md) instead of keeping that reasoning inside `$qingflow-app-user`.
4
4
 
5
- - Prefer `effective_count`
6
- - For `record_query(summary)` and `record_aggregate`, inspect `completeness` before concluding
7
- - If the browser and MCP disagree, compare `request_route.base_url` and `request_route.qf_version` first
8
-
9
- ## Record titles
5
+ ## Record Reads
10
6
 
11
- - Do not dump raw answer arrays to the user unless needed
12
- - Prefer concise business titles and counts
7
+ - `record_list` is for browsing, export, and sample inspection only
8
+ - `record_get` is for one exact record
9
+ - Do not present paged browse output as if it were a grouped or full-population conclusion
10
+ - If the browser and MCP disagree, compare `request_route.base_url` and `request_route.qf_version` first
13
11
 
14
- ## Preflight
12
+ ## Write Preflight
15
13
 
16
- - `record_write_plan` is static preflight only; linked visibility and runtime required rules can still reject writes
17
- - `record_write_plan` now exposes `write_format.support_level`; check `full / restricted / unsupported` before attempting non-trivial writes
18
- - Use `record_field_resolve` when field titles are uncertain instead of guessing ids
19
- - Prefer `strict_full=true` for final statistics or business conclusions
20
- - `record_create` and `record_update` can do post-write verification with `verify_write=true`; use that for complex, subtable, or production writes
21
- - `apply_id` is normalized to an integer; pass it directly into later record tools
14
+ - `record_write` always performs internal static preflight before any apply
15
+ - If `record_write` returns `ok=false`, the write was blocked and not executed
16
+ - Use `record_schema_get` when field titles are uncertain instead of guessing ids
17
+ - Prefer `verify_write=true` for complex, relation-heavy, subtable, or production writes
18
+ - Even when `record_write` returns `ok=true`, it may still surface verification failures; do not report success before checking them
22
19
 
23
- ## Mock data
20
+ ## Write Semantics
24
21
 
25
- - Default to at least `5` rows per relevant entity unless the user asked for fewer
26
- - Avoid identical titles and identical statuses across all rows
27
- - Keep relation references valid
22
+ - `insert` uses `values`
23
+ - `update` uses `set`
24
+ - `delete` uses `record_id` or `record_ids`
25
+ - Do not send raw SQL strings
26
+ - Do not fake formula or expression fields
27
+ - Do not perform free-form bulk updates or deletes
28
+ - Do not guess relation targets from display text; resolve the real `record_id` first
28
29
 
29
30
  ## Attachments
30
31
 
@@ -36,10 +37,10 @@
36
37
 
37
38
  - Subtable fields accept row objects keyed by subfield title, or native `tableValues`
38
39
  - Use the current form schema's subfield titles; do not guess nested ids
39
- - When updating existing subtable rows, preserve `rowId` if the source record returns it
40
+ - When updating existing subtable rows, preserve row ids if the source record returns them
40
41
  - Nested subtable writes are still unsupported
41
42
 
42
- ## Unsupported direct-write fields
43
+ ## Unsupported Direct-Write Fields
43
44
 
44
45
  - `14` time range
45
46
  - `34` image recognition
@@ -50,7 +50,7 @@ Production behavior:
50
50
  Production guardrails:
51
51
 
52
52
  - never assume a record id, app id, or workspace id
53
- - treat `record_delete` as high risk
53
+ - treat `record_write(operation="delete")` as high risk
54
54
  - if the task can be answered read-only, do not write
55
55
 
56
56
  ## Reporting Rule
@@ -1,54 +1,96 @@
1
1
  # Record Patterns
2
2
 
3
- ## Query first
3
+ If the task shifts into grouped analysis, ratio, ranking, trend, or any final statistical conclusion, switch to [$qingflow-record-analysis](/Users/yanqidong/Documents/qingflow-next/.codex/skills/qingflow-record-analysis/SKILL.md).
4
4
 
5
- Use `record_query` first when:
5
+ ## Browse Pattern
6
6
 
7
- - the user only gives a title or business key
8
- - the target record id is unknown
9
- - updates or deletes need confirmation
10
- - summary analysis or final counts are needed
7
+ Use `record_schema_get -> record_list` when:
11
8
 
12
- Use `record_query_plan` first when:
9
+ - the user wants to browse records
10
+ - the target `record_id` is unknown
11
+ - a delete or update target still needs confirmation
12
+ - the user needs sample rows or a small export
13
13
 
14
- - field titles may be ambiguous
15
- - filters are still in natural-language shape
16
- - the result may be used as a final conclusion
17
- - scan scope or completeness is unclear
14
+ Keep the browse DSL simple:
18
15
 
19
- ## Create pattern
16
+ - `columns`: field ids only
17
+ - `where`: flat AND filters only
18
+ - `order_by`: field sorting only
19
+ - `limit` and `page`: browsing intent only
20
20
 
21
- 1. Confirm target app
22
- 2. Resolve fields with `record_field_resolve` if needed. Prefer exact schema titles first; only rely on platform-neutral aliases such as `创建时间`, `负责人`, or `部门` when they resolve cleanly, and do not assume business-domain shorthand like `销售` is portable across apps
23
- 3. Run `record_write_plan` for non-trivial payloads or any `fields`-based write
24
- 4. For relation fields, query the target app first and resolve the referenced record `apply_id`
25
- 5. For attachments, call `file_upload_local` first and reuse the returned `attachment_value`
26
- 6. For subtable fields, pass a list of row objects keyed by subfield title. When updating existing rows, include `rowId` / `row_id` / `__row_id__` only if the current record already exposes it
27
- 7. Inspect `record_write_plan.data.support_matrix` or each field's `write_format.support_level` before submit:
28
- - `full`: direct write is supported
29
- - `restricted`: follow the documented presteps first
30
- - `unsupported`: stop and explain the limitation
31
- 8. For complex forms, production writes, attachments, relation-heavy payloads, or subtables, create with `verify_write=true`
32
- 9. If verification fails, treat the write as not yet successful and inspect the missing or empty fields before reporting back
33
- 10. Re-query or fetch the record when validation matters
21
+ Do not use `record_list` for grouped conclusions, ratios, rankings, trends, or any final statistical claim.
34
22
 
35
- ## Update pattern
23
+ ## Detail Pattern
36
24
 
37
- 1. Query the target records
38
- 2. Resolve exact `apply_id`
39
- 3. Run `record_write_plan`
40
- 4. Update only the intended fields
41
- 5. Prefer `verify_write=true` for attachment, relation, subtable, or production updates
42
- 6. Re-read the record if the change is important, attachment-related, subtable-related, or the form has linkage
25
+ Use `record_schema_get -> record_get` when:
43
26
 
44
- ## Delete pattern
27
+ - the exact `record_id` is known
28
+ - the user needs one record in detail
29
+ - a write target needs verification before action
45
30
 
46
- 1. Query or fetch the exact record first
47
- 2. Confirm the target ids
48
- 3. Delete
49
- 4. Report affected ids and remaining count when relevant
31
+ Prefer passing explicit `columns` when the user only needs a subset of fields.
50
32
 
51
- ## Unsupported direct writes
33
+ ## Write Pattern
34
+
35
+ Use `record_schema_get -> record_write`.
36
+
37
+ 1. Confirm the target app
38
+ 2. Resolve fields with `record_schema_get`
39
+ 3. Decide whether the task is `insert`, `update`, or `delete`
40
+ 4. Build SQL-like JSON clauses
41
+ 5. Run `record_write`
42
+ 6. If `ok=false`, explain `field_errors` first, then summarize blockers; stop because the write was not executed
43
+ 7. If `ok=true`, report the affected resource and any verification outcome
44
+ 8. For important writes, keep `verify_write=true`
45
+
46
+ ### Insert
47
+
48
+ ```json
49
+ {
50
+ "operation": "insert",
51
+ "values": [
52
+ { "field_id": 12, "value": "测试客户" },
53
+ { "field_id": 18, "value": 1000 }
54
+ ],
55
+ "submit_type": "submit",
56
+ "verify_write": true
57
+ }
58
+ ```
59
+
60
+ ### Update
61
+
62
+ ```json
63
+ {
64
+ "operation": "update",
65
+ "record_id": 123,
66
+ "set": [
67
+ { "field_id": 18, "value": 2000 }
68
+ ],
69
+ "verify_write": true
70
+ }
71
+ ```
72
+
73
+ ### Delete
74
+
75
+ ```json
76
+ {
77
+ "operation": "delete",
78
+ "record_ids": [123, 124]
79
+ }
80
+ ```
81
+
82
+ ## Write Anti-Patterns
83
+
84
+ Do not do this:
85
+
86
+ - do not send raw SQL text
87
+ - do not build free-form `WHERE` updates or deletes
88
+ - do not invent formulas or expressions
89
+ - do not auto-fill missing required fields
90
+ - do not guess relation targets without first resolving them
91
+ - do not claim a blocked `record_write` was executed
92
+
93
+ ## Unsupported Direct Writes
52
94
 
53
95
  Do not attempt direct app-user writes for these field types:
54
96
 
@@ -57,13 +99,10 @@ Do not attempt direct app-user writes for these field types:
57
99
  - `35` image generation
58
100
  - `36` document parsing
59
101
 
60
- If the payload includes them, stop at `record_write_plan` and explain that the tool does not build a reliable native payload for those fields yet.
61
-
62
- ## Relation fields
102
+ If the payload includes them, stop after the blocked `record_write` response and explain that the tool does not support a reliable direct write for those fields yet.
63
103
 
64
- Relation fields are record-id based.
104
+ ## Relation, Attachment, and Subtable Rules
65
105
 
66
- - Query the referenced app first
67
- - Resolve the target record `apply_id`
68
- - Write the relation field with that id
69
- - Do not write relation fields with display titles, business keys, or guessed identifiers unless they have already been resolved to the real record id
106
+ - Relation fields are record-id based. Resolve the referenced target first, then write the relation field with the real `record_id`.
107
+ - Attachment fields are two-step: upload first with `file_upload_local`, then reuse the returned attachment payload in `record_write`.
108
+ - Subtable writes require the current schema shape; when updating existing subtable rows, preserve row ids if the current record exposes them.
@@ -7,18 +7,20 @@ Examples:
7
7
  - add a comment to a record
8
8
  - approve or reject a workflow task
9
9
  - transfer a task
10
- - roll back a record
11
- - list pending, processed, or cc tasks
10
+ - roll back a task
11
+ - list todo, initiated, done, or cc tasks
12
+ - inspect workload by worksheet or workflow node
12
13
  - urge a pending task
13
14
 
14
15
  Rules:
15
16
 
16
17
  - if the user starts from inbox, todo, workload, cc, or bottleneck language, use `task_*` first
17
- - use `task_statistics` for counts and `task_list` or `task_list_grouped` for browsing
18
- - use `task_list_grouped` when grouped workload browsing matters
18
+ - use `task_summary` for headline counts
19
+ - use `task_list` for flat browsing
20
+ - use `task_facets` when worksheet or workflow-node buckets matter
19
21
  - treat task counts as task-center counts, not record counts
20
- - switch to `record_*` after locating the exact business record behind a task
21
- - identify the exact record first
22
- - for approve or reject, identify the exact `nodeId` first; prefer task-center results or audit info, then use `task_approve` or `task_reject`
23
- - avoid usage-side flow actions on ambiguous records
22
+ - switch to `record_*` only after locating the exact business record behind a task
23
+ - identify the exact target first
24
+ - for approve or reject, identify the exact `workflow_node_id` first; prefer task-center results or current audit info, then use `task_approve` or `task_reject`
25
+ - avoid usage-side workflow actions on ambiguous records
24
26
  - summarize the final action and target task ids or record ids