weaver-work-cli 0.1.25 → 0.1.26

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 (81) hide show
  1. package/README.md +30 -30
  2. package/dist/cmd/root.js +1 -0
  3. package/dist/core/runtime-agent.js +19 -0
  4. package/dist/internal/e10/auth/commands.js +47 -27
  5. package/dist/internal/e10/auth/xiaoe.js +62 -43
  6. package/dist/internal/e10/context.js +5 -27
  7. package/dist/shortcuts/archive-oa/constants.js +66 -0
  8. package/dist/shortcuts/archive-oa/continuation.js +70 -0
  9. package/dist/shortcuts/archive-oa/errors.js +53 -0
  10. package/dist/shortcuts/archive-oa/host.js +157 -0
  11. package/dist/shortcuts/archive-oa/index.js +225 -0
  12. package/dist/shortcuts/archive-oa/manifest.js +62 -0
  13. package/dist/shortcuts/archive-oa/operations/borrow-car.js +159 -0
  14. package/dist/shortcuts/archive-oa/operations/borrow-url.js +108 -0
  15. package/dist/shortcuts/archive-oa/operations/confirm.js +48 -0
  16. package/dist/shortcuts/archive-oa/operations/contract.js +120 -0
  17. package/dist/shortcuts/archive-oa/operations/locate.js +50 -0
  18. package/dist/shortcuts/archive-oa/operations/registry.js +40 -0
  19. package/dist/shortcuts/archive-oa/operations/shared.js +181 -0
  20. package/dist/shortcuts/archive-oa/operations/types.js +45 -0
  21. package/dist/shortcuts/archive-oa/operations.js +13 -0
  22. package/dist/shortcuts/index.js +2 -0
  23. package/dist/shortcuts/invoice/host.js +2 -1
  24. package/dist/shortcuts/invoice/manifest.js +111 -0
  25. package/dist/shortcuts/invoice/operations/issuing-qys.js +361 -0
  26. package/dist/shortcuts/invoice/operations/issuing.js +5 -5
  27. package/dist/shortcuts/invoice/operations/registry.js +4 -0
  28. package/dist/shortcuts/workflow/endpoints.js +11 -0
  29. package/dist/shortcuts/workflow/host.js +2 -2
  30. package/dist/shortcuts/workflow/index.js +6 -36
  31. package/dist/shortcuts/workflow/operations/chatscene.js +270 -0
  32. package/dist/shortcuts/workflow/operations/form.js +899 -158
  33. package/dist/shortcuts/workflow/operations/read.js +111 -6
  34. package/dist/shortcuts/workflow/operations/sign-input.js +106 -0
  35. package/dist/shortcuts/workflow/operations/write.js +9 -1
  36. package/dist/shortcuts/workflow/stdout-compact.js +9 -1
  37. package/docs/archive-oa.md +79 -0
  38. package/docs/e10-auth.md +7 -6
  39. package/package.json +1 -1
  40. package/skill-template/business-info.json +16 -0
  41. package/skill-template/domains/archive-oa.md +19 -0
  42. package/skill-template/domains/yepiaotong.md +2 -2
  43. package/skills/weaver-e10-archive-oa/SKILL.md +159 -0
  44. package/skills/weaver-e10-archive-oa/references/archive-locate.md +49 -0
  45. package/skills/weaver-e10-archive-oa/references/borrow-car.md +76 -0
  46. package/skills/weaver-e10-archive-oa/references/borrow-flow.md +53 -0
  47. package/skills/weaver-e10-archive-oa/references/contract-search.md +63 -0
  48. package/skills/weaver-e10-archive-oa/references/disabled-capabilities.md +29 -0
  49. package/skills/weaver-e10-archive-oa/references/qys-contract-search.md +47 -0
  50. package/skills/weaver-e10-archive-oa/references/source-manifest.json +400 -0
  51. package/skills/weaver-e10-builder/SKILL.md +22 -0
  52. package/skills/weaver-e10-caizhilian/SKILL.md +37 -15
  53. package/skills/weaver-e10-caizhilian/references/agent-entry.md +7 -3
  54. package/skills/weaver-e10-caizhilian/references/collaboration.md +5 -3
  55. package/skills/weaver-e10-caizhilian/references/document.md +33 -11
  56. package/skills/weaver-e10-caizhilian/references/file-collection.md +4 -3
  57. package/skills/weaver-e10-caizhilian/references/file-upload.md +2 -3
  58. package/skills/weaver-e10-caizhilian/references/files.md +9 -3
  59. package/skills/weaver-e10-caizhilian/references/folder.md +48 -16
  60. package/skills/weaver-e10-caizhilian/references/setting-attach.md +13 -39
  61. package/skills/weaver-e10-caizhilian/references/setting-backup.md +13 -51
  62. package/skills/weaver-e10-caizhilian/references/setting-encrypt.md +20 -51
  63. package/skills/weaver-e10-caizhilian/references/setting-storage.md +82 -147
  64. package/skills/weaver-e10-caizhilian/references/withheld.md +20 -44
  65. package/skills/weaver-e10-shared/SKILL.md +22 -20
  66. package/skills/weaver-e10-shared/references/e10-auth-and-session.md +14 -15
  67. package/skills/weaver-e10-shared/references/non-interactive-environment.md +10 -10
  68. package/skills/weaver-e10-workflow/references/source-manifest.json +32 -22
  69. package/skills/weaver-e10-workflow/references/workflow-create.md +68 -28
  70. package/skills/weaver-e10-yepiaotong/SKILL.md +10 -7
  71. package/skills/weaver-e10-yepiaotong/references/invoice-issuing-examples.md +49 -1
  72. package/skills/weaver-e10-yepiaotong/references/invoice-issuing-qys-ledger.md +66 -0
  73. package/skills/weaver-e10-yepiaotong/references/invoice-reim.md +59 -36
  74. package/skills/weaver-e10-yepiaotong/references/reim-api-reference.md +54 -509
  75. package/skills/weaver-e10-yepiaotong/references/reim-examples.md +182 -345
  76. package/skills/weaver-e10-yepiaotong/references/reim-expense-subject-rules.md +4 -5
  77. package/skills/weaver-e10-yepiaotong/references/reim-form-fill-rules.md +153 -345
  78. package/skills/weaver-e10-yepiaotong/references/reim-phone-subsidy-rules.md +5 -5
  79. package/skills/weaver-e10-yepiaotong/references/reim-workflow.md +182 -154
  80. package/skills/weaver-e10-yepiaotong/references/source-manifest.json +96 -0
  81. package/skills/weaver-e10-yepiaotong/references/reim-fast-path.md +0 -119
@@ -15,17 +15,19 @@
15
15
 
16
16
  | 步 | 命令 | 做什么 |
17
17
  | --- | --- | --- |
18
- | 1 | `workflow.createForm` | 用用户说法解析可发起的工作流并**加载表单字段**:拿回 `fields`(**每个能填的字段一行**,有默认值的字段带 `initialValue`)、`historyRequestData`(历史参考值)、`continuation`(下一步的 `context`) |
19
- | 2 | `workflow.createRequest` | 按「填值纪律」把值拼进 `data`,`context` 传第 1 步的 `continuation`,`action` 取 `draft` / `submit`,**发起流程** |
20
- | 3 | —(无命令) | **把第 2 步的返回结果输出给用户**:有 `finalMarkdown` 就**原样粘贴**(一字不改)。**小e 环境例外:命令 stdout 整体就是一段 `<browsertool>` 标签块(没有 JSON 信封)**——见到输出以 `<browsertool>` 开头,就把**整段原样输出**(从 `<browsertool>` 到 `</browsertool>`):**不要用代码块(三反引号)包裹、不要加任何前后说明、不要解析它、也不要去找 `status` / `contextId`**(这一档不打信封);没有 `finalMarkdown`(如 `NEEDS_CONFIRMATION`)才按「主表(已填内容)展示规则」+「明细表(子表单)展示规则」自己拼。**不要重跑任何命令、不要自己再去查一遍流程。** |
18
+ | 1 | `workflow.createForm` | 用用户说法解析可发起的工作流并**加载表单字段**:拿回 `fields`(**每个能填的字段一行**,有默认值的字段带 `initialValue`)、`continuation`(下一步的 `context`)。**把 `userQuestion` 一起传进去**(一句话概括用户要发起什么)——命令会按你的意图把字段值直接算好放在 `data` 里返回,此时**不再返回** `historyRequestData` / `systemFields` |
19
+ | 2 | `workflow.createRequest` | **返回里有 `data` 就直接用它**(见「`data` 已填好时怎么用」):没有发票/附件意图就原样传;有就先上传、把返回对象替换进 `data` 再传。**只有在返回里没有 `data` 时**才按「填值纪律」自己拼 |
20
+ | 3 | —(无命令) | **把第 2 步的返回结果输出给用户**:返回结果里有 `finalMarkdown` 就把**它的内容整段原样输出**——**不要解释、不要改写、也不要补内容**。小e 环境(`BROWSER_FILL`)的 `finalMarkdown` 是一段 `<browsertool>` 标签块,同样**整段原样输出**(从 `<browsertool>` 到 `</browsertool>`:**不要用代码块(三反引号)包裹、不要加任何前后说明、不要解析它**);没有 `finalMarkdown`(如 `NEEDS_CONFIRMATION`)才按「主表(已填内容)展示规则」+「明细表(子表单)展示规则」自己拼。**不要重跑任何命令、不要自己再去查一遍流程。** |
21
21
 
22
22
  澄清、必填缺失、幂等重放等分支见下「发起链路」。
23
23
 
24
24
  ## 发起链路(两条命令的完整分支)
25
25
 
26
- 1. `workflow.createForm`:按用户说法解析可发起的工作流并载入表单,拿回 `continuation`(表单会话短句柄,载荷由 CLI 托管在本机)与 `fields`(**每个能填的字段一行**:`id` + 中文名 `name` + 所属明细 `subFormId`(主表字段省略该键)+ `componentKey`;**有默认值的字段直接带 `initialValue`**);**同时返回 `historyRequestData`**——本表单**要落值的字段**(口径同 `fields`)在历史流程里的取值参考(`null` = 没有可参考的)。
26
+ 1. `workflow.createForm`:按用户说法解析可发起的工作流并载入表单,拿回 `continuation`(表单会话短句柄,载荷由 CLI 托管在本机)与 `fields`(**每个能填的字段一行**:`id` + 中文名 `name` + 所属明细 `subFormId`(主表字段省略该键)+ `componentKey`;**有默认值的字段直接带 `initialValue`**)。**把 `userQuestion` 一起传进来**:
27
+ - 传了 `userQuestion` 且返回里带 `data` ⇒ **`data`** 就是按用户意图已经识别好的字段值(结构就是 `createRequest` 的入参),**此时的返回里没有** `historyRequestData` / `systemFields`;
28
+ - 返回里没有 `data` ⇒ 用 **`historyRequestData`**(本表单要落值的字段在历史流程里的取值参考,`null` = 没有可参考的)+ `systemFields`。
27
29
  - 返回 `NEEDS_CLARIFICATION` 时按 `candidates` 向用户确认(只问完整名称或其它可用于检索的关键词,**不要向用户索取 ID**),确认后由你按 `名称(ID)` 拼好、重发**同一条命令**。
28
- 2. 按用户意图把字段值填进 `data`(键用字段 id):**照「填值纪律」的优先级逐个字段一遍定案**——用户说了的照用户说的填;用户没说到、而该字段带 `initialValue` 的就用默认值(也可以干脆不传,CLI 会自动并入);其余字段按「历史流程数据参考规则」判断能不能落值。
30
+ 2. **返回里有 `data` 就直接用它**(见「`data` 已填好时怎么用」:没有发票/附件意图就原样传;有就先上传替换)。**只有在没有 `data` 时**,才按用户意图把字段值填进 `data`(键用字段 id):**照「填值纪律」的优先级逐个字段一遍定案**——用户说了的照用户说的填;用户没说到、而该字段带 `initialValue` 的就用默认值(也可以干脆不传,CLI 会自动并入);其余字段按「历史流程数据参考规则」判断能不能落值。
29
31
  3. `workflow.createRequest`:`context` 传第 1 步返回的 `continuation`,`action` 按用户意图取 `draft`/`submit`。
30
32
  - `action: "submit"` 且仍有必填缺失 → **命令不会创建流程**,返回 `NEEDS_INPUT` + `missingFields` + **渲染好的 `finalMarkdown`**(已填内容 + 明细 + 待补必填项清单;**历史取值一致的待补字段,命令已附一行 `历史推荐值`**);**不做任何值推断**——**把这份 `finalMarkdown` 原样发出**(与成功时完全同一口径:不弹窗、不挑字段、不自己列待补项、不解释),带同一 `context` 重发 `action: "submit"`。
31
33
  - `action: "draft"` 且仍有必填缺失 → 照常建草稿,`missingFields` 只作提醒(必须原样转述给用户)。
@@ -43,8 +45,44 @@
43
45
 
44
46
  **输出纪律(与上面的省时纪律同理:多写的每一句都在拖长回复,并让用户看不懂)**:① 面向用户**只给三样**——"这次做了什么、结果如何" + "**已填内容预览**"(展示口径见下文「主表(已填内容)展示规则」)+ "需要用户提供什么",其余不说——**尤其不要交代"用了哪个流程 / 编号是多少 / 我是怎么判断的"这类内部依据**;② **不要复述自己的判断过程、取舍与推演**,也不要写自我批评或事后反省——用户要的是结果,不是你怎么想的;③ **不要把澄清分支的区别讲给用户**(如"不是有多个候选要挑,而是一条都没命中"):该报"系统里没有「XX」"就按下文浏览按钮口径直接说结论,**不要解释你是怎么判定出来的**;④ 需要用户给值时**只说清"要什么值"**,不要顺带解释"我为什么判断不出来"。
45
47
 
48
+ ## `data` 已填好时怎么用
49
+
50
+ `createForm` 传了 `userQuestion`、返回里带 `data` 时:**它就是按用户意图已经识别好的字段值**,结构与 `createRequest` 的 `data` 入参**完全一致**(`{main: {<字段id>: <值>}, details: {<子表单id>: [{...}]}}`)。
51
+
52
+ **这时不要再重新推演字段值**——不要逐字段对照 `fields`、不要翻历史、不要把"我理解的意图"再拼一遍。直接基于这份 `data` 往下走,只有下面两种情况需要动手。
53
+
54
+ ### 情况一:用户本次没有发票 / 附件填写意图
55
+
56
+ `data` **原样**作为 `createRequest` 的 `data` 传进去,一个键都不用改、也不用补——字段值、明细行、标题都已经算好。
57
+
58
+ ### 情况二:用户本次要传发票 / 附件
59
+
60
+ `data` 里对应字段的值会是一个**占位符**(原样字符串):
61
+
62
+ - `"file"` —— 这个附件字段需要你先上传文件再填入
63
+ - `"invoice"` —— 这个发票字段需要你先从票夹取发票再填入
64
+
65
+ **占位符不是真实值,直接提交会失败。**按类型走对应技能,再把返回的对象**原位替换**回 `data` 的该字段:
66
+
67
+ | 占位符 | 怎么做 | 替换成什么 |
68
+ | --- | --- | --- |
69
+ | `"file"` | 用 `weaver-e10-caizhilian` 技能上传用户给的文件(`caizhilian.file-upload.prepare` → `.upload.prepare` → `.upload.apply`),拿到 `file_id` | `[{ "optionId": "<file_id>", "content": "<文件名>", "type": "file" }]`(多个文件就多项) |
70
+ | `"invoice"` | 用 `weaver-e10-yepiaotong` 技能:用户发了票就上传(`invoice.upload`);用户说"从票夹取"就查票夹拿 `fid`,再取完整发票对象 | `[{ "optionId": "<fid>", "type": "einvoice", "optionObj": { <完整发票对象> } }]` |
71
+
72
+ 三条纪律:
73
+
74
+ 1. **上传前必须先告诉用户「文件会先经过公网大模型」,并等用户确认**——不能默默上传。
75
+ 2. **替换完把整个 `data` 交给 `createRequest`**,其余字段保持 `createForm` 给的 `data` 原值,不要重算。
76
+ 3. 用户**没提到**的附件 / 发票字段,`data` 里本来就不会有,**不要自己去补**。
77
+
78
+ ### 没有 `data` 的时候
79
+
80
+ 返回里**没有** `data`(没传 `userQuestion`,或这次没能算出字段值),就按下面的「填值纪律」自己拼(此时会照常返回 `historyRequestData` / `systemFields`)。
81
+
46
82
  ## 填值纪律(一遍定案,不许回头)
47
83
 
84
+ > **仅在返回里没有 `data` 时适用**。有 `data` 就直接用(见「`data` 已填好时怎么用」),不要走下面这套逐字段推演。
85
+
48
86
  拼 `data` 只走一遍:**按字段逐个落值,每个字段只做一次取舍、取完不再回头看**;落到值就离开这个字段,不在同一字段上比较第二轮。
49
87
 
50
88
  **一趟走完、一个字段一行**——照这个形状(`<…>` 是占位,实写时换成本次的真字段与真值):
@@ -113,12 +151,12 @@
113
151
 
114
152
  | 返回 | 处置 |
115
153
  | --- | --- |
116
- | `BROWSER_FILL`(小e 环境) | **这一档没有 JSON 返回**——命令 stdout 直接就是那段 `<browsertool>` 标签块本身(看不到 `status` / `finalMarkdown` 这些键名)。**把命令输出整段作为本轮回复正文**:从 `<browsertool>` 到 `</browsertool>` 原样输出,**不要用代码块(三反引号)包裹、不要加任何前后说明**。它交给宿主浏览器页面去打开新建页并带上字段值;本档**不写服务端、不判必填缺失**。 |
154
+ | `BROWSER_FILL`(小e 环境) | **本档不写服务端、不判必填缺失**(没有 `requestId`)。`finalMarkdown` 就是那段 `<browsertool>` 标签块——**把 `finalMarkdown` 的内容整段原样作为本轮回复正文**:从 `<browsertool>` 到 `</browsertool>`,**不要解释、不要改写、不要补内容、不要用代码块(三反引号)包裹**。它交给宿主浏览器页面去打开新建页并带上字段值。 |
117
155
  | `NEEDS_INPUT`(必填缺失) | **不做任何值推断**——不看历史值、不用记忆里的常用值、不逐字段推演、不解释"为什么判断不出来"。**原样粘贴返回的 `finalMarkdown`**(命令已渲染好:结论一句 + `**已填内容**` 两列表 + `**明细表**` Excel 列 + `**还需要你提供**` 待补清单)——**一字不改、不弹窗、不自己列待补清单**。清单里带 `历史推荐值:` 的行是**命令按历史值一致性算好的**(全部一致或最近三条一致才会出现)——**不要自己再算一遍、也不要回头去翻历史**;用户认可就直接采用,其余项等用户给值后带同一 `context` 重发。 |
118
156
  | `CREATED` / `CREATED_SUBMITTED`(成功) | **原样粘贴返回的 `finalMarkdown`**(命令已渲染好:结论一句 + 流程编号/链接 + `**已填内容**` 两列表 + `**明细表**` Excel 列)——**一字不改、不重排、不自己再拼一遍表格**;链接**只出现在回复文本里**,不要打开。 |
119
157
  | `CREATED_SUBMIT_FAILED`(失败) | 同样**原样粘贴 `finalMarkdown`**(流程信息照常完整给出,末尾带 `**提交失败原因**:…`);不要读成"什么都没做成",不要重发同一次提交。 |
120
158
 
121
- **`finalMarkdown` = 命令渲染好的最终回复文本**(与查询侧的 `finalMarkdown` 同口径):在**「流程已落地」三态**与 **`NEEDS_INPUT`(必填缺失)**返回,**本轮回复正文 = 它的值本身(从第一个字符到最后一个字符,不增不减)**;`BROWSER_FILL`(小e 环境)是**同一份渲染档、换了投递方式**——它不经 JSON 信封,命令 stdout 整体就是那段 `<browsertool>` 标签块,**原样输出、不要包在代码块里**(见处置表,那里看不到 `finalMarkdown` 这个键名);其余状态字段、表格、待补清单、缺项的类型提示都已渲染在里面,不需要你再组织任何内容。**`**已填内容**` 两列表列的是「用户在表单上看到的、有值的、可编辑的主表字段」**(流程标题在前,业务字段按**表单布局顺序**随后,**含表单默认值**;只读/禁用、联动隐藏、没值的字段不列)——所以**里面会出现你没传过的字段(默认值)**,那是命令按表单实际已填状态渲染的,**照贴、不要删、不要改写、也不要把某个字段挪进待补清单**。它已包含全部要交代的内容——**回复里不出现它之外的任何内容**。`NEEDS_INPUT` 那份的读法:末段「**还需要你提供**」就是要问用户的全部内容(每项已标出在主表还是明细第几行),照它问即可——**不要回去翻历史值、也不要自己再列一遍**;其中带 `历史推荐值:` 的行是命令算好的,照抄即可(不必自己核对、更不要自己另算一条)。`finalMarkdown` 随 CLI **0.1.24** 起返回(`NEEDS_INPUT` 那份从 **0.1.25** 起、其 `历史推荐值` 行从 **0.1.26** 起);老版本命令没有这个字段时,才按下文「主表(已填内容)展示规则」+「明细表(子表单)展示规则」自己拼。
159
+ **`finalMarkdown` = 命令渲染好的最终回复文本**(与查询侧的 `finalMarkdown` 同口径):在**「流程已落地」三态**、**`NEEDS_INPUT`(必填缺失)**与 **`BROWSER_FILL`(小e 环境)**返回,**本轮回复正文 = 它的值本身(从第一个字符到最后一个字符,不增不减)**;`BROWSER_FILL`(小e 环境)也是同一份渲染档:`finalMarkdown` 里就是那段 `<browsertool>` 标签块,同样**整段原样输出**(不要解释、改写或补内容,不要包在代码块里);其余状态字段、表格、待补清单、缺项的类型提示都已渲染在里面,不需要你再组织任何内容。**`**已填内容**` 两列表列的是「用户在表单上看到的、有值的、可编辑的主表字段」**(流程标题在前,业务字段按**表单布局顺序**随后,**含表单默认值**;只读/禁用、联动隐藏、没值的字段不列)——所以**里面会出现你没传过的字段(默认值)**,那是命令按表单实际已填状态渲染的,**照贴、不要删、不要改写、也不要把某个字段挪进待补清单**。它已包含全部要交代的内容——**回复里不出现它之外的任何内容**。`NEEDS_INPUT` 那份的读法:末段「**还需要你提供**」就是要问用户的全部内容(每项已标出在主表还是明细第几行),照它问即可——**不要回去翻历史值、也不要自己再列一遍**;其中带 `历史推荐值:` 的行是命令算好的,照抄即可(不必自己核对、更不要自己另算一条)。**返回里没有 `finalMarkdown` 时**,才按下文「主表(已填内容)展示规则」+「明细表(子表单)展示规则」自己拼。
122
160
 
123
161
  `NEEDS_CONFIRMATION` / `partial` / `write_uncertain` / `ALREADY_APPLIED` 等其余状态**不给** `finalMarkdown`,按「返回」与「发起链路」里的对应条目处置(`ALREADY_APPLIED` 是"上一次已成功"的幂等回报——按返回值里的 `requestId` / `previousResult` 汇报)。
124
162
 
@@ -130,11 +168,12 @@
130
168
  | --- | --- | --- | --- |
131
169
  | `workflow` | `string[]` | 是 | 工作流条件——`"名称(ID)"` / 纯名称 / 纯数字 ID;**可一次给多个说法**:数组多元素,或一个元素内用英文逗号分隔(两者完全等价) |
132
170
  | `relatesTo` | `string` | 否 | 关联对象 id,**仅透传**,不影响表单初始化 |
171
+ | `userQuestion` | `string` | 否 | **用户的填单意图**(一句话概括,可以是多轮对话汇总后的最终需求,如"帮我发起一条9月手机话费报销流程,报销金额是100元")。**传了才可能拿到 `data`**(返回里带 `data` 就直接用它;不带就自己拼)。**强烈建议每次发起都传**。**只在这里传这一次**,后续 `createRequest` 不要再传 |
133
172
 
134
173
  - **自带显式 ID(`"名称(ID)"` 或纯数字)时不查可发起列表**:流程名与"你能不能发起"都由表单载入接口直接给出,因此比"按名称解析"少一整次往返。该 ID 不可用时仍回澄清,但会带 `clarificationReason` 说明是**哪一种**(见下)。
135
174
  - **纯名称**按当前用户**可发起**的工作流做模糊匹配,**可一次给多个说法**:数组多个元素(`["<说法1>","<说法2>"]`)与一个元素内用英文逗号分隔(`["<说法1>,<说法2>"]`)**完全等价**,CLI 会把各说法拆成关键词、命中取并集去重。
136
175
  - **直接选定并载入表单**时,`selectionSource` 标明是如何选定的:`workflowId`(按 ID 命中)/ `single`(唯一命中)/ `exactName`(全名精确匹配)。`exactName` 表示 CLI 已替用户选定,**不要再反问“您指的是哪一个”**。
137
- - **0 命中**,或**多命中且没有与所写完全一致的** → **澄清**:返回 `status: "NEEDS_CLARIFICATION"` + `candidates`(每项含 `id`/`name`/`display`,`display` 是 `名称(ID)`),此时**不返回任何表单数据**。把候选**原样**列给用户(不加 "(Recommended)"/"推荐" 等后缀,由用户明确选择),选定后用 `display` 的 `名称(ID)` 重发同一条命令。
176
+ - **需要澄清时** → 返回 `status: "NEEDS_CLARIFICATION"` + `candidates`(每项含 `id`/`name`/`display`,`display` 是 `名称(ID)`),此时**不返回任何表单数据**。把候选**原样**列给用户(不加 "(Recommended)"/"推荐" 等后缀,由用户明确选择),选定后用 `display` 的 `名称(ID)` 重发同一条命令。
138
177
  - **自带显式 ID 但该 ID 不可用** → 同样回澄清(`candidates` 为空),并带 `clarificationReason` 标明是**哪一种**——这两句话**必须分开说、不许混**:
139
178
  - `clarificationReason = "workflow_not_exist"`:该目标不存在(可能已删除或被停用)。如实告知"这个目标不存在",请用户改用该流程的**完整名称**(或其它可用于检索的关键词)重发——**不要向用户索取 ID**;**不要**说成"没有可发起的工作流"这类模糊说法。
140
179
  - `clarificationReason = "no_create_right"`:流程**存在**,但当前账号**没有发起权限**。**必须明确说出「存在但没有发起权限」**,绝不能转述成"流程不存在";并给出下一步:改用其他可发起的流程,或联系管理员为该流程授予发起权限。
@@ -177,14 +216,15 @@
177
216
  | `workflow` | `{id, name, description, type_name, selectionSource}`;`selectionSource` 见「输入」 |
178
217
  | `form` | `{id, layout_id}` |
179
218
  | `fields` | **字段清单(唯一一份)**:所有「可编辑 ∪ 必填且可见」的字段,每个字段一条记录(**整块在 stdout 上压成单行**,见下),见下 |
180
- | `historyRequestData` | 本表单**要落值的字段**(口径同 `fields`)在历史流程里的取值参考(`null` = 没有可参考的),见下 |
181
- | `systemFields` | `{permissions, defaults, levelOptions, secLevelOptions}`——系统字段的权限与默认值,见下 |
182
- | `systemFieldWarning` | 系统字段权限读取失败时的提示文本(正常为 `null`) |
219
+ | `data` | **★ 按用户意图已经识别好的字段值**,结构就是 `createRequest` 的 `data` 入参(`{main:{<字段id>:<值>}, details:{<子表单id>:[{...}]}}`)。**传了 `userQuestion` 且这次算出了字段值才有**;有它时 `historyRequestData` / `systemFields` / `systemFieldWarning` **都不出现**。怎么用见「`data` 已填好时怎么用」 |
220
+ | `historyRequestData` | **仅在返回里没有 `data` 时出现**:本表单**要落值的字段**(口径同 `fields`)在历史流程里的取值参考(`null` = 没有可参考的),见下 |
221
+ | `systemFields` | **仅在返回里没有 `data` 时出现**:`{permissions, defaults, levelOptions, secLevelOptions}`——系统字段的权限与默认值,见下 |
222
+ | `systemFieldWarning` | **仅在返回里没有 `data` 时出现**:系统字段权限读取失败时的提示文本(正常为 `null`) |
183
223
  | `requiredInfoWarning` | OA 未下发静态字段权限时的告警文本(正常为 `null`),见「注意」 |
184
- | `launchPreferences` | 该工作流的发起偏好(`available` + `promptText`),见下 |
224
+ | `workflowMemory` | 这条工作流维度的记忆(一段 Markdown 文本);**读不到时没有这个键**,见下 |
185
225
  | `fileUploadParams` | 附件字段的上传限制,挂在对应字段的 `fields[].fileUploadParams` 上 |
186
226
 
187
- **stdout 紧凑形态**:`fields` / `historyRequestData` / `systemFields` 这三个键在 stdout 上是**压成单行的**——只去掉缩进空白,**内容、结构、键序一字不改**(`parse` 出来与多行版完全一致,可以直接读)。所以 `fields` 那一行字段多时可能上万字符:**这是正常的,不是被截断、也不是数据缺失**,照常按 JSON 解析即可。**不要**因为"这一行太长 / 看着不像完整 JSON"就去读 `resultFile` 或重跑命令;`contextId` / `workflow` 等其余键仍是正常的多行缩进。
227
+ **stdout 紧凑形态**:`fields` / `data` / `historyRequestData` / `systemFields` 这几个键在 stdout 上是**压成单行的**——只去掉缩进空白,**内容、结构、键序一字不改**(`parse` 出来与多行版完全一致,可以直接读)。所以 `fields` 那一行字段多时可能上万字符:**这是正常的,不是被截断、也不是数据缺失**,照常按 JSON 解析即可。**不要**因为"这一行太长 / 看着不像完整 JSON"就去读 `resultFile` 或重跑命令;`contextId` / `workflow` 等其余键仍是正常的多行缩进。
188
228
 
189
229
  **`fields[]` 每个字段的键**(**能出现在这里就是能填的字段**):
190
230
 
@@ -203,25 +243,23 @@
203
243
  | `folderDependsOnOption` | 附件目录联动(配合最近一次的 `attachmentFolderIds` 用) |
204
244
  | `format` | 日期 / 时间字段自带的形式标记——**不用你管**,CLI 会按它自动归一化 |
205
245
 
206
- **`fields` 为什么不区分必填**(2026-10-14 口径):它就是「可编辑 ∪ 必填且可见」的全集,**「哪些字段可以落值」= 本清单,「哪个必填还没值」= `createRequest` 的 `missingFields`**,只有这两句口径。用户看不到、改不了的字段(只读 / 禁止编辑 / 联动隐藏 / 落在布局隐藏行上 / 落在明细表隐藏列上 / 落在多内容单元格的隐藏格上 / 不在当前布局的展示配置里)**不下发**——所以**条数不多是正常的**,不要拿它当"页面上肉眼可见的字段数",也不要因为"表单上看着没这么多"就怀疑字段清单不对。
246
+ **`fields` 为什么不区分必填**:它就是「可编辑 ∪ 必填且可见」的全集,**「哪些字段可以落值」= 本清单,「哪个必填还没值」= `createRequest` 的 `missingFields`**,只有这两句口径。用户看不到、改不了的字段(只读 / 禁止编辑 / 联动隐藏 / 落在布局隐藏行上 / 落在明细表隐藏列上 / 落在多内容单元格的隐藏格上 / 不在当前布局的展示配置里)**不下发**——所以**条数不多是正常的**,不要拿它当"页面上肉眼可见的字段数",也不要因为"表单上看着没这么多"就怀疑字段清单不对。
207
247
 
208
- **`historyRequestData`(历史参考值)**:范围是**本工作流**、**近一年、非草稿、按发起时间倒序的前 5 条**「我发起的」流程——不是"所有流程混在一起",所以里面每条都是同一张表单的单据,字段可直接对照;形如 `[{requestName, requestId, createdatetime, fieldValues: {<字段id>: <值>}}]`——`fieldValues` 是**「字段id → 值」的映射**(字段名不随每条记录重复下发:同一个名字要在每条记录里打印一遍,要名字请用 `fields`);值已按字段类型给出**可直接复用**的写法——浏览按钮 / 选项类为 `名称(id)`(多值以 `、` 分隔);**附件类为对象**(形如 `{"formField":{"id":"<字段id>"},"dataOptions":[{"optionId":"<附件ID>","content":"<文件名>","type":"<文件类型>"}]}`,可整块放进 `data`,见「历史流程数据参考规则」第三条);其余为普通字符串。**`null` 表示没有可参考的历史数据**(不返回空数组);某条历史流程在这批字段上一个值都没命中时会被整条剔除(所以条数可能少于 5)。**你不需要自己再去查历史流程。** 它给的是**本表单要落值的字段**(口径同 `fields`)的取值——填 `data` 时用它把能补的字段补上,判断口径见「历史流程数据参考规则」。
209
- - **`createRequest` 一侧不再返回它**(V12.1.102 起撤出):`NEEDS_INPUT` / `NEEDS_CONFIRMATION` 时**手上没有任何历史值**,必填缺失直接**一次问齐用户**(`NEEDS_INPUT` 用命令给的 `finalMarkdown`,见「createRequest 返回后的处置」)——**不要**回头翻 `createForm` 阶段那份历史值、也不要凭印象补值。(命令**内部**仍会用这份缓存给缺失字段算 `历史推荐值`,但原始历史始终不回给模型——一致性判断不外包给你。)
248
+ **`historyRequestData`(历史参考值,仅在没有 `data` 时才有)**:范围是**本工作流**、**近一年、非草稿、按发起时间倒序的前 5 条**「我发起的」流程——不是"所有流程混在一起",所以里面每条都是同一张表单的单据,字段可直接对照;形如 `[{requestName, requestId, createdatetime, fieldValues: {<字段id>: <值>}}]`——`fieldValues` 是**「字段id → 值」的映射**(字段名不随每条记录重复下发:同一个名字要在每条记录里打印一遍,要名字请用 `fields`);值已按字段类型给出**可直接复用**的写法——浏览按钮 / 选项类为 `名称(id)`(多值以 `、` 分隔);**附件类为对象**(形如 `{"formField":{"id":"<字段id>"},"dataOptions":[{"optionId":"<附件ID>","content":"<文件名>","type":"<文件类型>"}]}`,可整块放进 `data`,见「历史流程数据参考规则」第三条);其余为普通字符串。**`null` 表示没有可参考的历史数据**(不返回空数组);某条历史流程在这批字段上一个值都没命中时会被整条剔除(所以条数可能少于 5)。**你不需要自己再去查历史流程。** 它给的是**本表单要落值的字段**(口径同 `fields`)的取值——填 `data` 时用它把能补的字段补上,判断口径见「历史流程数据参考规则」。
249
+ - **`createRequest` 一侧没有它**:`NEEDS_INPUT` / `NEEDS_CONFIRMATION` 时**手上没有任何历史值**,必填缺失直接**一次问齐用户**(`NEEDS_INPUT` 用命令给的 `finalMarkdown`,见「createRequest 返回后的处置」)——**不要**回头翻 `createForm` 阶段那份历史值、也不要凭印象补值。
210
250
 
211
- **`systemFields`**:`permissions` 给各系统字段的 isview/isedit/ismandatory,`defaults` 是默认值,`levelOptions`/`secLevelOptions` 是紧急程度/密级选项。**只有 `isview=true` 且 `isedit=true` 的系统字段才需要填**;紧急程度/密级**只从这两个 options 取**(不得使用记忆、表单字段或其他来源);**`defaults` 已有非空值即视为已满足,不要询问用户、直接采用**;仅当 ismandatory=true 且默认值为空时才需要用户提供。
251
+ **`systemFields`(仅在返回里没有 `data` 时出现)**:`permissions` 给各系统字段的 isview/isedit/ismandatory,`defaults` 是默认值,`levelOptions`/`secLevelOptions` 是紧急程度/密级选项。**只有 `isview=true` 且 `isedit=true` 的系统字段才需要填**;紧急程度/密级**只从这两个 options 取**(不得使用记忆、表单字段或其他来源);**`defaults` 已有非空值即视为已满足,不要询问用户、直接采用**;仅当 ismandatory=true 且默认值为空时才需要用户提供。
212
252
 
213
- **`launchPreferences`**:该工作流的发起偏好(`available` + `promptText`)。`promptText` **只是「该工作流维度」那一段记忆**——全局画像 / 全局别名(`user.md` / `memory.md`)已由入口的 `workflow.memoryPrompt`(无参)给过,这里不再重复下发,所以**不要再调一次无参 `memoryPrompt` 来"补全"、也不要把两份拼接**(会重复)。`available: true` 时,**只能用它补用户没提到的非必填字段或口径类信息**(如签字意见口径、展示偏好);**必填字段一律不得用它里面的"常用值"补**——必填缺失只由 `missingFields` 告知、直接一次问齐用户(见「createRequest 返回后的处置」),不要为"能不能用记忆里的值"反复权衡;与用户本次明说的冲突时以用户本次为准。`available: false`(或带 `note`)说明该工作流还没有偏好或读取失败——**按新用户处理,不要重试读取**。
253
+ **`workflowMemory`**:这条工作流维度的记忆,一段 Markdown 文本。它**只含该工作流那一段**——全局画像 / 全局别名(`user.md` / `memory.md`)已由入口的 `workflow.memoryPrompt`(无参)给过,这里不再重复下发,所以**不要再调一次无参 `memoryPrompt` 来"补全"、也不要把两份拼接**(会重复)。**返回里没有这个键** ⇒ 该工作流还没有记忆(或没读到)——**按新用户处理,不要重试读取**。有这个键时,**只能用它补用户没提到的非必填字段或口径类信息**(如签字意见口径、展示偏好);**必填字段一律不得用它里面的"常用值"补**——必填缺失只由 `missingFields` 告知、直接一次问齐用户(见「createRequest 返回后的处置」),不要为"能不能用记忆里的值"反复权衡;与用户本次明说的冲突时以用户本次为准。
214
254
 
215
- **大表单超线形态**(`createForm` 输出**超过 20,000 字符**时才有):此时 stdout **只回一句话**——「当前表单内容较大,已临时写入文件 `resultFile路径`,请直接读取 `resultFile路径` 获取完整结果」。**`fields`、`contextId`、`historyRequestData` 一个都不在 stdout 里**,它们全都在那个文件里(**未裁剪的完整 pretty JSON**,与 stdout 同口径):`fields` / `historyRequestData` / `systemFields` / `contextId` / `continuation` 一样不少。所以:**先按 `resultFile` 把该文件一次读完**(整份读,不要只给个小的 `limit` 再分段;宿主若报单次读取超限,按报错提示调整),拿到字段清单与 `contextId` 之后再拼 `data`、走 `createRequest`。**不要重跑 `createForm`、不要分段读、不要用 `head`/`tail` 截断、也不要用脚本去挖文件。**
216
- - 结果里 `persistedResult: true` 表示走了落盘档;`outputChars` 是**本次输出那份最终文本的字符数**(判线量的就是它——口径 = 已压掉 `fields` / `historyRequestData` / `systemFields` 缩进空白后的整段 stdout,与小e 侧宿主那条 20,000 字符限制同源)。
255
+ **大表单超线形态**(`createForm` 输出**超过 20,000 字符**时才有):此时 stdout **只回一句话**——「当前表单内容较大,已临时写入文件 `resultFile路径`,请直接读取 `resultFile路径` 获取完整结果」。**`fields`、`data`、`contextId` 一个都不在 stdout 里**,它们全都在那个文件里(未裁剪的完整 pretty JSON,与 stdout 同口径):`fields` / `data` / `contextId` / `continuation` 一样不少(没有 `data` 时则是 `fields` / `historyRequestData` / `systemFields`)。所以:**先按 `resultFile` 把该文件一次读完**(整份读,不要只给个小的 `limit` 再分段;宿主若报单次读取超限,按报错提示调整),拿到字段清单与 `contextId` 之后再拼 `data`、走 `createRequest`。**不要重跑 `createForm`、不要分段读、不要用 `head`/`tail` 截断、也不要用脚本去挖文件。**
256
+ - 结果里 `persistedResult: true` 表示走了落盘档;`outputChars` 是本次输出那份最终文本的字符数。
217
257
  - **输出被宿主截断时**(只看到一小段预览、出现「已截断…字符」字样):**不要去读宿主的工具结果目录**(`~/.workbuddy/projects/**/tool-results/**`:没有读权限,去了必白跑一轮),按同一份输出里的 `resultFile` 取完整结果。
218
258
 
219
259
  `status` 为 `NEEDS_CLARIFICATION` 时只给 `candidates` / `clarificationKeyword` / `clarificationReason`(存在时,见「输入」里的 `workflow_not_exist` / `no_create_right`)/ `candidateCount` / `clarificationQuestion` / `note`,**不含任何表单数据**——它不是失败(`ok:true`),也不代表查询已执行。
220
260
 
221
261
  ### workflow.createRequest
222
262
 
223
- **小e 环境(`BROWSER_FILL`)档不走 JSON 信封**:stdout 整体就是一段 `<browsertool>` 标签块(见「createRequest 返回后的处置」),所以下表这些键**这一档在 stdout 上都看不到**——见到 `<browsertool>` 开头就照处置表处理,不要去找 `status` / `contextId`。
224
-
225
263
  | 键 | 说明 |
226
264
  | --- | --- |
227
265
  | `status` | `CREATED` / `CREATED_SUBMITTED` / `CREATED_SUBMIT_FAILED` / `NEEDS_INPUT` / `NEEDS_CONFIRMATION` / `ALREADY_APPLIED` / `BROWSER_FILL` |
@@ -237,8 +275,8 @@
237
275
  | `submitResult` / `submitFailReason` | 提交结果(`success`/`failed`);**只在本命令真正发起过提交(`action:submit`)时出现**,`action:draft` 不带 |
238
276
  | `finalMarkdown` | 命令渲染好的最终回复文本,见「createRequest 返回后的处置」 |
239
277
 
240
- - **`finalMarkdown`(命令渲染好的最终回复文本,与查询侧同名同口径)**:在**流程已落地的三个状态**(`CREATED` / `CREATED_SUBMITTED` / `CREATED_SUBMIT_FAILED`)与 **`NEEDS_INPUT`(必填缺失)**出现——**有它就原样粘贴、一字不改**(见「createRequest 返回后的处置」),不要再自己挑字段、拼主表/明细表格,也不要自己拼待补清单。`BROWSER_FILL`(小e 环境)用的是**同一份渲染档**,但**不经信封、没有这个键名**:那段文本直接就是命令的 stdout。`NEEDS_INPUT` 那份的末段「**还需要你提供**」就是待补必填项清单,其中**历史取值一致**的字段会带一行 `历史推荐值:…(依据)`——**由命令算好,模型不参与判断**;该分支**不再返回** `resolvedValues`(渲染素材已在命令内部用过)。
241
- - **`BROWSER_FILL`(小e 环境)**:本次**一个写请求都没发**(也没做必填判定)。这一段 `<browsertool>`(`arguments` 里带工作流名称 `title`、新建页地址 `src` 与 `sdkOptions`——PC / 移动两套路由与参数,`params.customParams` 里是这次要填的**字段 id → 值**,另有 `fieldAssignKeys` 列出全部字段 id)**就是命令 stdout 的全部内容**(不套信封,所以 `status` / `contextId` 这一档在输出里看不到)。**处置:把命令输出整段作为本轮回复正文**(不要包在代码块里),宿主会拿这段标签去打开新建页并把字段值带进去;`contextId` 未被消费,需要时由用户再发起一次即可。
278
+ - **`finalMarkdown`(命令渲染好的最终回复文本,与查询侧同名同口径)**:在**流程已落地的三个状态**(`CREATED` / `CREATED_SUBMITTED` / `CREATED_SUBMIT_FAILED`)、**`NEEDS_INPUT`(必填缺失)**与 **`BROWSER_FILL`(小e 环境)**出现——**有它就原样粘贴、一字不改**(见「createRequest 返回后的处置」),不要再自己挑字段、拼主表/明细表格,也不要自己拼待补清单。`BROWSER_FILL`(小e 环境)用的是**同一份渲染档**,`finalMarkdown` 里就是那段 `<browsertool>` 标签块——同样**整段原样输出**(不要解释、改写或补内容)。`NEEDS_INPUT` 那份的末段「**还需要你提供**」就是待补必填项清单,其中**历史取值一致**的字段会带一行 `历史推荐值:…(依据)`——**由命令算好,模型不参与判断**;该分支**不返回** `resolvedValues`。
279
+ - **`BROWSER_FILL`(小e 环境)**:本次**一个写请求都没发**(也没做必填判定)。`finalMarkdown` 就是这一段 `<browsertool>`(`arguments` 里带工作流名称 `title`、新建页地址 `src` 与 `sdkOptions`——PC / 移动两套路由与参数,`params.customParams` 里是这次要填的**字段 id → 值**,另有 `fieldAssignKeys` 列出全部字段 id)。**处置:把 `finalMarkdown` 的内容整段原样作为本轮回复正文**(从 `<browsertool>` 到 `</browsertool>`,不要解释、改写、补内容,不要包在代码块里),宿主会拿这段标签去打开新建页并把字段值带进去;`contextId` 未被消费,需要时由用户再发起一次即可。
242
280
  - `NEEDS_CONFIRMATION`(`ambiguities` 非空)时同时给 `resolvedValues`("我传的值 → 服务端最终值"的回显)与 `missingFields`——先把 `ambiguities` 解决掉,再用同一 `context` 重发。
243
281
  - `needVerificationConfirm: true` 时流程**已创建但未提交**:向用户确认后,用本次返回的 `requestId` 走提交(`workflow operateApply action=submit`);**不要用同一个 `context` 重发**——该句柄已消费,重发只会拿到 `ALREADY_APPLIED`。
244
282
  - **`CREATED_SUBMIT_FAILED`(提交结果=失败)**:流程**已创建为草稿**,但提交被服务端拒绝、**未进入审批**——表单数据已经落库,`requestId` / `requestName` / `url` 与成功时一样都给了(可直接打开查看或编辑),差别只在提交结果。此时 `submitResult: "failed"`、`submitFailReason` 是接口给出的失败原因。**处置:把失败原因原样转述给用户,并给出 `url`**;**不要**读成"什么都没做成",也**不要**原样重发同一次提交(会再堆一份草稿)。
@@ -246,7 +284,7 @@
246
284
 
247
285
  ## 历史流程数据参考规则
248
286
 
249
- 本节**只适用于 `createForm` 之后组装首次 `data` 那一步**——`createRequest` 返回 `missingFields`(必填缺失)后**一律不看历史值、直接问用户**(见「createRequest 返回后的处置」)。历史流程数据有两个来源:命令随 `createForm` 给的 `historyRequestData`,以及你自己按它的范围说明核对过的同类历史流程。**历史流程里的字段值只能按下面六条使用**——六条之外一律不推算、不拼接、不凭印象补值:
287
+ 本节**只适用于 `createForm` 之后组装首次 `data` 那一步,而且只在返回里没有 `data` 时**(有 `data` 就直接用,本节整套都不要走)——`createRequest` 返回 `missingFields`(必填缺失)后**一律不看历史值、直接问用户**(见「createRequest 返回后的处置」)。历史流程数据有两个来源:命令随 `createForm` 给的 `historyRequestData`,以及你自己按它的范围说明核对过的同类历史流程。**历史流程里的字段值只能按下面六条使用**——六条之外一律不推算、不拼接、不凭印象补值:
250
288
 
251
289
  1. **取值一致、且能推断与本次业务同类 → 可直接采用**:某个字段在**命中的历史流程里取值完全一致**(**一条也算**),并且对照这些历史流程的**其他字段值**,能推断它们和本次要填写的表单属于同一类业务时,直接把这个值填进 `data`,不必再问用户;**取值不一致**时,才需要**三条及以上**取值相同(同样要满足"能推断与本次同类业务"),否则按规则 2 处理或问用户。
252
290
  2. **看得出规律 → 按规律生成新值**:历史取值呈现可推断的规律(如编号递增、日期递推、金额分档)时,按该规律生成本次的新值;**规律推不出来就不要用**,照常问用户。
@@ -302,20 +340,22 @@
302
340
 
303
341
  ## 示例
304
342
 
305
- ### ① 解析工作流并载入表单(拿到 fields / historyRequestData / continuation)
343
+ ### ① 解析工作流并载入表单(拿到 fields / data / continuation)
306
344
 
307
345
  Windows PowerShell:
308
346
 
309
347
  ```powershell
310
- weaver-work-cli --json workflow run workflow.createForm --input-json '{"workflow":["<工作流名称>"]}'
348
+ weaver-work-cli --json workflow run workflow.createForm --input-json '{"workflow":["<工作流名称>"],"userQuestion":"<用户的填单意图原文>"}'
311
349
  ```
312
350
 
313
351
  macOS/Linux(bash/zsh):
314
352
 
315
353
  ```bash
316
- weaver-work-cli --json workflow run workflow.createForm --input-json '{"workflow":["<工作流名称>"]}'
354
+ weaver-work-cli --json workflow run workflow.createForm --input-json '{"workflow":["<工作流名称>"],"userQuestion":"<用户的填单意图原文>"}'
317
355
  ```
318
356
 
357
+ 返回里 `data` 就是按 `userQuestion` 算好的字段值;没有 `data` 时改用 `historyRequestData` 自己拼。
358
+
319
359
  ### ② 填好字段后一次完成发起(action 必填)
320
360
 
321
361
  Windows PowerShell:
@@ -3,8 +3,8 @@ name: weaver-e10-yepiaotong
3
3
  display_name: 泛微业票通发票
4
4
  display_name_en: Weaver Invoice
5
5
  description: "泛微 E10 业票通发票管理:查询票夹、OCR/查验、附件、流程发票字段、报销填单、智能开票确认链。"
6
- description_zh: "泛微 E10 业票通发票管理。支持查询个人/企业票夹、查看详情、上传、OCR/查验预览、下载附件、流程表单发票字段数据,通过 prepare/apply 确认链处理导入、新增、编辑、删除、报销单创建/更新、智能开票/存台账。"
7
- description_en: "Weaver E10 Yepiaotong invoice skill for folder queries, detail lookup, OCR and validation previews, attachment downloads, workflow invoice field data, reimbursement form submission, and confirmed invoice issuing."
6
+ description_zh: "泛微 E10 业票通发票管理。支持查询个人/企业票夹、查看详情、上传、OCR/查验预览、下载附件、流程表单发票字段数据,通过 prepare/apply 确认链处理导入、新增、编辑、删除、智能开票/存台账;报销填单由本技能准备发票与预填数据,报销单创建/修改调用 weaver-e10-workflow 的发起/修改能力。"
7
+ description_en: "Weaver E10 Yepiaotong invoice skill for folder queries, detail lookup, OCR and validation previews, attachment downloads, workflow invoice field data, reimbursement data preparation (forms are created and edited via weaver-e10-workflow), and confirmed invoice issuing."
8
8
  version: 1.0.3
9
9
  author: 泛微网络科技股份有限公司
10
10
  agent_created: true
@@ -17,7 +17,7 @@ cliHelp: "weaver-work-cli invoice --help"
17
17
  **`--is-connector` 判据**:用户明确使用连接器、或上下文要求用连接器完成任务 → 传 `true`;本次任务或上下文直接选择单独技能 → 不传;用户没有明确说明时,按**正在运行的这份 Skill 是哪一级**定——**用户级(条目标 `(user)`)不传,连接器级(标 `(connector)`)传**(同名 Skill 只会运行用户级那一份)。传 `true` 时不要再写 `--profile` / `--base-url`。完整规则见 `[../weaver-e10-shared/SKILL.md](../weaver-e10-shared/SKILL.md)`。
18
18
 
19
19
  认证和登录态只能按共享规则通过 `weaver-work-cli auth ...` 命令判断;禁止直接读取、列出、打印或解析用户主目录下的旧 `.e10-cli`、auth、config 或 Keychain 数据。
20
- 所有命令通过 `weaver-work-cli --json invoice run <operation>` 执行:简单 JSON 优先传 `--input-json '<json>'`,复杂或多行 JSON 先写入 UTF-8 文件再传 `--input <path>`,只有确认当前 shell 能稳定传管道时才使用 `--input -`。调用前先按需读取 references 下对应的文件,查参数结构,不要猜字段;**references 是第一信息源**,`weaver-work-cli invoice schema` 是 operation、字段和风险等级的合约来源。
20
+ 所有命令通过 `weaver-work-cli --json invoice run <operation>` 执行(唯一例外:报销单的创建/修改调用 `weaver-e10-workflow` 技能的 `weaver-work-cli --json workflow run workflow.*`,见下方「报销填单」):简单 JSON 优先传 `--input-json '<json>'`,复杂或多行 JSON 先写入 UTF-8 文件再传 `--input <path>`,只有确认当前 shell 能稳定传管道时才使用 `--input -`。调用前先按需读取 references 下对应的文件,查参数结构,不要猜字段;**references 是第一信息源**,`weaver-work-cli invoice schema` 是 operation、字段和风险等级的合约来源。
21
21
  命令示例、提示词和临时说明必须同时兼容 Windows 和 macOS/Linux;涉及 JSON 输入、用户目录、路径分隔符、Python 启动器、文件删除、目录查看或文件比对时,同时给 Windows PowerShell 与 macOS/Linux(bash/zsh)两套示例。Agent 先根据当前系统和 shell 选择对应示例,不确定时用 `node -p "process.platform"` 判断。Windows/PowerShell 下不要使用 `printf`、`$HOME/...`、`~/...`、bash 反斜杠续行、`rm/ls/diff/python3` 等 Unix-only 写法。
22
22
  涉及发票附件、图片、本地文件、远程 URL 文件或 OCR/文件解析的操作,执行前必须提醒用户:文件内容可能被上传到 E10 业票通、OCR/查验服务,并可能进入当前大模型上下文用于理解和处理;必须等待用户明确确认后才继续。
23
23
 
@@ -88,7 +88,8 @@ cliHelp: "weaver-work-cli invoice --help"
88
88
  | 准备/确认编辑发票 | `invoice run invoice.update.prepare/apply` | `[invoice-update.md](references/invoice-update.md)` |
89
89
  | 准备/确认删除发票 | `invoice run invoice.delete.prepare/apply` | `[invoice-delete.md](references/invoice-delete.md)` |
90
90
  | 生成流程表单发票浏览按钮 JSON | `invoice run invoice.browse-field.data` | `[invoice-browse-field-data.md](references/invoice-browse-field-data.md)` |
91
- | 报销自动填单、报销单创建/更新 | `invoice run invoice.reim.`* | `[invoice-reim.md](references/invoice-reim.md)` |
91
+ | 报销自动填单(发票、事前申请、工作流、预填数据) | `invoice run invoice.reim.`* | `[invoice-reim.md](references/invoice-reim.md)` |
92
+ | 报销单创建 / 修改 | `workflow run workflow.createForm/createRequest`、`workflow.editLoad/editPrepare/editApply`(`weaver-e10-workflow` 技能) | `[reim-workflow.md](references/reim-workflow.md)` Step 3~6;命令契约见 `[workflow-create.md](../weaver-e10-workflow/references/workflow-create.md)` |
92
93
  | 报销完整工作流编排、行为准则 | AI 内部 | `[reim-workflow.md](references/reim-workflow.md)` |
93
94
  | 批量获取多张发票预填信息 | `invoice run invoice.reim.row-info-batch` | `[reim-api-reference.md](references/reim-api-reference.md)` |
94
95
  | 报销 CLI operation 入参与返回值 | AI 内部 | `[reim-api-reference.md](references/reim-api-reference.md)` |
@@ -98,6 +99,7 @@ cliHelp: "weaver-work-cli invoice --help"
98
99
  | 话费补贴 / 话费报销硬拦截规则 | AI 内部 | `[reim-phone-subsidy-rules.md](references/reim-phone-subsidy-rules.md)` |
99
100
  | 报销端到端示例 | 参考 | `[reim-examples.md](references/reim-examples.md)` |
100
101
  | 智能开票或存入待开台账 | `invoice run invoice.issuing.make.prepare/apply` | `[invoice-issuing.md](references/invoice-issuing.md)` |
102
+ | 按契约锁合同/开票台账开票、查开票结果 | `invoice run invoice.issuing.qys.list/prepare` -> `invoice.issuing.make.apply` -> `invoice.issuing.result` | `[invoice-issuing-qys-ledger.md](references/invoice-issuing-qys-ledger.md)` |
101
103
  | 开票字段提取规则、税率推断、金额计算 | AI 内部 | `[invoice-issuing-field-rules.md](references/invoice-issuing-field-rules.md)` |
102
104
  | 开票端到端示例 | 参考 | `[invoice-issuing-examples.md](references/invoice-issuing-examples.md)` |
103
105
  | 共享、转让、标签或 schema 未列出的能力 | 无可用命令 | `[invoice-disabled-capabilities.md](references/invoice-disabled-capabilities.md)` |
@@ -116,10 +118,11 @@ cliHelp: "weaver-work-cli invoice --help"
116
118
  - 编辑发票:`invoice.update.prepare` -> 用户确认 -> `invoice.update.apply`
117
119
  - 删除发票:`invoice.delete.prepare` -> 用户确认 -> `invoice.delete.apply`
118
120
  - 流程发票字段:已有 `fid` 或详情时,用 `invoice.browse-field.data` 生成浏览按钮对象;不要运行旧源码脚本或直接调接口。
119
- - 报销快速路径(0.1.13 新增,流程为「总部费用报销」时优先用):查票分类 `invoice.reim.candidates.list` -> 用户确认范围 -> `invoice.reim.flow.create.auto-prepare`(或 `invoice.reim.template.build` + `flow.create.prepare`)-> 用户确认 -> `invoice.reim.flow.create.apply`,详见 `[reim-fast-path.md](references/reim-fast-path.md)`;明细字段与上级口径以该文档固化映射为准,其他流程仍走下面的手工路径。
120
- - **⚠️ 报销单「合同编号」固定填 `20260999`**(除非用户当次明确给出别的合同号):`template.build` / `auto-prepare` 必须显式传 `contractNo`,不传时 `合同号(100003720000001376)` 会**整条缺失且 `warnings` 不提示**,等于静默留空;手工组装路径同样不能留空或放进 `unable_to_fill`。口径见 `[reim-form-fill-rules.md](references/reim-form-fill-rules.md)` 主表字段映射。
121
- - 报销填单(完整工作流见 `[reim-workflow.md](references/reim-workflow.md)`):先用 `invoice.list`/`invoice.get`/`invoice.reim.file-ocr.preview` 获取发票 -> 展示汇总并确认 -> 用 `invoice.reim.requests.list`、`invoice.reim.workflow.resolve`、`invoice.reim.form.structure`、`invoice.reim.row-info`(单张)或 `invoice.reim.row-info-batch`(多张,推荐)、`invoice.reim.employee-superiors` 组装报销单 JSON(匹配规则见 `[reim-matching-rules.md](references/reim-matching-rules.md)`,填单规则见 `[reim-form-fill-rules.md](references/reim-form-fill-rules.md)`,科目匹配见 `[reim-expense-subject-rules.md](references/reim-expense-subject-rules.md)`;命中话费补贴/话费报销时先读 `[reim-phone-subsidy-rules.md](references/reim-phone-subsidy-rules.md)`)-> `invoice.reim.flow.create.prepare` -> 用户确认 -> `invoice.reim.flow.create.apply`。创建成功后修改只能用 `invoice.reim.flow.update.prepare/apply`。
121
+ - 报销填单(完整工作流见 `[reim-workflow.md](references/reim-workflow.md)`):先用 `invoice.reim.candidates.list`(按日期批量)/`invoice.list`/`invoice.get`/`invoice.reim.file-ocr.preview` 获取发票 -> 展示汇总并确认 -> `invoice.reim.requests.list` 匹配事前申请 -> `invoice.reim.workflow.resolve` 得到报销工作流 -> 并行 `workflow.createForm`(`weaver-e10-workflow`,传 `{workFlowName}({workFlowId})`)、`invoice.reim.row-info-batch`、`invoice.browse-field.data`(发票 + 配对凭证)-> 按规则组装 `data`(匹配规则见 `[reim-matching-rules.md](references/reim-matching-rules.md)`,填单规则见 `[reim-form-fill-rules.md](references/reim-form-fill-rules.md)`,科目匹配见 `[reim-expense-subject-rules.md](references/reim-expense-subject-rules.md)`;命中话费补贴/话费报销时先读 `[reim-phone-subsidy-rules.md](references/reim-phone-subsidy-rules.md)`)-> 展示预览、用户确认「存草稿 / 提交审批」-> `workflow.createRequest` -> 原样粘贴 `finalMarkdown`。创建成功后修改只能用 `workflow.editLoad` -> `workflow.editPrepare` -> 用户确认 -> `workflow.editApply`。
122
+ - 报销单创建/修改依赖同级的 `weaver-e10-workflow` 技能(`../weaver-e10-workflow/`);该技能不存在时停止并告知用户需要安装,不要改用其他方式创建报销单。
123
+ - **⚠️ 报销单「合同号」固定为 `20260999`**(除非用户当次明确给出别的合同号):`createForm` 已带出该默认值时不传;没带出或用户给了别的合同号时显式传。**用户给了合同号时,承担主体 / 相关客户 / 相关项目都不传,以合同联动带出的值为准(用户口头指定的承担主体也一样)**。口径见 `[reim-form-fill-rules.md](references/reim-form-fill-rules.md)` 主表字段规则。
122
124
  - 智能开票:Agent 读取 `invoice-issuing.md` 和 `invoice-issuing-field-rules.md`,从用户输入或附件中提取购方、税号、商品明细、金额和税率;资料不足时追问用户补齐,再执行 `invoice.issuing.make.prepare` -> 用户确认开票或存台账 -> `invoice.issuing.make.apply`。当前资料包没有客户档案查询 operation,不要调用 `invoice.customer.`*。
125
+ - 契约锁台账开票(用户提到合同号、契约锁合同或“按台账开票”时优先走这条,不要让 Agent 自己提取字段):`invoice.issuing.qys.list` -> 用户选定台账行 -> `invoice.issuing.qys.prepare`(CLI 按不含税金额组装开票入参)-> 用户确认 -> `invoice.issuing.make.apply`(`payload` 用 prepare 返回的 `normalizedPayload`)-> `invoice.issuing.result` 查一次结果。详见 `[invoice-issuing-qys-ledger.md](references/invoice-issuing-qys-ledger.md)`。
123
126
 
124
127
  ## 执行原则(减少误路由、误重试和无效消耗)
125
128
 
@@ -11,6 +11,7 @@
11
11
  **用户**:帮我开一张专票给深圳腾讯科技有限公司,税号 91440300MA5G3JE95L,10万的信息技术咨询服务费,含税
12
12
 
13
13
  **AI 处理**:
14
+
14
15
  - 提取:purchaser_name, purchaser_tax_no, goods_name, amount_raw=100000, amount_is_tax_inclusive=true
15
16
  - 推断税率:信息技术咨询服务 → 6%
16
17
  - 用户确认税率 → "好的"
@@ -25,7 +26,9 @@
25
26
  **用户**:帮我开票
26
27
 
27
28
  **AI**:
29
+
28
30
  > 需要以下信息:
31
+ >
29
32
  > 1. **购方名称**(开给谁?)
30
33
  > 2. **商品/服务名称**(开什么?)
31
34
  > 3. **金额**(多少钱?含税还是不含税?)
@@ -33,7 +36,8 @@
33
36
  **用户**:开给杭州阿里巴巴,技术服务费5万,不含税
34
37
 
35
38
  **AI**:
36
- > 请问是开**个人票(普票,无需税号)**还是**企业专票(需提供税号)**?
39
+
40
+ > 请问是开**个人票(普票,无需税号)还是企业专票(需提供税号)**?
37
41
 
38
42
  **用户**:专票,税号 91330100MA27F4RQ12
39
43
 
@@ -41,11 +45,14 @@
41
45
 
42
46
  ---
43
47
 
48
+
49
+
44
50
  ## 示例 3:个人普票
45
51
 
46
52
  **用户**:开普票,购方张三,500块钱的餐饮服务,含税
47
53
 
48
54
  **AI**:
55
+
49
56
  > 是否确认开**个人普票**?(个人票无需税号)
50
57
 
51
58
  **用户**:对,开个人票
@@ -56,9 +63,12 @@
56
63
 
57
64
  ---
58
65
 
66
+
67
+
59
68
  ## 示例 4:多明细行
60
69
 
61
70
  **用户**:开专票给北京XX公司,税号 91110000MA01B6BH1K,明细:
71
+
62
72
  1. 软件开发服务 8万不含税
63
73
  2. 技术咨询服务 2万不含税
64
74
  3. 服务器硬件 5台每台6000含税
@@ -67,16 +77,21 @@
67
77
 
68
78
  ---
69
79
 
80
+
81
+
70
82
  ## 示例 5:Excel 附件开票
71
83
 
72
84
  **用户**:(上传 Excel)帮我按这个表开票,购方杭州XX科技,税号91330100XX,专票,不含税
73
85
 
74
86
  **AI**:
87
+
75
88
  1. 解析 Excel 表头判断同一张发票多明细行
76
89
  2. 推断税率 → 预览 → 确认 → 提交
77
90
 
78
91
  ---
79
92
 
93
+
94
+
80
95
  ## 示例 6:存入待开台账
81
96
 
82
97
  **用户**:帮我开票给XX公司...(常规流程)
@@ -84,3 +99,36 @@
84
99
  预览后用户回复:"**先存台账**"
85
100
 
86
101
  **AI**:调用 makeInvoice 时添加 `"operateType": "5"` → 展示"已存入待开台账"
102
+
103
+ ---
104
+
105
+
106
+
107
+ ## 示例 7:按契约锁台账开票
108
+
109
+ **用户**:帮我把南昌我爱我家那份合同开票
110
+
111
+ **AI**:
112
+
113
+ 1. `invoice.issuing.qys.list`,`keyword="南昌我爱我家"` → 命中 1 行(合同号 20266105541,技术服务费,开票金额 20000,6%)
114
+ 2. `invoice.issuing.qys.prepare`,`formDataId="1328267444527472669"`,`mode="issue"`
115
+ 3. 展示预览:
116
+
117
+ > 合同号 20266105541(南昌我爱我家科技有限公司开放平台续购20000元10000份)
118
+ > 购方:南昌我爱我家科技有限公司,税号 91360125083909438T,全电专票
119
+ > 技术服务费,税率 6%,不含税 20000.00,税额 1200.00,价税合计 21200.00
120
+ > 确认开票吗?
121
+
122
+ **用户**:确认开票
123
+
124
+ **AI**:`invoice.issuing.make.apply`(`payload` = `normalizedPayload`)→ `invoice.issuing.result`,`externalDocumentNo="QYS-1328267444527472669"` → 展示发票号码或“开票中”
125
+
126
+ ---
127
+
128
+
129
+
130
+ ## 示例 8:台账命中多行
131
+
132
+ **用户**:开一下技术服务费那几单
133
+
134
+ **AI**:`invoice.issuing.qys.list`,`keyword="技术服务费"` → 命中 4 行,列出合同号、合同名称、购方、不含税金额、税率,请用户选择具体哪一行;用户选定后按示例 7 继续,一次只开一行。
@@ -0,0 +1,66 @@
1
+ # 契约锁开票台账开票
2
+
3
+ ## 什么时候读取
4
+
5
+ 用户要按契约锁合同开票、按合同号开票、从“契约锁合同商品信息”台账开票,或说“把 XX 公司那份合同开了”“开一下合同 20266105541 的票”时读取本文件。用户自己口述购方、金额、明细的开票不走本文件,改读 `invoice-issuing.md`。
6
+
7
+ ## Operation
8
+
9
+ | 阶段 | Operation | 风险 |
10
+ | --- | --- | --- |
11
+ | 查询待开票台账行 | `invoice.issuing.qys.list` | read |
12
+ | 按台账行组装开票入参并预览 | `invoice.issuing.qys.prepare` | read-before-write |
13
+ | 确认开票或存台账 | `invoice.issuing.make.apply` | high-risk-write |
14
+ | 查询异步开票结果 | `invoice.issuing.result` | read |
15
+
16
+ ## 组装规则(CLI 固化,Agent 不参与计算)
17
+
18
+ - 一行台账开一张发票,外部单号固定为 `QYS-{formDataId}`。
19
+ - 台账“开票金额”和“商品单价”是**不含税**金额:`taxSign="0"`,税额 = 金额 × 税率(四舍五入到分),价税合计 = 金额 + 税额。
20
+ - 商品名称优先取“开票名称”,为空时取“商品名称”;税率取台账“商品税率”(如 `6.0%` → 0.06)。
21
+ - 发票类型取台账“发票类型”的选项 ID(如全电专票 = `8`);购方名称、税号、地址、电话、开户行、账号按台账原值透传,空值不填。
22
+ - 销方固定为上海泛微网络科技股份有限公司。
23
+ - 已有发票号码、已关联开票流程、开票中金额大于 0 或已废弃的行,`qys.list` 默认不返回,`qys.prepare` 直接拒绝。
24
+
25
+ Agent **不得**自行修改预览里的金额、税率、税号或商品名称。用户要改,先让用户去台账改数据,再重新 `qys.prepare`。
26
+
27
+ ## 对话流程
28
+
29
+ 1. 用户给出合同号时传 `contractNo`;给出公司名、合同名等线索时传 `keyword`。调用 `invoice.issuing.qys.list`。
30
+ 2. 命中 0 行:告诉用户没有可开票的行;如果用户坚持该合同存在,可加 `includeIssued=true` 再查一次,展示 `blockers` 说明为什么不能开。
31
+ 3. 命中多行:列出合同号、合同审批流程名称、购方名称、商品、开票金额(不含税)、税率,让用户选择。不要替用户选。
32
+ 4. 用户选定后调用 `invoice.issuing.qys.prepare`,`mode` 默认 `issue`;用户说“先存台账/先不开”时用 `ledger`。
33
+ 5. 向用户展示预览:合同号、合同审批流程名称、购方名称、购方税号、发票类型、商品名称、税率、不含税金额、税额、价税合计。`warnings` 非空时逐条列出并询问是否仍然继续。
34
+ 6. 用户明确回复“确认开票”或同义确认后,把 `normalizedPayload` 原样作为 `payload`,连同 `continuation`、`confirm=true` 调用 `invoice.issuing.make.apply`。
35
+ 7. 正式开票成功后,用 `preview.externalDocumentNo` 调一次 `invoice.issuing.result`:`SUCCESS` 时展示发票号码;`PENDING` 时说明开票中、稍后再查;`FAILED` 时展示 `returnMessage`。不要循环轮询。
36
+
37
+ ## 命令
38
+
39
+ Windows PowerShell:
40
+
41
+ ```powershell
42
+ weaver-work-cli --json invoice run invoice.issuing.qys.list --input-json '{"keyword":"南昌我爱我家"}'
43
+ weaver-work-cli --json invoice run invoice.issuing.qys.prepare --input-json '{"formDataId":"1328267444527472669","mode":"issue"}'
44
+ weaver-work-cli --json invoice run invoice.issuing.result --input-json '{"externalDocumentNo":"QYS-1328267444527472669"}'
45
+ ```
46
+
47
+ macOS/Linux(bash/zsh):
48
+
49
+ ```bash
50
+ weaver-work-cli --json invoice run invoice.issuing.qys.list --input-json '{"keyword":"南昌我爱我家"}'
51
+ weaver-work-cli --json invoice run invoice.issuing.qys.prepare --input-json '{"formDataId":"1328267444527472669","mode":"issue"}'
52
+ weaver-work-cli --json invoice run invoice.issuing.result --input-json '{"externalDocumentNo":"QYS-1328267444527472669"}'
53
+ ```
54
+
55
+ `invoice.issuing.make.apply` 的 `payload` 较长,按 `invoice-issuing.md` 的做法先把 `{"payload":<normalizedPayload>,"continuation":"<continuation>","confirm":true}` 写入 UTF-8 JSON 文件,再用 `--input <path>` 传入。
56
+
57
+ ## 输出处理
58
+
59
+ - `qys.list` 返回 `items[]`(可读字段 + `issuable` + `blockers`)、`matched`、`truncated`、`scanned`、`scanComplete`。`scanComplete=false` 表示台账超过扫描上限,需提醒用户结果可能不全。
60
+ - `qys.prepare` 返回 `preview`、`warnings`、`ledgerRow`、`normalizedPayload`、`continuation`。只给用户看 `preview` 和 `warnings`,不要贴完整 JSON。
61
+ - `make.apply` 失败或连接中断时按 `invoice-issuing.md` 处理,**禁止自动重试**;同一台账行的外部单号固定,重复提交会被后端识别。
62
+
63
+ ## 注意
64
+
65
+ - 当前版本开票后不会自动回写台账的发票号码、开票时间等字段;向用户说明需要在台账侧另行处理。
66
+ - 正式开票是不可逆的高风险写入;同一 continuation 只服务一次确认,用户改了台账数据必须重新 `qys.prepare`。