@josephyan/qingflow-app-user-mcp 0.2.0-beta.21 → 0.2.0-beta.23
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 +4 -2
- package/package.json +1 -1
- package/pyproject.toml +1 -1
- package/skills/qingflow-app-user/SKILL.md +35 -202
- package/skills/qingflow-app-user/agents/openai.yaml +2 -2
- package/skills/qingflow-app-user/references/data-gotchas.md +3 -2
- package/skills/qingflow-app-user/references/record-patterns.md +7 -9
- package/skills/qingflow-record-analysis/SKILL.md +18 -4
- package/skills/qingflow-record-analysis/references/analysis-gotchas.md +5 -1
- package/skills/qingflow-record-analysis/references/analysis-patterns.md +17 -5
- package/skills/qingflow-record-analysis/references/confidence-reporting.md +3 -3
- package/skills/qingflow-record-crud/SKILL.md +181 -0
- package/skills/qingflow-record-crud/agents/openai.yaml +5 -0
- package/skills/qingflow-record-crud/references/data-gotchas.md +44 -0
- package/skills/qingflow-record-crud/references/environments.md +58 -0
- package/skills/qingflow-record-crud/references/record-patterns.md +112 -0
- package/skills/qingflow-task-ops/SKILL.md +148 -0
- package/skills/qingflow-task-ops/agents/openai.yaml +4 -0
- package/skills/qingflow-task-ops/references/environments.md +44 -0
- package/skills/qingflow-task-ops/references/workflow-usage.md +27 -0
- package/src/qingflow_mcp/__init__.py +1 -1
- package/src/qingflow_mcp/server.py +4 -2
- package/src/qingflow_mcp/server_app_user.py +2 -1
- package/src/qingflow_mcp/tools/record_tools.py +527 -292
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.
|
|
6
|
+
npm install @josephyan/qingflow-app-user-mcp@0.2.0-beta.23
|
|
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.
|
|
12
|
+
npx -y -p @josephyan/qingflow-app-user-mcp@0.2.0-beta.23 qingflow-app-user-mcp
|
|
13
13
|
```
|
|
14
14
|
|
|
15
15
|
Environment:
|
|
@@ -23,6 +23,8 @@ This package bootstraps a local Python runtime on first install and then starts
|
|
|
23
23
|
Bundled skills:
|
|
24
24
|
|
|
25
25
|
- `skills/qingflow-app-user`
|
|
26
|
+
- `skills/qingflow-record-crud`
|
|
27
|
+
- `skills/qingflow-task-ops`
|
|
26
28
|
- `skills/qingflow-record-analysis`
|
|
27
29
|
|
|
28
30
|
Note:
|
package/package.json
CHANGED
package/pyproject.toml
CHANGED
|
@@ -1,230 +1,63 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: qingflow-app-user
|
|
3
|
-
description:
|
|
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, task-center workflow work, or final analysis.
|
|
4
4
|
metadata:
|
|
5
|
-
short-description:
|
|
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
|
|
12
|
+
This skill is a **router skill** for operational usage inside existing Qingflow apps.
|
|
13
13
|
|
|
14
|
-
Use it
|
|
14
|
+
Use it when the request is operational, but you first need to decide which specialized skill should own it.
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
- record create / update / delete
|
|
19
|
-
- task-center usage
|
|
20
|
-
- record comments
|
|
21
|
-
- approval / reject / rollback / transfer
|
|
22
|
-
- directory lookup
|
|
16
|
+
This skill does **not** try to teach every detailed workflow itself.
|
|
17
|
+
It routes to:
|
|
23
18
|
|
|
24
|
-
|
|
25
|
-
|
|
19
|
+
- [$qingflow-record-crud](/Users/yanqidong/Documents/qingflow-next/.codex/skills/qingflow-record-crud/SKILL.md) for record browsing, detail lookup, create, update, and delete
|
|
20
|
+
- [$qingflow-task-ops](/Users/yanqidong/Documents/qingflow-next/.codex/skills/qingflow-task-ops/SKILL.md) for task-center usage, comments, approvals, rollback, transfer, urge, and directory lookup
|
|
21
|
+
- [$qingflow-record-analysis](/Users/yanqidong/Documents/qingflow-next/.codex/skills/qingflow-record-analysis/SKILL.md) for grouped analysis, ratios, rankings, trends, and final statistical conclusions
|
|
26
22
|
|
|
27
23
|
Before operating on data, identify whether the task targets `test` or `prod` and read [references/environments.md](references/environments.md).
|
|
28
24
|
If the user did not specify one, default to `prod`.
|
|
29
25
|
|
|
30
26
|
## Default Paths
|
|
31
27
|
|
|
32
|
-
|
|
28
|
+
Route to exactly one of these specialized paths:
|
|
33
29
|
|
|
34
|
-
1.
|
|
35
|
-
|
|
30
|
+
1. Record CRUD
|
|
31
|
+
Switch to [$qingflow-record-crud](/Users/yanqidong/Documents/qingflow-next/.codex/skills/qingflow-record-crud/SKILL.md)
|
|
36
32
|
|
|
37
|
-
2.
|
|
38
|
-
|
|
33
|
+
2. Task center / comments / workflow usage / directory
|
|
34
|
+
Switch to [$qingflow-task-ops](/Users/yanqidong/Documents/qingflow-next/.codex/skills/qingflow-task-ops/SKILL.md)
|
|
39
35
|
|
|
40
|
-
3.
|
|
41
|
-
|
|
36
|
+
3. Analysis
|
|
37
|
+
Switch to [$qingflow-record-analysis](/Users/yanqidong/Documents/qingflow-next/.codex/skills/qingflow-record-analysis/SKILL.md)
|
|
42
38
|
|
|
43
|
-
4.
|
|
44
|
-
|
|
39
|
+
4. MCP connection / auth / workspace selection
|
|
40
|
+
Switch to [$qingflow-mcp-setup](/Users/yanqidong/.codex/skills/qingflow-mcp-setup/SKILL.md)
|
|
45
41
|
|
|
46
|
-
|
|
47
|
-
|
|
42
|
+
## Routing Rules
|
|
43
|
+
|
|
44
|
+
- If the task is about browsing, reading, creating, updating, deleting, attachments, relations, or subtable writes, switch to `$qingflow-record-crud`
|
|
45
|
+
- If the task is about inbox, todo, cc, task-center workload, comments, approval, reject, rollback, transfer, urge, or directory lookup, switch to `$qingflow-task-ops`
|
|
46
|
+
- If the task is about grouped distributions, ratios, rankings, trends, insights, or any final statistical conclusion, switch to `$qingflow-record-analysis`
|
|
47
|
+
- If the MCP is not connected, authenticated, or bound to the right workspace, switch to `$qingflow-mcp-setup`
|
|
48
|
+
|
|
49
|
+
## Shared Preconditions
|
|
48
50
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
-
|
|
54
|
-
-
|
|
55
|
-
- `record_get`
|
|
56
|
-
- `record_write`
|
|
57
|
-
|
|
58
|
-
Directory tools:
|
|
59
|
-
|
|
60
|
-
- `directory_search`
|
|
61
|
-
- `directory_list_internal_users`
|
|
62
|
-
- `directory_list_all_internal_users`
|
|
63
|
-
- `directory_list_internal_departments`
|
|
64
|
-
- `directory_list_all_departments`
|
|
65
|
-
- `directory_list_sub_departments`
|
|
66
|
-
- `directory_list_external_members`
|
|
67
|
-
|
|
68
|
-
Task-center tools:
|
|
69
|
-
|
|
70
|
-
- `task_summary`
|
|
71
|
-
- `task_list`
|
|
72
|
-
- `task_facets`
|
|
73
|
-
- `task_mark_read`
|
|
74
|
-
- `task_mark_all_cc_read`
|
|
75
|
-
- `task_urge`
|
|
76
|
-
|
|
77
|
-
Comments and workflow usage actions:
|
|
78
|
-
|
|
79
|
-
- `record_comment_write`
|
|
80
|
-
- `record_comment_list`
|
|
81
|
-
- `record_comment_mentions`
|
|
82
|
-
- `record_comment_mark_read`
|
|
83
|
-
- `task_approve`
|
|
84
|
-
- `task_reject`
|
|
85
|
-
- `task_rollback_candidates`
|
|
86
|
-
- `task_rollback`
|
|
87
|
-
- `task_transfer_candidates`
|
|
88
|
-
- `task_transfer`
|
|
89
|
-
|
|
90
|
-
Do not use builder-side tools here.
|
|
91
|
-
|
|
92
|
-
## Standard Operating Order
|
|
93
|
-
|
|
94
|
-
1. Ensure auth exists
|
|
95
|
-
2. Ensure workspace is selected
|
|
96
|
-
3. Confirm target app and whether the task is browse / detail / write / task / analysis
|
|
97
|
-
4. Run `record_schema_get` before any non-trivial record read or write
|
|
98
|
-
5. If the request is analysis-like, switch to [$qingflow-record-analysis](/Users/yanqidong/Documents/qingflow-next/.codex/skills/qingflow-record-analysis/SKILL.md)
|
|
99
|
-
6. If the request is write-like, decide `insert / update / delete` before building any payload
|
|
100
|
-
7. If fields are still ambiguous after `record_schema_get`, ask the user to confirm from a short candidate list instead of guessing
|
|
101
|
-
8. For high-risk writes, task actions, or production changes, read the current state first whenever practical
|
|
102
|
-
9. After actions, report the affected `record_id`, `task_id`, counts, or returned item count
|
|
103
|
-
|
|
104
|
-
## Record Read Rules
|
|
105
|
-
|
|
106
|
-
- Use `record_list` for browse/export/sample inspection only
|
|
107
|
-
- Use `record_get` when `record_id` is known
|
|
108
|
-
- `record_list` accepts:
|
|
109
|
-
- `columns`
|
|
110
|
-
- `where`
|
|
111
|
-
- `order_by`
|
|
112
|
-
- `limit`
|
|
113
|
-
- `page`
|
|
114
|
-
- `record_list` is **not** an analysis tool
|
|
115
|
-
- If a request turns into grouped distributions, ratios, rankings, trends, or final statistical conclusions, switch to [$qingflow-record-analysis](/Users/yanqidong/Documents/qingflow-next/.codex/skills/qingflow-record-analysis/SKILL.md)
|
|
116
|
-
|
|
117
|
-
## Record Write Rules
|
|
118
|
-
|
|
119
|
-
Use `record_write` as the only default write tool.
|
|
120
|
-
|
|
121
|
-
### Write workflow
|
|
122
|
-
|
|
123
|
-
1. Run `record_schema_get`
|
|
124
|
-
2. Decide whether the task is `insert`, `update`, or `delete`
|
|
125
|
-
3. Build SQL-like JSON clauses
|
|
126
|
-
4. Run `record_write(mode="plan")`
|
|
127
|
-
5. If blockers are empty, run `record_write(mode="apply")`
|
|
128
|
-
6. For important writes, keep `verify_write=true`
|
|
129
|
-
|
|
130
|
-
### SQL-like JSON DSL
|
|
131
|
-
|
|
132
|
-
The DSL is clause-shaped like SQL, but it is **not raw SQL text**.
|
|
133
|
-
|
|
134
|
-
#### Insert
|
|
135
|
-
|
|
136
|
-
```json
|
|
137
|
-
{
|
|
138
|
-
"operation": "insert",
|
|
139
|
-
"mode": "plan",
|
|
140
|
-
"values": [
|
|
141
|
-
{ "field_id": 12, "value": "测试客户" },
|
|
142
|
-
{ "field_id": 18, "value": 1000 }
|
|
143
|
-
],
|
|
144
|
-
"submit_type": "submit",
|
|
145
|
-
"verify_write": true
|
|
146
|
-
}
|
|
147
|
-
```
|
|
148
|
-
|
|
149
|
-
#### Update
|
|
150
|
-
|
|
151
|
-
```json
|
|
152
|
-
{
|
|
153
|
-
"operation": "update",
|
|
154
|
-
"mode": "plan",
|
|
155
|
-
"record_id": 123,
|
|
156
|
-
"set": [
|
|
157
|
-
{ "field_id": 18, "value": 2000 }
|
|
158
|
-
],
|
|
159
|
-
"verify_write": true
|
|
160
|
-
}
|
|
161
|
-
```
|
|
162
|
-
|
|
163
|
-
#### Delete
|
|
164
|
-
|
|
165
|
-
```json
|
|
166
|
-
{
|
|
167
|
-
"operation": "delete",
|
|
168
|
-
"mode": "plan",
|
|
169
|
-
"record_ids": [123, 124]
|
|
170
|
-
}
|
|
171
|
-
```
|
|
172
|
-
|
|
173
|
-
### Write discipline
|
|
174
|
-
|
|
175
|
-
- `insert` uses `values`
|
|
176
|
-
- `update` uses `set`
|
|
177
|
-
- `delete` uses `record_id` or `record_ids`
|
|
178
|
-
- Do not send raw SQL text
|
|
179
|
-
- Do not invent formulas or expressions
|
|
180
|
-
- Do not use free-form `WHERE` updates or deletes
|
|
181
|
-
- Do not auto-fill missing fields
|
|
182
|
-
- Do not auto-resolve relation targets without first querying them
|
|
183
|
-
|
|
184
|
-
## Task-Center Rules
|
|
185
|
-
|
|
186
|
-
- Use `task_summary` for headline counts
|
|
187
|
-
- Use `task_list` for flat browsing
|
|
188
|
-
- Use `task_facets` for grouped worksheet or workflow-node buckets
|
|
189
|
-
- `task_box` must be one of:
|
|
190
|
-
- `todo`
|
|
191
|
-
- `initiated`
|
|
192
|
-
- `cc`
|
|
193
|
-
- `done`
|
|
194
|
-
- `flow_status` must be one of:
|
|
195
|
-
- `all`
|
|
196
|
-
- `in_progress`
|
|
197
|
-
- `approved`
|
|
198
|
-
- `rejected`
|
|
199
|
-
- `pending_fix`
|
|
200
|
-
- `urged`
|
|
201
|
-
- `overdue`
|
|
202
|
-
- `due_soon`
|
|
203
|
-
- `unread`
|
|
204
|
-
- `ended`
|
|
205
|
-
- Find the exact task or record first, then use `task_approve`, `task_reject`, `task_rollback`, or `task_transfer`
|
|
206
|
-
- Do not guess `workflow_node_id`
|
|
207
|
-
|
|
208
|
-
## Directory and Comments
|
|
209
|
-
|
|
210
|
-
- Use `directory_search` for fuzzy member/department lookup
|
|
211
|
-
- Use `directory_list_all_internal_users` and `directory_list_all_departments` only when the user explicitly wants a complete export
|
|
212
|
-
- Use `record_comment_write` after the exact `record_id` is known
|
|
213
|
-
- Use `record_comment_mentions` to resolve mention candidates before building complex comment payloads
|
|
214
|
-
|
|
215
|
-
## Response Interpretation
|
|
216
|
-
|
|
217
|
-
- `record_list` returns browse/sample data, not final analysis conclusions
|
|
218
|
-
- `record_write(mode="plan")` is static preflight, not runtime execution
|
|
219
|
-
- `record_write(mode="apply")` may still surface verification failures
|
|
220
|
-
- Treat `request_route` as the source of truth for live route debugging
|
|
221
|
-
- Prefer canonical schema titles and aliases in your final wording
|
|
222
|
-
- If only part of the requested work is completed, explicitly disclose which parts are done and which are not
|
|
51
|
+
- confirm environment first
|
|
52
|
+
- ensure auth exists
|
|
53
|
+
- ensure workspace is selected
|
|
54
|
+
- prefer canonical app ids, record ids, task ids, and workflow node ids over guessed names
|
|
55
|
+
- 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
|
|
56
|
+
- if the task can stay read-only, do not write or act
|
|
223
57
|
|
|
224
58
|
## Resources
|
|
225
59
|
|
|
226
60
|
- Environment switching: [references/environments.md](references/environments.md)
|
|
227
|
-
- Record
|
|
228
|
-
-
|
|
229
|
-
-
|
|
230
|
-
- Dedicated analysis workflow: [qingflow-record-analysis](/Users/yanqidong/Documents/qingflow-next/.codex/skills/qingflow-record-analysis/SKILL.md)
|
|
61
|
+
- Record CRUD: [$qingflow-record-crud](/Users/yanqidong/Documents/qingflow-next/.codex/skills/qingflow-record-crud/SKILL.md)
|
|
62
|
+
- Task center and workflow usage: [$qingflow-task-ops](/Users/yanqidong/Documents/qingflow-next/.codex/skills/qingflow-task-ops/SKILL.md)
|
|
63
|
+
- 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: "
|
|
4
|
-
default_prompt: "Use $qingflow-app-user
|
|
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."
|
|
@@ -11,10 +11,11 @@ For final statistics, grouped distributions, rankings, trends, or insight-style
|
|
|
11
11
|
|
|
12
12
|
## Write Preflight
|
|
13
13
|
|
|
14
|
-
- `record_write
|
|
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
|
|
15
16
|
- Use `record_schema_get` when field titles are uncertain instead of guessing ids
|
|
16
17
|
- Prefer `verify_write=true` for complex, relation-heavy, subtable, or production writes
|
|
17
|
-
- `record_write
|
|
18
|
+
- Even when `record_write` returns `ok=true`, it may still surface verification failures; do not report success before checking them
|
|
18
19
|
|
|
19
20
|
## Write Semantics
|
|
20
21
|
|
|
@@ -32,22 +32,22 @@ Prefer passing explicit `columns` when the user only needs a subset of fields.
|
|
|
32
32
|
|
|
33
33
|
## Write Pattern
|
|
34
34
|
|
|
35
|
-
Use `record_schema_get -> record_write
|
|
35
|
+
Use `record_schema_get -> record_write`.
|
|
36
36
|
|
|
37
37
|
1. Confirm the target app
|
|
38
38
|
2. Resolve fields with `record_schema_get`
|
|
39
39
|
3. Decide whether the task is `insert`, `update`, or `delete`
|
|
40
40
|
4. Build SQL-like JSON clauses
|
|
41
|
-
5. Run `record_write
|
|
42
|
-
6. If
|
|
43
|
-
7.
|
|
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`
|
|
44
45
|
|
|
45
46
|
### Insert
|
|
46
47
|
|
|
47
48
|
```json
|
|
48
49
|
{
|
|
49
50
|
"operation": "insert",
|
|
50
|
-
"mode": "plan",
|
|
51
51
|
"values": [
|
|
52
52
|
{ "field_id": 12, "value": "测试客户" },
|
|
53
53
|
{ "field_id": 18, "value": 1000 }
|
|
@@ -62,7 +62,6 @@ Use `record_schema_get -> record_write(mode="plan") -> record_write(mode="apply"
|
|
|
62
62
|
```json
|
|
63
63
|
{
|
|
64
64
|
"operation": "update",
|
|
65
|
-
"mode": "plan",
|
|
66
65
|
"record_id": 123,
|
|
67
66
|
"set": [
|
|
68
67
|
{ "field_id": 18, "value": 2000 }
|
|
@@ -76,7 +75,6 @@ Use `record_schema_get -> record_write(mode="plan") -> record_write(mode="apply"
|
|
|
76
75
|
```json
|
|
77
76
|
{
|
|
78
77
|
"operation": "delete",
|
|
79
|
-
"mode": "plan",
|
|
80
78
|
"record_ids": [123, 124]
|
|
81
79
|
}
|
|
82
80
|
```
|
|
@@ -90,7 +88,7 @@ Do not do this:
|
|
|
90
88
|
- do not invent formulas or expressions
|
|
91
89
|
- do not auto-fill missing required fields
|
|
92
90
|
- do not guess relation targets without first resolving them
|
|
93
|
-
- do not
|
|
91
|
+
- do not claim a blocked `record_write` was executed
|
|
94
92
|
|
|
95
93
|
## Unsupported Direct Writes
|
|
96
94
|
|
|
@@ -101,7 +99,7 @@ Do not attempt direct app-user writes for these field types:
|
|
|
101
99
|
- `35` image generation
|
|
102
100
|
- `36` document parsing
|
|
103
101
|
|
|
104
|
-
If the payload includes them, stop
|
|
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.
|
|
105
103
|
|
|
106
104
|
## Relation, Attachment, and Subtable Rules
|
|
107
105
|
|
|
@@ -11,9 +11,9 @@ metadata:
|
|
|
11
11
|
|
|
12
12
|
This skill is for record analysis inside existing Qingflow apps. Use it when the task is about `分析 / 洞察 / 分布 / 占比 / 平均 / 排名 / 趋势 / 所有 / 全部 / 全国 / 高价值` or any final statistical conclusion.
|
|
13
13
|
|
|
14
|
-
This skill assumes the MCP is already connected and authenticated. If not, switch to `$qingflow-mcp-setup` first. If the task is about creating, updating,
|
|
14
|
+
This skill assumes the MCP is already connected and authenticated. If not, switch to `$qingflow-mcp-setup` first. If the task is about creating, updating, or deleting records rather than analyzing them, switch to `$qingflow-record-crud`. If it is about task-center actions, comments, approvals, rollback, transfer, or directory-driven workflow work, switch to `$qingflow-task-ops`.
|
|
15
15
|
|
|
16
|
-
Before running analysis in `prod`, confirm the intended environment and compare `request_route` with the browser route
|
|
16
|
+
Before running analysis in `prod`, confirm the intended environment. If browser parity or live route debugging matters, call `record_analyze` with `output_profile=\"verbose\"` and compare `debug.request_route` with the browser route.
|
|
17
17
|
|
|
18
18
|
## Tool Scope
|
|
19
19
|
|
|
@@ -24,6 +24,12 @@ Use these tools as the core analysis surface:
|
|
|
24
24
|
|
|
25
25
|
Use `record_list` or `record_get` only when you need sample rows or a specific supporting example after the main analysis path.
|
|
26
26
|
|
|
27
|
+
`record_schema_get` now returns the **current user's applicant-node visible schema only**:
|
|
28
|
+
|
|
29
|
+
- hidden fields are omitted entirely
|
|
30
|
+
- absent fields should be interpreted as `当前用户在申请人节点下不可见/不可用`
|
|
31
|
+
- do not treat the schema as a builder/full-field metadata dump
|
|
32
|
+
|
|
27
33
|
## Hard Rules
|
|
28
34
|
|
|
29
35
|
- Analysis tasks must start with `record_schema_get`
|
|
@@ -71,6 +77,7 @@ For analysis:
|
|
|
71
77
|
- whether each side needs its own DSL
|
|
72
78
|
- If you cannot name the denominator from real schema fields and filters, do not use words like `渗透率`, `转化率`, `占比`, `比例`, or `%`
|
|
73
79
|
- If a field is still ambiguous after `record_schema_get`, do not guess; either select one unique `field_id` from the schema or ask the user to confirm from a short candidate list
|
|
80
|
+
- If a business field is absent from `record_schema_get`, do not infer or guess a hidden `field_id`; explain that the field is not visible in the current applicant-node permission scope
|
|
74
81
|
- If a statement depends on `count`, query `count`
|
|
75
82
|
- If a statement depends on total amount, query `sum`
|
|
76
83
|
- If a statement depends on average level, query `avg` or derive it from trusted `sum + count`
|
|
@@ -78,7 +85,7 @@ For analysis:
|
|
|
78
85
|
- If a statement depends on a ratio that the DSL cannot express directly, run the numerator and denominator separately, then compute the ratio outside MCP only after both sides are complete and compatible
|
|
79
86
|
- Rankings must come from structured sorted results, not from loose natural-language restatement
|
|
80
87
|
- When grouped rows are truncated, describe them as `已返回分组中` or `主要分组`
|
|
81
|
-
- If `
|
|
88
|
+
- If `completeness.rows_truncated=true` or `completeness.statement_scope=returned_groups_only`, do not use words like `各部门`、`所有分组`、`完整名单`、`全部渠道`
|
|
82
89
|
- If grouped rows are truncated, explicitly downgrade the wording to `前 N 个分组` or `主要分组`, never `全部`
|
|
83
90
|
- Complex answers should default to `先结构、后解读`: present the table / metrics / ordering first, then add concise interpretation
|
|
84
91
|
- Final wording should stay as close as possible to schema titles, dimension aliases, and metric aliases; do not rename the business object or field title unless the user asked for a rewrite
|
|
@@ -236,10 +243,17 @@ Two-dimensional cross analysis:
|
|
|
236
243
|
|
|
237
244
|
## Output Gate
|
|
238
245
|
|
|
246
|
+
- Read aggregate rows from `result.rows`
|
|
247
|
+
- Read overall totals from `result.totals.metric_totals`
|
|
248
|
+
- Read sort intent from `query.sort`
|
|
249
|
+
- Read ranked output from `ranking` when it is not `null`
|
|
250
|
+
- Read ratio output from `ratios` when it is not `null`; `ratios=null` is normal when MCP did not produce a native ratio block
|
|
251
|
+
- Read warning codes from `completeness.warnings`
|
|
252
|
+
|
|
239
253
|
- Only write `全量可信结论` when the supporting `record_analyze` calls report `completeness.status=complete` and `safe_for_final_conclusion=true`
|
|
240
254
|
- If any key analysis call is incomplete, downgrade the answer to `初步观察` or `部分结果`
|
|
241
255
|
- Treat `safe_for_final_conclusion=true` as necessary but not sufficient when the metric definition is incomplete or grouped rows are truncated
|
|
242
|
-
- If `
|
|
256
|
+
- If `completeness.statement_scope=returned_groups_only`, you may still give full-population conclusions about totals or ratios, but not a full grouped enumeration claim
|
|
243
257
|
- If aggregate-style output is full but list evidence is sample-only, split the answer into:
|
|
244
258
|
- `全量可信结论`
|
|
245
259
|
- `样本观察(不作为最终结论)`
|
|
@@ -11,6 +11,8 @@ Correct recovery:
|
|
|
11
11
|
3. build one or more small DSLs
|
|
12
12
|
4. run `record_analyze`
|
|
13
13
|
|
|
14
|
+
The schema here is applicant-node visible-only. If a field is absent, treat it as not available to the current user rather than switching to guessed ids or builder-side memory.
|
|
15
|
+
|
|
14
16
|
## Normalize relative time phrases before building the DSL.
|
|
15
17
|
|
|
16
18
|
Examples:
|
|
@@ -51,7 +53,7 @@ Split them into:
|
|
|
51
53
|
|
|
52
54
|
## Do not present truncated grouped rows as a full grouped list
|
|
53
55
|
|
|
54
|
-
If `
|
|
56
|
+
If `completeness.rows_truncated=true` or `completeness.statement_scope=returned_groups_only`:
|
|
55
57
|
|
|
56
58
|
- do not say `各部门`
|
|
57
59
|
- do not say `所有分组`
|
|
@@ -77,6 +79,8 @@ Correct recovery:
|
|
|
77
79
|
2. if several plausible candidates remain, ask the user to confirm from a short list
|
|
78
80
|
3. build the DSL only after the field is clear
|
|
79
81
|
|
|
82
|
+
If the intended field is absent from the schema altogether, stop and explain that it is not visible in the current applicant-node permission scope.
|
|
83
|
+
|
|
80
84
|
Examples of the right recovery question:
|
|
81
85
|
|
|
82
86
|
- “我找到两个可能的字段:`线索来源`、`来源渠道`。你要按哪个字段统计?”
|
|
@@ -21,6 +21,17 @@ Use this skill when the user asks for:
|
|
|
21
21
|
4. `record_analyze`
|
|
22
22
|
5. `record_list` only for sample inspection
|
|
23
23
|
|
|
24
|
+
Result reading order:
|
|
25
|
+
|
|
26
|
+
1. `result.rows`
|
|
27
|
+
2. `result.totals.metric_totals`
|
|
28
|
+
3. `ranking`
|
|
29
|
+
4. `ratios`
|
|
30
|
+
5. `completeness`
|
|
31
|
+
6. `presentation`
|
|
32
|
+
|
|
33
|
+
Treat `record_schema_get` as applicant-node visible-only schema. Missing fields are permission boundaries, not invitations to guess hidden ids.
|
|
34
|
+
|
|
24
35
|
## Distribution / ratio pattern
|
|
25
36
|
|
|
26
37
|
1. Run `record_schema_get`
|
|
@@ -32,10 +43,10 @@ Use this skill when the user asks for:
|
|
|
32
43
|
- sort by the count alias
|
|
33
44
|
5. Run `record_analyze`
|
|
34
45
|
6. Report:
|
|
35
|
-
- `
|
|
46
|
+
- `result.totals.metric_totals`
|
|
36
47
|
- `safe_for_final_conclusion`
|
|
37
|
-
- `
|
|
38
|
-
- `completeness.
|
|
48
|
+
- `completeness.statement_scope`
|
|
49
|
+
- `completeness.warnings`
|
|
39
50
|
7. If grouped rows are truncated, describe the answer as `主要分组` or `已返回分组中`, not `各部门` or `全部`
|
|
40
51
|
|
|
41
52
|
## penetration / conversion / share-of-total pattern
|
|
@@ -60,7 +71,8 @@ Use this skill when the user asks for:
|
|
|
60
71
|
- `metrics=[count,sum]` or `metrics=[count,avg,min,max]`
|
|
61
72
|
4. Run `record_analyze`
|
|
62
73
|
5. If the answer uses ranking language, make the ranking come from structured sorted results
|
|
63
|
-
6.
|
|
74
|
+
6. Prefer the structured `ranking` block when it exists instead of inferring order from loose text
|
|
75
|
+
7. Use list mode only to inspect examples after the aggregate result is understood
|
|
64
76
|
|
|
65
77
|
## Trend pattern
|
|
66
78
|
|
|
@@ -89,7 +101,7 @@ Never use list mode alone to justify final averages, shares, rankings, or region
|
|
|
89
101
|
- If you want to say `客单价高`, query `avg` or trusted `sum + count`
|
|
90
102
|
- If you want to say `增长` or `下降`, query a time bucket
|
|
91
103
|
- If you want to say `渗透率` or `占比`, query both numerator and denominator
|
|
92
|
-
- If you want to say `各部门` / `全部渠道` / `完整名单`, make sure `
|
|
104
|
+
- If you want to say `各部门` / `全部渠道` / `完整名单`, make sure `completeness.statement_scope=full_population` and `completeness.rows_truncated=false`
|
|
93
105
|
- If you want to say `Top N` or `排名`, make sure the result is explicitly sorted and the conclusion follows that returned order
|
|
94
106
|
- If the task is complex, default to `先结构、后解读`
|
|
95
107
|
|
|
@@ -55,8 +55,8 @@ Even when `safe_for_final_conclusion=true`, do not overstate the answer if:
|
|
|
55
55
|
- the conclusion mentions trend but no time bucket was queried
|
|
56
56
|
- the conclusion mentions单量/volume but no `count` metric was queried
|
|
57
57
|
- the conclusion depends on a derived metric the DSL cannot natively express
|
|
58
|
-
- `
|
|
59
|
-
- `
|
|
58
|
+
- `completeness.statement_scope=returned_groups_only`
|
|
59
|
+
- `completeness.rows_truncated=true`
|
|
60
60
|
|
|
61
61
|
## Grouped enumeration gate
|
|
62
62
|
|
|
@@ -78,7 +78,7 @@ If the user asked for multiple conclusions but only some are complete:
|
|
|
78
78
|
|
|
79
79
|
### 全量可信结论
|
|
80
80
|
|
|
81
|
-
- `
|
|
81
|
+
- `result.totals.metric_totals=...`
|
|
82
82
|
- `safe_for_final_conclusion=true`
|
|
83
83
|
- 这里写最终业务结论
|
|
84
84
|
|