weaver-work-cli 0.1.32 → 0.1.36
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/chunks/{archive-UMGX72K6.js → archive-XBVH7JU7.js} +2 -2
- package/dist/chunks/{archive-oa-N2IYBLF3.js → archive-oa-MZM3EKFQ.js} +2 -2
- package/dist/chunks/{asset-GLEGKFG5.js → asset-4XO7UOUW.js} +2 -2
- package/dist/chunks/{attachment-content-AQNX5N3S.js → attachment-content-VXSWANAC.js} +3 -2
- package/dist/chunks/{blog-E44OTVDA.js → blog-PGZKOPSC.js} +2 -2
- package/dist/chunks/{caizhilian-DQUFZXZL.js → caizhilian-BH4ZVGUN.js} +2 -2
- package/dist/chunks/{calendar-JKPIRKFD.js → calendar-MXEMTIO4.js} +2 -2
- package/dist/chunks/{chunk-QWY6PGL6.js → chunk-2LV74IWP.js} +361 -56
- package/dist/chunks/chunk-3SO6QL6U.js +73 -0
- package/dist/chunks/chunk-5DQEEGCC.js +229 -0
- package/dist/chunks/{chunk-G3QJULO2.js → chunk-6LLJFKJE.js} +1 -1
- package/dist/chunks/{chunk-C6R3B2ML.js → chunk-BPE37FPB.js} +35 -7
- package/dist/chunks/chunk-BYATLLEF.js +68 -0
- package/dist/chunks/chunk-BYBSCN4X.js +932 -0
- package/dist/chunks/{chunk-CVZ2JOSW.js → chunk-F746NKNF.js} +1 -1
- package/dist/chunks/{chunk-GCG2NMWR.js → chunk-HXJQI5NM.js} +4 -2
- package/dist/chunks/{chunk-YRVDW4WN.js → chunk-I6QGIBDM.js} +2 -2
- package/dist/chunks/{chunk-H7J4DC5R.js → chunk-JCSN3JGM.js} +2 -2
- package/dist/chunks/{chunk-2GA5ZIQL.js → chunk-JNG42JKG.js} +30 -1
- package/dist/chunks/{chunk-DW6AUUKS.js → chunk-JUXVYKII.js} +9 -4
- package/dist/chunks/{chunk-6RKD4DRZ.js → chunk-JYKABYCV.js} +2 -2
- package/dist/chunks/{chunk-6EFWDL7Y.js → chunk-NCOVUAZK.js} +2 -2
- package/dist/chunks/{chunk-E4Z23GHM.js → chunk-QHFANTX7.js} +1114 -904
- package/dist/chunks/{ebuilder-form-V5FG2EHC.js → chunk-QYGO5EE2.js} +22 -1148
- package/dist/chunks/{chunk-IURUFGZK.js → chunk-T72N74ZT.js} +50 -33
- package/dist/chunks/{chunk-H6XSTSLM.js → chunk-TC6MZAO3.js} +137 -204
- package/dist/chunks/{chunk-WKI2FBIQ.js → chunk-VPUTVEMC.js} +737 -341
- package/dist/chunks/{chunk-WSKBSQ2U.js → chunk-VPXOPQJI.js} +2 -2
- package/dist/chunks/chunk-WXFPWCXG.js +774 -0
- package/dist/chunks/{chunk-4YC43QQ4.js → chunk-XMGSYD6S.js} +4 -4
- package/dist/chunks/conflict-JAB2LJEZ.js +21 -0
- package/dist/chunks/continuation-RN6PZN2M.js +11 -0
- package/dist/chunks/contract-XI2EEIZU.js +9110 -0
- package/dist/chunks/cowork-SCPGLBA4.js +2527 -0
- package/dist/chunks/ebuilder-form-EYLHNOTA.js +121 -0
- package/dist/chunks/{ehr-HMFY6VIL.js → ehr-EAP77IMT.js} +1344 -27
- package/dist/chunks/{esb-ZYSVB7SG.js → esb-2TGGXEE7.js} +4 -4
- package/dist/chunks/{fna-B7RKPAZD.js → fna-2X7ZE7BU.js} +13 -8
- package/dist/chunks/{host-OCH2BCCV.js → host-C6EL2RKL.js} +3 -3
- package/dist/chunks/{host-45WED2KK.js → host-I4NRK4MX.js} +3 -3
- package/dist/chunks/{host-I4Z6BFYX.js → host-Q4LZGCRU.js} +3 -3
- package/dist/chunks/host-UEI5FGDM.js +23 -0
- package/dist/chunks/{host-KNZ52LJZ.js → host-XCLDDXKQ.js} +3 -3
- package/dist/chunks/{hrm-2KAZGUHI.js → hrm-YXERJM76.js} +3 -3
- package/dist/chunks/{im-ACJJWH4U.js → im-A4VZN2TQ.js} +88 -12
- package/dist/chunks/{invoice-ZK3WCX2U.js → invoice-2Z6YPMIS.js} +3 -3
- package/dist/chunks/{jiuchuanhui-5PQD3IL2.js → jiuchuanhui-AR5GMKZB.js} +2 -2
- package/dist/chunks/{lazy-dispatch-JQXBW3GM.js → lazy-dispatch-QXW7P4X3.js} +4 -4
- package/dist/chunks/{mail-S2HDDXO2.js → mail-7GZ6CPBJ.js} +45 -24
- package/dist/chunks/{meeting-QVN3I37L.js → meeting-3NMGA3MB.js} +278 -43
- package/dist/chunks/{okr-QNG4VC2Q.js → okr-BZ6XUOAG.js} +2 -2
- package/dist/chunks/operations-5QL3AECO.js +11 -0
- package/dist/chunks/{plan-A25EMW6U.js → plan-DR5CMUYP.js} +2 -2
- package/dist/chunks/{project-G6XV66DZ.js → project-6J63MK33.js} +2 -2
- package/dist/chunks/{registry-DC6KR3NH.js → registry-KDD7DHNK.js} +4 -4
- package/dist/chunks/{registry-2VLUAESA.js → registry-OZSMDVPP.js} +2 -2
- package/dist/chunks/{registry-7C5UMIPL.js → registry-TKX2E7C7.js} +2 -2
- package/dist/chunks/{registry-TI3CIUXF.js → registry-VRTNC6UR.js} +8 -6
- package/dist/chunks/{room-recommend-WRTHO6Y2.js → room-recommend-XCWRMB5P.js} +4 -3
- package/dist/chunks/{schedule-KFIITGSK.js → schedule-IVBICP32.js} +4 -3
- package/dist/chunks/{workflow-DJ7SYWAF.js → workflow-D74NFK3C.js} +179 -6
- package/dist/index.js +35 -25
- package/dist/internal/e10/auth-recovery.js +14 -4
- package/dist/internal/e10/fetch-timing.js +31 -0
- package/dist/internal/e10/request-runtime.js +5 -0
- package/dist/shortcuts/contract/host.js +34 -59
- package/dist/shortcuts/cowork/continuation.js +70 -0
- package/dist/shortcuts/cowork/errors.js +59 -0
- package/dist/shortcuts/cowork/host.js +180 -0
- package/dist/shortcuts/cowork/index.js +166 -0
- package/dist/shortcuts/cowork/manifest.js +65 -0
- package/dist/shortcuts/cowork/operations/discuss-write.js +277 -0
- package/dist/shortcuts/cowork/operations/item-write.js +380 -0
- package/dist/shortcuts/cowork/operations/member-write.js +283 -0
- package/dist/shortcuts/cowork/operations/permission-write.js +286 -0
- package/dist/shortcuts/cowork/operations/read.js +423 -0
- package/dist/shortcuts/cowork/operations/registry.js +39 -0
- package/dist/shortcuts/cowork/operations/review-write.js +157 -0
- package/dist/shortcuts/cowork/operations/shared.js +215 -0
- package/dist/shortcuts/cowork/operations/types.js +39 -0
- package/dist/shortcuts/cowork/operations.js +19 -0
- package/dist/shortcuts/ehr/host.js +4 -1
- package/dist/shortcuts/ehr/operations/recruit-candidate-import.js +757 -0
- package/dist/shortcuts/ehr/operations/recruit-position.js +367 -0
- package/dist/shortcuts/ehr/operations/recruit-stats.js +133 -0
- package/dist/shortcuts/ehr/operations/recruit-write.js +43 -16
- package/dist/shortcuts/ehr/operations/recruit.js +182 -10
- package/dist/shortcuts/ehr/operations/registry.js +6 -0
- package/dist/shortcuts/fna/operations/expense-chart.js +19 -7
- package/dist/shortcuts/im/diagnostics.js +97 -0
- package/dist/shortcuts/im/host.js +58 -31
- package/dist/shortcuts/im/index.js +7 -2
- package/dist/shortcuts/im/operations/at-mention.js +127 -0
- package/dist/shortcuts/im/operations/file-user.js +10 -2
- package/dist/shortcuts/im/operations/group-read.js +26 -5
- package/dist/shortcuts/im/operations/group-write.js +35 -28
- package/dist/shortcuts/im/operations/msg-sync.js +7 -2
- package/dist/shortcuts/im/operations/msg-write.js +76 -10
- package/dist/shortcuts/im/operations/quote-mention.js +119 -0
- package/dist/shortcuts/im/operations/session.js +1 -1
- package/dist/shortcuts/im/operations/shared.js +10 -0
- package/dist/shortcuts/im/operations/types.js +13 -0
- package/dist/shortcuts/index.js +10 -0
- package/dist/shortcuts/mail/host.js +12 -1
- package/dist/shortcuts/mail/operations/types.js +17 -2
- package/dist/shortcuts/meeting/host.js +27 -34
- package/dist/shortcuts/meeting/index.js +79 -1
- package/dist/shortcuts/meeting/manifest.js +10 -0
- package/dist/shortcuts/meeting/operations/create.js +4 -1
- package/dist/shortcuts/meeting/operations/eb/catalog.js +10 -0
- package/dist/shortcuts/meeting/operations/eb/conflict.js +84 -8
- package/dist/shortcuts/meeting/operations/eb/create-flow.js +1195 -140
- package/dist/shortcuts/meeting/operations/eb/factory.js +170 -8
- package/dist/shortcuts/meeting/operations/eb/index.js +16 -3
- package/dist/shortcuts/meeting/operations/eb/room-recommend.js +50 -5
- package/dist/shortcuts/meeting/operations/eb-fallback.js +163 -0
- package/dist/shortcuts/meeting/operations/env.js +99 -46
- package/dist/shortcuts/meeting/operations/form-fields.js +110 -0
- package/dist/shortcuts/meeting/operations/invitation.js +79 -20
- package/dist/shortcuts/meeting/operations/registry.js +2 -0
- package/dist/shortcuts/meeting/operations/standard-guard.js +71 -0
- package/dist/shortcuts/meeting/operations.js +16 -0
- package/dist/shortcuts/workflow/endpoints.js +8 -3
- package/dist/shortcuts/workflow/index.js +110 -1
- package/dist/shortcuts/workflow/operations/form.js +204 -36
- package/dist/shortcuts/workflow/operations/read.js +104 -23
- package/dist/shortcuts/workflow/operations/todoSmartConvert/aigroupRules.js +448 -0
- package/dist/shortcuts/workflow/operations/todoSmartConvert/aigroupStore.js +106 -0
- package/dist/shortcuts/workflow/operations/todoSmartConvert/businessRules.js +47 -0
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.collect.js +30 -23
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.core.js +1 -0
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.group.js +1 -0
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.groupSummary.js +2 -1
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.js +2 -4
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.smartGroup.js +138 -181
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.summary.js +12 -7
- package/dist/shortcuts/workflow/operations.js +23 -1
- package/docs/e10-auth.md +1 -1
- package/docs/ehr.md +1 -1
- package/docs/fna.md +2 -1
- package/docs/im.md +8 -1
- package/docs/todo-smart-convert/README.md +1 -1
- package/docs/todo-smart-convert/data-contract.md +2 -2
- package/docs/todo-smart-convert/subgroup-rules.md +6 -0
- package/package.json +1 -1
- package/skill-template/business-info.json +18 -0
- package/skill-template/domains/cowork.md +14 -0
- package/skill-template/domains/yimiaoban.md +3 -3
- package/skill-template/skill-template.md +1 -1
- package/skills/weaver-e10-blog/SKILL.md +5 -5
- package/skills/weaver-e10-caizhilian/SKILL.md +5 -5
- package/skills/weaver-e10-calendar/SKILL.md +5 -5
- package/skills/weaver-e10-cowork/SKILL.md +101 -0
- package/skills/weaver-e10-cowork/references/cowork-read.md +90 -0
- package/skills/weaver-e10-cowork/references/cowork-write.md +131 -0
- package/skills/weaver-e10-cowork/references/safety-boundaries.md +45 -0
- package/skills/weaver-e10-esb/SKILL.md +5 -5
- package/skills/weaver-e10-hrm/SKILL.md +5 -5
- package/skills/weaver-e10-jinchengda/SKILL.md +2 -2
- package/skills/weaver-e10-jiuchuanhui/SKILL.md +5 -5
- package/skills/weaver-e10-jucailin/SKILL.md +38 -14
- package/skills/weaver-e10-jucailin/references/recruit-create.md +104 -0
- package/skills/weaver-e10-jucailin/references/recruit-read.md +25 -0
- package/skills/weaver-e10-jucailin/references/recruit-write.md +13 -0
- package/skills/weaver-e10-jucailin/references/salary.md +15 -11
- package/skills/weaver-e10-mail/SKILL.md +17 -14
- package/skills/weaver-e10-meeting/SKILL.md +442 -46
- package/skills/weaver-e10-meeting/references/meeting-eb.md +135 -3
- package/skills/weaver-e10-meeting/references/meeting-invitation.md +28 -2
- package/skills/weaver-e10-meeting/references/meeting-queries.md +9 -6
- package/skills/weaver-e10-meeting/references/meeting-verification.md +8 -6
- package/skills/weaver-e10-meeting.zip +0 -0
- package/skills/weaver-e10-okr/SKILL.md +5 -5
- package/skills/weaver-e10-okr/references/source-manifest.json +3 -3
- package/skills/weaver-e10-plan/SKILL.md +5 -5
- package/skills/weaver-e10-qiyecheng/SKILL.md +5 -2
- package/skills/weaver-e10-qiyecheng/references/catalog.md +2 -2
- package/skills/weaver-e10-qiyecheng/references/expense-chart.md +15 -1
- package/skills/weaver-e10-qiyecheng/references/source-manifest.json +22 -21
- package/skills/weaver-e10-shared/SKILL.md +12 -12
- package/skills/weaver-e10-shared/references/e10-auth-and-session.md +4 -4
- package/skills/weaver-e10-wenshuding/SKILL.md +5 -5
- package/skills/weaver-e10-workflow/SKILL.md +29 -5
- package/skills/weaver-e10-workflow/aigroup/default.json +88 -0
- package/skills/weaver-e10-workflow/references/todo-smart-convert.md +66 -14
- package/skills/weaver-e10-workflow/references/workflow-agent-entry.md +1 -1
- package/skills/weaver-e10-workflow/references/workflow-memory.md +1 -1
- package/skills/weaver-e10-workflow/references/workflow-query.md +12 -10
- package/skills/weaver-e10-workflow/references/workflow-view.md +2 -2
- package/skills/weaver-e10-workflow/tools/todo-serve.cjs +239 -0
- package/skills/weaver-e10-workflow/{scripts → tools}/todo-summary.cjs +218 -28
- package/skills/weaver-e10-yepiaotong/SKILL.md +10 -8
- package/skills/weaver-e10-yepiaotong/references/invoice-reim.md +7 -7
- package/skills/weaver-e10-yepiaotong/references/reim-api-reference.md +10 -10
- package/skills/weaver-e10-yepiaotong/references/reim-examples.md +40 -37
- package/skills/weaver-e10-yepiaotong/references/reim-expense-subject-rules.md +4 -4
- package/skills/weaver-e10-yepiaotong/references/reim-form-fill-rules.md +27 -38
- package/skills/weaver-e10-yepiaotong/references/reim-phone-subsidy-rules.md +4 -4
- package/skills/weaver-e10-yepiaotong/references/reim-workflow.md +37 -29
- package/skills/weaver-e10-yimiaoban/SKILL.md +156 -33
- package/skills/weaver-e10-yimiaoban/references/ding-write.md +1 -1
- package/skills/weaver-e10-yimiaoban/references/error-codes.md +5 -1
- package/skills/weaver-e10-yimiaoban/references/group-read.md +5 -1
- package/skills/weaver-e10-yimiaoban/references/group-write.md +6 -4
- package/skills/weaver-e10-yimiaoban/references/msg-read.md +1 -0
- package/skills/weaver-e10-yimiaoban/references/msg-write.md +34 -2
- package/skills/weaver-e10-yimiaoban/references/safety-boundaries.md +5 -2
- package/skills/weaver-e10-yimiaoban/references/source-manifest.json +79 -58
- package/skills/weaver-e10-yimiaoban/references/user-remind.md +2 -2
- package/skills/weaver-e10-ziguanjia/SKILL.md +5 -5
|
@@ -6,6 +6,9 @@ import { workflowManifest } from './manifest.js';
|
|
|
6
6
|
import { executeWorkflowOperation } from './operations.js';
|
|
7
7
|
import { workflowValidationError } from './errors.js';
|
|
8
8
|
import { compactStdoutPaths } from './stdout-compact.js';
|
|
9
|
+
import { join } from 'node:path';
|
|
10
|
+
import { loadRules, resetActiveRules } from './operations/todoSmartConvert/aigroupRules.js';
|
|
11
|
+
import { clearUserIntents, readRawUserIntents, readUserIntents, saveUserIntents, } from './operations/todoSmartConvert/aigroupStore.js';
|
|
9
12
|
function asOptions(value) {
|
|
10
13
|
return value && typeof value === 'object' && !Array.isArray(value) ? value : {};
|
|
11
14
|
}
|
|
@@ -114,6 +117,53 @@ async function executeAndPrint(ctx, operation, input) {
|
|
|
114
117
|
process.exitCode = isCliError(error) ? error.exitCode : ExitCode.GeneralError;
|
|
115
118
|
}
|
|
116
119
|
}
|
|
120
|
+
/**
|
|
121
|
+
* 目录里的 `fields` 只取 `inputSchema.properties` 的键名,供 agent 判断「这个字段存不存在」。
|
|
122
|
+
*
|
|
123
|
+
* ★ 2026-10-28:整份 manifest 实测 65,748 B,超过 stdout 预算(`DEFAULT_RESULT_THRESHOLD_BYTES`
|
|
124
|
+
* = 24 KB)后,公共输出层按 `COMPACT_TIERS` 第一档把 `operations` 截到 10 条 —— 26 个 operation 里
|
|
125
|
+
* 排在后面的(`createRequest` 之后,含 `workflow.todoSmartConvert`)在 stdout 上完全不可见,
|
|
126
|
+
* 且没有任何「还有 16 条」的提示。此处改为默认编目形态(约 15 KB,26 条全可见),
|
|
127
|
+
* 完整 inputSchema 用 `--operation` 单取,整份完整 manifest 用 `--full`。
|
|
128
|
+
*/
|
|
129
|
+
function fieldNamesOf(inputSchema) {
|
|
130
|
+
const properties = inputSchema.properties;
|
|
131
|
+
if (!properties || typeof properties !== 'object' || Array.isArray(properties))
|
|
132
|
+
return [];
|
|
133
|
+
return Object.keys(properties);
|
|
134
|
+
}
|
|
135
|
+
function manifestIndex() {
|
|
136
|
+
return {
|
|
137
|
+
schemaVersion: workflowManifest.schemaVersion,
|
|
138
|
+
name: workflowManifest.name,
|
|
139
|
+
title: workflowManifest.title,
|
|
140
|
+
version: workflowManifest.version,
|
|
141
|
+
host: workflowManifest.host,
|
|
142
|
+
status: workflowManifest.status,
|
|
143
|
+
sourceSkill: workflowManifest.sourceSkill,
|
|
144
|
+
capabilities: workflowManifest.capabilities,
|
|
145
|
+
operationCount: workflowManifest.operations.length,
|
|
146
|
+
operations: workflowManifest.operations.map((definition) => ({
|
|
147
|
+
name: definition.name,
|
|
148
|
+
resource: definition.resource,
|
|
149
|
+
summary: definition.summary,
|
|
150
|
+
...(definition.capability ? { capability: definition.capability } : {}),
|
|
151
|
+
risk: definition.risk,
|
|
152
|
+
...(definition.requiresConfirmation ? { requiresConfirmation: true } : {}),
|
|
153
|
+
fields: fieldNamesOf(definition.inputSchema),
|
|
154
|
+
})),
|
|
155
|
+
withheldOperations: workflowManifest.withheldOperations,
|
|
156
|
+
operationsHint: '默认只列 operation 与字段名;字段类型、枚举和填写口径用 `workflow schema --operation <name>` 单取,整份完整 manifest 用 `workflow schema --full`。',
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
function findOperationContract(name) {
|
|
160
|
+
const full = name.startsWith('workflow.') ? name : `workflow.${name}`;
|
|
161
|
+
const matched = workflowManifest.operations.find((definition) => definition.name === full);
|
|
162
|
+
if (!matched) {
|
|
163
|
+
throw workflowValidationError('operation_unknown', `流程模块不支持操作:${name}`);
|
|
164
|
+
}
|
|
165
|
+
return matched;
|
|
166
|
+
}
|
|
117
167
|
function withJsonInputOptions(command) {
|
|
118
168
|
command
|
|
119
169
|
.option('--input <path>', 'JSON input file, or - for stdin')
|
|
@@ -130,8 +180,67 @@ export const workflowShortcut = {
|
|
|
130
180
|
.description('泛微E10流程智能助手(待办/已办/我发起/全部、详情、操作、批量、发起、修改)');
|
|
131
181
|
workflow.command('schema')
|
|
132
182
|
.description('Print workflow operation manifest for agents')
|
|
183
|
+
.option('--operation <name>', 'print one operation with its full inputSchema')
|
|
184
|
+
.option('--full', 'print the whole manifest (about 65 KB; stdout may be trimmed)')
|
|
185
|
+
.action(action((ctx, options) => {
|
|
186
|
+
const opts = asOptions(options);
|
|
187
|
+
const requested = String(opts.operation ?? '').trim();
|
|
188
|
+
if (requested && opts.full === true) {
|
|
189
|
+
throw workflowValidationError('option_conflict', '不能同时传 --operation 和 --full');
|
|
190
|
+
}
|
|
191
|
+
if (opts.full === true) {
|
|
192
|
+
ctx.output.write(workflowManifest, { json: true });
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
if (requested) {
|
|
196
|
+
ctx.output.write(findOperationContract(requested), { json: true });
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
ctx.output.write(manifestIndex(), { json: true });
|
|
200
|
+
}));
|
|
201
|
+
/**
|
|
202
|
+
* ai二次分组规则库:`<skill>/aigroup/default.json`(系统只读)+ CLI 状态目录下的
|
|
203
|
+
* `aigroup/user-intents.json`(用户意图,不随 skill 分发)。
|
|
204
|
+
* 意图由模型理解、但**落盘必须结构化**:这里统一做校验 + 按 workflowName 整条覆盖。
|
|
205
|
+
*/
|
|
206
|
+
const aigroup = workflow
|
|
207
|
+
.command('aigroup')
|
|
208
|
+
.description('ai二次分组规则库(默认规则 + 用户意图)');
|
|
209
|
+
aigroup.command('show')
|
|
210
|
+
.description('Print effective ai-group rules (default merged with user intents)')
|
|
211
|
+
.option('--raw', 'also print user-intents.json as stored on disk')
|
|
212
|
+
.action(action((ctx, options) => {
|
|
213
|
+
const opts = asOptions(options);
|
|
214
|
+
const loaded = loadRules({ ctx: ctx });
|
|
215
|
+
const user = readUserIntents({ ctx: ctx });
|
|
216
|
+
ctx.output.write({
|
|
217
|
+
dir: loaded.dir,
|
|
218
|
+
defaultFile: join(loaded.dir, 'default.json'),
|
|
219
|
+
userIntentFile: user.file,
|
|
220
|
+
userIntentExists: user.exists,
|
|
221
|
+
userIntentError: user.error,
|
|
222
|
+
defaults: loaded.file.defaults,
|
|
223
|
+
rules: loaded.file.rules,
|
|
224
|
+
userRules: user.rules,
|
|
225
|
+
warnings: loaded.warnings,
|
|
226
|
+
...(opts.raw === true && user.exists ? { rawUserIntents: readRawUserIntents(user.file) } : {}),
|
|
227
|
+
}, { json: true });
|
|
228
|
+
}));
|
|
229
|
+
withJsonInputOptions(aigroup.command('set')
|
|
230
|
+
.description('Save user-intent rules: validated, whole-entry replace by workflowName')
|
|
231
|
+
.action(action(async (ctx, options) => {
|
|
232
|
+
const payload = await inputFrom(options);
|
|
233
|
+
const result = saveUserIntents(payload, { ctx: ctx });
|
|
234
|
+
// 同一进程内后续命令要看到新规则,避免读到旧的进程内缓存
|
|
235
|
+
resetActiveRules();
|
|
236
|
+
ctx.output.write(result, { json: true });
|
|
237
|
+
})));
|
|
238
|
+
aigroup.command('clear')
|
|
239
|
+
.description('Empty user-intent rules (default.json is never touched)')
|
|
133
240
|
.action(action((ctx) => {
|
|
134
|
-
|
|
241
|
+
const file = clearUserIntents({ ctx: ctx });
|
|
242
|
+
resetActiveRules();
|
|
243
|
+
ctx.output.write({ cleared: true, file }, { json: true });
|
|
135
244
|
}));
|
|
136
245
|
withJsonInputOptions(workflow.command('run')
|
|
137
246
|
.description('Run a workflow operation with JSON input')
|
|
@@ -24,8 +24,9 @@ import { resolveSignRemark } from './sign-input.js';
|
|
|
24
24
|
import { compactStdoutPaths } from '../stdout-compact.js';
|
|
25
25
|
import { continuationReplayError } from '../continuation.js';
|
|
26
26
|
import { writeStateFileBestEffort } from '../state.js';
|
|
27
|
-
import { buildHistoryRequestData, fetchHistoryListSnapshot, filterHistoryRequestData, pickUniqueMineWorkflow } from './read.js';
|
|
27
|
+
import { buildHistoryRequestData, fetchHistoryListSnapshot, filterHistoryRequestData, pickUniqueMineWorkflow, prefetchHistoryDetails } from './read.js';
|
|
28
28
|
import { hasXiaoEEnv } from '../../../internal/e10/auth/xiaoe.js';
|
|
29
|
+
import { createFetchTimingSink, runWithFetchTiming } from '../../../internal/e10/fetch-timing.js';
|
|
29
30
|
import { buildChatSceneInput, formatLocalNow, requestFormFill } from './chatscene.js';
|
|
30
31
|
// ---------------------------------------------------------------------------
|
|
31
32
|
// 常量(与 Python 源逐条对齐)
|
|
@@ -448,6 +449,12 @@ function parseTenantSetting(data) {
|
|
|
448
449
|
* 只读字段 35→0);不带时拿到的才是表单设计级的真实属性。
|
|
449
450
|
*/
|
|
450
451
|
function buildLayoutRequest(workflowId, runtime, frame) {
|
|
452
|
+
// 建模表单(relateType=WEA_EBUILDER)的 `module` 与桥接服务名都不是 workflow:服务端按请求体里的
|
|
453
|
+
// `module` 解析 `@Service("<module>_FormCoreService")`,传 `workflow` 会直接 500「未找到名为
|
|
454
|
+
// FormCoreService 的实例对象」(2026-10-29 e-cology 建模流程 1179913136549412865 实测:只把该值
|
|
455
|
+
// 改成 ebuildercard 即 200,其余 params 逐字不变)。页面同场景传 `module:"ebuildercard"` +
|
|
456
|
+
// `customParam.bridgeService:"ebuilder"`(`loadBaseParam` 顶层也返回 `bridgeService:"ebuilder"`)。
|
|
457
|
+
const isEbForm = String(frame.relate_type ?? '').trim() === 'WEA_EBUILDER';
|
|
451
458
|
const custom = {
|
|
452
459
|
permissionType: frame.permission_type,
|
|
453
460
|
requestId: runtime.request_id,
|
|
@@ -463,6 +470,7 @@ function buildLayoutRequest(workflowId, runtime, frame) {
|
|
|
463
470
|
mobile: false,
|
|
464
471
|
formId: frame.form_id,
|
|
465
472
|
source: 'view',
|
|
473
|
+
...(isEbForm ? { bridgeService: 'ebuilder' } : {}),
|
|
466
474
|
isAgent: false,
|
|
467
475
|
beAgentId: '0',
|
|
468
476
|
hideSysFieldArea: true,
|
|
@@ -478,7 +486,7 @@ function buildLayoutRequest(workflowId, runtime, frame) {
|
|
|
478
486
|
terminalType: 'PC',
|
|
479
487
|
formId: frame.form_id,
|
|
480
488
|
...(nodePermissionEnabled && permissionId ? { permissionId } : {}),
|
|
481
|
-
module: 'workflow',
|
|
489
|
+
module: isEbForm ? 'ebuildercard' : 'workflow',
|
|
482
490
|
customParam: custom,
|
|
483
491
|
cacheUid: randomUUID(),
|
|
484
492
|
newLayout: frame.new_layout,
|
|
@@ -1478,7 +1486,23 @@ async function resolveCreateWorkflow(rawWorkflow, env) {
|
|
|
1478
1486
|
// 澄清文案里回显的是**用户原话**(不是切分后的关键词)——用户要能认出自己给的条件
|
|
1479
1487
|
const queryText = rawTerms.join('、');
|
|
1480
1488
|
if (!rawTerms.length) {
|
|
1481
|
-
|
|
1489
|
+
// ★ 2026-10-30 用户裁定:这一档不是「名称没匹配上」,而是**必填入参 `workflow` 根本没给**
|
|
1490
|
+
// (缺键 / 空数组 / 空字符串都算)。原先与「只给了填充词」共用同一句澄清,模型看到的是
|
|
1491
|
+
// 「请提供完整名称」,于是键名写错(如写成 `workflows`、`name`)时不知道自己漏了 `workflow`,
|
|
1492
|
+
// 只会回头把锅甩给用户。现在单独标 `clarificationReason=workflow_required` 并下发
|
|
1493
|
+
// `missingInput` + `requiredInput`,让模型知道「是我少传了入参、要按这个形态补」。
|
|
1494
|
+
throw workflowClarificationError('workflow', '', '要发起哪个流程?请提供该流程的完整名称(或其它可用于检索的关键词)后再继续。', [], {
|
|
1495
|
+
clarificationReason: 'workflow_required',
|
|
1496
|
+
missingInput: ['workflow'],
|
|
1497
|
+
requiredInput: {
|
|
1498
|
+
workflow: {
|
|
1499
|
+
required: true,
|
|
1500
|
+
type: 'string | string[]',
|
|
1501
|
+
description: '要发起的工作流:完整名称、名称关键词,或「名称(ID)」;纯数字按工作流 ID 处理。',
|
|
1502
|
+
example: ['费用报销'],
|
|
1503
|
+
},
|
|
1504
|
+
},
|
|
1505
|
+
});
|
|
1482
1506
|
}
|
|
1483
1507
|
// 先做**纯本地**的解析:显式 ID(`名称(ID)` / 纯数字)与名称关键词(一格可含多个,见
|
|
1484
1508
|
// `splitCreateKeywords`)。这一步不依赖远端结果,于是能先判"到底有没有可用条件"——
|
|
@@ -1744,9 +1768,9 @@ function singleExplicitWorkflowId(rawWorkflow) {
|
|
|
1744
1768
|
return parsed.id ?? (/^[0-9]+$/.test(terms[0]) ? terms[0] : '');
|
|
1745
1769
|
}
|
|
1746
1770
|
/** 表单载入 + 该工作流的记忆:两者只共享 `workflowId`,可以并行。 */
|
|
1747
|
-
async function loadCreateFormPack(workflowId, env) {
|
|
1771
|
+
async function loadCreateFormPack(workflowId, env, options = {}) {
|
|
1748
1772
|
const [{ data }, workflowMemory] = await Promise.all([
|
|
1749
|
-
buildCreateFormData(workflowId, env),
|
|
1773
|
+
buildCreateFormData(workflowId, env, options),
|
|
1750
1774
|
// 记忆读取是 best-effort(内部全 catch),不会把表单载入的错误顶掉。
|
|
1751
1775
|
fetchWorkflowMemory(workflowId, env),
|
|
1752
1776
|
]);
|
|
@@ -1832,7 +1856,7 @@ async function resolveIntentFill(pack, userQuestion, baseUrl, env) {
|
|
|
1832
1856
|
* 现在返回的就是纯取数结果:`fields` + `historyRequestData` + `systemFields` + 记忆,
|
|
1833
1857
|
* 由模型自己拼 `data` 后交给 `createRequest`。
|
|
1834
1858
|
*/
|
|
1835
|
-
async function prepareCreateFormPayload(args, env) {
|
|
1859
|
+
async function prepareCreateFormPayload(args, env, options = {}) {
|
|
1836
1860
|
// 会话是**惰性**加载的(`ensureSession` 只在首次调用时填充)。本命令随后会并发发起多个请求,
|
|
1837
1861
|
// 先在这里显式取一次,避免并发首调各自走一遍会话初始化。
|
|
1838
1862
|
//
|
|
@@ -1851,11 +1875,11 @@ async function prepareCreateFormPayload(args, env) {
|
|
|
1851
1875
|
// `commonParam.authInfo` 给出;该 ID 不可用时由载入表单一侧的 `readCreateFormBlock`
|
|
1852
1876
|
// 抛出**可判别**的澄清(不是把它伪装成"没有匹配到可发起的工作流")。
|
|
1853
1877
|
target = { id: explicitId, name: '', source: 'workflowId' };
|
|
1854
|
-
pack = await loadCreateFormPack(explicitId, env);
|
|
1878
|
+
pack = await loadCreateFormPack(explicitId, env, options);
|
|
1855
1879
|
}
|
|
1856
1880
|
else {
|
|
1857
1881
|
target = await resolveCreateWorkflow(args.workflow, env);
|
|
1858
|
-
pack = await loadCreateFormPack(target.id, env);
|
|
1882
|
+
pack = await loadCreateFormPack(target.id, env, options);
|
|
1859
1883
|
}
|
|
1860
1884
|
// ★ 2026-10-15 用户裁定:`createForm` 改用**字符口径 20,000** 的**严格档**(见
|
|
1861
1885
|
// `CREATE_FORM_STDOUT_SAFE_CHARS` / `compactFormOutput` 的 `charBudget`)。
|
|
@@ -1947,7 +1971,21 @@ async function commandCreateForm(args, env) {
|
|
|
1947
1971
|
* 与旧版的差别只有一处:`workflowId` 由调用方(`resolveCreateWorkflow`)解析好后传进来,
|
|
1948
1972
|
* 不再是本函数的入参校验点。
|
|
1949
1973
|
*/
|
|
1950
|
-
async function buildCreateFormData(workflowId, env) {
|
|
1974
|
+
async function buildCreateFormData(workflowId, env, options = {}) {
|
|
1975
|
+
/**
|
|
1976
|
+
* 明细字段的标记形态(2026-10-30 用户裁定):
|
|
1977
|
+
* - 缺省 `subFormId` —— `createForm` 口径,明细字段带 `subFormId`(`data.details` 的键);
|
|
1978
|
+
* - `isDetail` —— `createRequestDirect` 独有的口径,明细字段带 `isDetail: true`、不再下发 `subFormId`。
|
|
1979
|
+
*/
|
|
1980
|
+
const detailMark = options.detailMark === 'isDetail' ? 'isDetail' : 'subFormId';
|
|
1981
|
+
/**
|
|
1982
|
+
* ★ 2026-10-30 用户裁定:`getHistory` 是 `createRequestDirect` 的**隐藏入参**(只在 CLI 实现层支持,
|
|
1983
|
+
* 不进 `inputSchema`、不进 skill)。传 `false` 时「历史发起流程」这一段整块不做 ——
|
|
1984
|
+
* 不发 `getMineListData`(列表)、不发明细,也不要组装;输出里 `historyRequestData` 直接给 `null`。
|
|
1985
|
+
*
|
|
1986
|
+
* 缺省(含 `createForm` 这一侧,它从不传)一律按 `true`,行为与从前一字不差。
|
|
1987
|
+
*/
|
|
1988
|
+
const getHistory = options.getHistory !== false;
|
|
1951
1989
|
const query = { workflowId, isCreate: 1, ...AJAX_QUERY };
|
|
1952
1990
|
const body = { workflowId, isCreate: 1, isMobile: 0 };
|
|
1953
1991
|
/**
|
|
@@ -1958,7 +1996,23 @@ async function buildCreateFormData(workflowId, env) {
|
|
|
1958
1996
|
* `.catch(() => null)` 是必须的:这个 Promise 可能因为表单后续抛错而**没人 await**,
|
|
1959
1997
|
* 兜住之后就不会留下未处理的拒绝;真要暴露的认证/网络错误由同批的载入请求抛出,不会被吞掉。
|
|
1960
1998
|
*/
|
|
1961
|
-
const historyListSnapshot =
|
|
1999
|
+
const historyListSnapshot = getHistory
|
|
2000
|
+
? fetchHistoryListSnapshot(env, { workflowId }).catch(() => null)
|
|
2001
|
+
: Promise.resolve(null);
|
|
2002
|
+
/**
|
|
2003
|
+
* 明细请求紧跟着**列表**走(2026-10-29 用户口径):它的入参只有 `requestId`(列表给的)与会话
|
|
2004
|
+
* `userId`,与 `getFormLayout` **没有任何参数依赖**;原先排在 layout 之后纯属写法问题,白等约
|
|
2005
|
+
* 100 ms。现在列表一返回就发出去,与 layout 并行;**取值后怎么组装一个字没改**(仍在 layout 之后
|
|
2006
|
+
* 用本表单字段清单做,见下方 `buildHistoryRequestData`)。
|
|
2007
|
+
*
|
|
2008
|
+
* `.catch(() => {})`:表单后续可能先抛错(layout 失败等),这条链就没人 `await` 了 —— 先挂一个
|
|
2009
|
+
* 空处理免得留下未处理的拒绝。真正的认证/网络错误仍由 `buildHistoryRequestData` 里那次 `await`
|
|
2010
|
+
* 决定去留(口径不变)。
|
|
2011
|
+
*/
|
|
2012
|
+
const historyDetails = getHistory
|
|
2013
|
+
? historyListSnapshot.then(async (snapshot) => (snapshot && snapshot.requestIds.length ? prefetchHistoryDetails(env, snapshot) : null))
|
|
2014
|
+
: Promise.resolve(null);
|
|
2015
|
+
historyDetails.catch(() => { });
|
|
1962
2016
|
// 2026-09-22:这四个接口**彼此没有数据依赖**(入参只需要 workflowId,见各自的 query/body),
|
|
1963
2017
|
// 真机实测各 171–429 ms、串行合计约 1.1 s;并行后只受最慢的一个约束。
|
|
1964
2018
|
// `loadMinorInfo` / `tenant/setting` 仍是 best-effort(失败只降级、不阻断),所以各自 catch 成
|
|
@@ -2235,12 +2289,20 @@ async function buildCreateFormData(workflowId, env) {
|
|
|
2235
2289
|
// 不在当前布局上的字段不下发——模型既填不了也看不到。
|
|
2236
2290
|
if (!modelFieldIds.has(String(field.id ?? '')))
|
|
2237
2291
|
continue;
|
|
2238
|
-
//
|
|
2239
|
-
//
|
|
2292
|
+
// 明细标记**按命令分档**(2026-10-30 用户裁定:改成 isDetail 只对 `createRequestDirect` 生效):
|
|
2293
|
+
// - `createRequestDirect`:键序 `id|name|isDetail|componentKey`,明细字段带 `isDetail: true`,
|
|
2294
|
+
// 主表字段**整个省略**该键(缺键=主表;恒写 `isDetail:false` 白占体积),且**不下发** `subFormId`;
|
|
2295
|
+
// - `createForm`(默认档):维持原口径,明细字段带 `subFormId`(它就是 `data.details` 的键),
|
|
2296
|
+
// 主表字段省略该键。
|
|
2240
2297
|
const slimSubFormId = String(field.subFormId ?? '');
|
|
2241
2298
|
const item = { id: field.id, name: field.name };
|
|
2242
|
-
if (
|
|
2299
|
+
if (detailMark === 'isDetail') {
|
|
2300
|
+
if (slimSubFormId)
|
|
2301
|
+
item.isDetail = true;
|
|
2302
|
+
}
|
|
2303
|
+
else if (slimSubFormId) {
|
|
2243
2304
|
item.subFormId = slimSubFormId;
|
|
2305
|
+
}
|
|
2244
2306
|
item.componentKey = field.componentKey;
|
|
2245
2307
|
// 表单初始化时就有的值(OA 预填 + onLoadForm 联动带出)——有才出现该键;**没有默认值的字段不带**。
|
|
2246
2308
|
// CLI 拼 `data` 时会自动并入,模型**不必显式传**;用户本次明确改写了它才按用户说的覆盖(见
|
|
@@ -2316,10 +2378,12 @@ async function buildCreateFormData(workflowId, env) {
|
|
|
2316
2378
|
...requiredFieldsList.map((f) => String(f?.id ?? '')),
|
|
2317
2379
|
...Object.values(subFormRequired).flatMap((list) => list.map((f) => String(f?.id ?? ''))),
|
|
2318
2380
|
].filter(Boolean))];
|
|
2319
|
-
const historyCache = fields.length
|
|
2381
|
+
const historyCache = getHistory && fields.length
|
|
2320
2382
|
? await buildHistoryRequestData(env, fields, historyRequiredFieldIds.map((id) => ({ id, name: String((fieldsById.get(id) || {}).name ?? id) })), { allFormFields: true, workflowId },
|
|
2321
2383
|
// 本命令开头就已并发发起的列表请求:这里只补「详情」那几步(P2)。
|
|
2322
|
-
historyListSnapshot
|
|
2384
|
+
historyListSnapshot,
|
|
2385
|
+
// 明细也已在列表返回时就发出去(与 layout 并行),这里只等它回来、按本表单字段组装。
|
|
2386
|
+
historyDetails)
|
|
2323
2387
|
: null;
|
|
2324
2388
|
const session = await getSessionContext(env);
|
|
2325
2389
|
const context = {
|
|
@@ -2386,7 +2450,9 @@ async function buildCreateFormData(workflowId, env) {
|
|
|
2386
2450
|
// 历史参考值(近一年、非草稿、最近 5 条「我发起的」)——填值前先看它,能直接照用的字段就别去
|
|
2387
2451
|
// 问用户。字段范围与 `fields` **同一口径**(见 modelFieldIds 注释);完整结果(本表单全部字段)
|
|
2388
2452
|
// 仍随句柄留给 `createRequest` 用(条件必填要到那边才现身)。
|
|
2389
|
-
|
|
2453
|
+
// `getHistory:false`(隐藏入参)时整段历史取数没做 ⇒ 这里给 `null`(不是空数组:空数组表示
|
|
2454
|
+
// "查了但没数据",两者含义不同)。
|
|
2455
|
+
historyRequestData: getHistory ? filterHistoryRequestData(historyCache, modelFieldIds) : null,
|
|
2390
2456
|
systemFields: {
|
|
2391
2457
|
permissions: minorInfo.permissions || {},
|
|
2392
2458
|
defaults: context.systemFields.defaults,
|
|
@@ -3800,9 +3866,11 @@ async function runFieldLinkage(env, ctx, entries, actionTypes, allDetails, isEdi
|
|
|
3800
3866
|
}
|
|
3801
3867
|
if (!dataList.length && !runDataList.length)
|
|
3802
3868
|
return [];
|
|
3869
|
+
// 建模表单的联动接口 `module` 是 `ebuilderform`(与布局 / 保存的 `ebuildercard` 不同,真机请求体实证)。
|
|
3870
|
+
const linkageModule = formModuleName(ctx.frame && ctx.frame.relate_type, 'ebuilderform');
|
|
3803
3871
|
const executeParam = {
|
|
3804
3872
|
formId: ctx.layout.form_id,
|
|
3805
|
-
module:
|
|
3873
|
+
module: linkageModule,
|
|
3806
3874
|
dataList,
|
|
3807
3875
|
runDataList,
|
|
3808
3876
|
moduleDataList: [],
|
|
@@ -3846,9 +3914,10 @@ async function runFieldLinkage(env, ctx, entries, actionTypes, allDetails, isEdi
|
|
|
3846
3914
|
if (frame.layout_multi_id)
|
|
3847
3915
|
executeParam.layoutId = frame.layout_multi_id;
|
|
3848
3916
|
}
|
|
3849
|
-
const payload = { formId: ctx.layout.form_id, module:
|
|
3917
|
+
const payload = { formId: ctx.layout.form_id, module: linkageModule, executeParam };
|
|
3850
3918
|
const relateType = (ctx.frame && ctx.frame.relate_type) || '';
|
|
3851
|
-
|
|
3919
|
+
// 建模表单的联动接口在 `/api/ebuilder/form/` 下,与布局 / 保存的 `/api/ebuilder/flow/` 不同(真机实证)。
|
|
3920
|
+
const endpoint = formApiUrl(FORM_ENDPOINTS.fdLinkage, relateType, '/api/ebuilder/form/');
|
|
3852
3921
|
const response = await requestJson(env, 'POST', endpoint, AJAX_QUERY, payload);
|
|
3853
3922
|
// requestJson 内部已解包一层(responseData),此处不可再取 .data
|
|
3854
3923
|
const data = (response && typeof response === 'object') ? response : null;
|
|
@@ -4625,6 +4694,8 @@ function linkageResultNotice(linkageDetails, fields, hiddenSubforms, rowHidden,
|
|
|
4625
4694
|
* 的就是与普通链路同一段代码),它们不是必填判定。
|
|
4626
4695
|
* - 句柄**不消费**:本分支在任何写请求之前返回,同一个 `context` 之后仍可正常重发。
|
|
4627
4696
|
* - `title` 取**工作流名称**;`src` 与两处 `routerProps_*` 的 `initialEntries` 用**工作流 id**;
|
|
4697
|
+
* `src` 末尾另按 `&<字段id>=<值>` 拼上本次要填的字段(2026-10-30 用户裁定,与下面
|
|
4698
|
+
* `params.customParams` 同一份数据);
|
|
4628
4699
|
* `params.customParams` 取 `createRequest` **入参**经解析后的字段值(不含表单默认值、不含联动带出的值),
|
|
4629
4700
|
* 同段 `fieldAssignKeys` 列出这次要填的**全部字段 id**(`,` 连接)。
|
|
4630
4701
|
*/
|
|
@@ -4777,10 +4848,31 @@ function xiaoECustomParams(preview) {
|
|
|
4777
4848
|
}
|
|
4778
4849
|
return { values, keys: ordered };
|
|
4779
4850
|
}
|
|
4851
|
+
/**
|
|
4852
|
+
* `src` 末尾的字段参数(2026-10-30 用户裁定):`&<字段id>=<值>`,与 `params.customParams` 里那份
|
|
4853
|
+
* 字段值**同一份数据、同一顺序**(`fieldAssignKeys` 是元信息,不进 URL)。
|
|
4854
|
+
*
|
|
4855
|
+
* 值**原样拼、不做任何百分号编码**:客户端自己解析这段 query(按 `&` 切键值对、再按 `=` 切第一个
|
|
4856
|
+
* 等号),中文、空格、`,` / `;` / `#` 等都不需要转义,拼出来的字面值必须与 `params.customParams`
|
|
4857
|
+
* 里逐字相同。唯一代价是值本身含 `&` 时会截断——按用户口径以此为准,不在此处兜底改写。
|
|
4858
|
+
*/
|
|
4859
|
+
function xiaoESrcFieldQuery(params) {
|
|
4860
|
+
let query = '';
|
|
4861
|
+
for (const fieldId of params.keys) {
|
|
4862
|
+
const text = params.values[fieldId];
|
|
4863
|
+
if (!text)
|
|
4864
|
+
continue;
|
|
4865
|
+
query += `&${fieldId}=${text}`;
|
|
4866
|
+
}
|
|
4867
|
+
return query;
|
|
4868
|
+
}
|
|
4780
4869
|
/**
|
|
4781
4870
|
* 渲染 `<browsertool>` 块(该块**整体**就是小e 环境下 `createRequest` 的 `finalMarkdown`)。
|
|
4782
4871
|
*
|
|
4783
4872
|
* 除 `title` / `src` / 两处 `routerProps_*` 的 `initialEntries` / `params.customParams` 外全部写死。
|
|
4873
|
+
*
|
|
4874
|
+
* `src` 形如 `…/flowpage/create/<workflowId>?workflowId=<workflowId>&isCreate=1&<字段id>=<值>&…`
|
|
4875
|
+
* —— 末尾的字段参数与 `params.customParams` 同源(2026-10-30 用户裁定)。
|
|
4784
4876
|
*/
|
|
4785
4877
|
function renderXiaoEFillFormMarkdown(params) {
|
|
4786
4878
|
const base = String(params.baseUrl ?? '').replace(/\/+$/u, '');
|
|
@@ -4793,7 +4885,7 @@ function renderXiaoEFillFormMarkdown(params) {
|
|
|
4793
4885
|
arguments: {
|
|
4794
4886
|
type: 'e10',
|
|
4795
4887
|
title: String(params.title ?? ''),
|
|
4796
|
-
src: `${base}/sp/workflow${createPath}?workflowId=${workflowId}&isCreate=1`,
|
|
4888
|
+
src: `${base}/sp/workflow${createPath}?workflowId=${workflowId}&isCreate=1${xiaoESrcFieldQuery(params.customParams)}`,
|
|
4797
4889
|
sdkOptions: {
|
|
4798
4890
|
compName: XIAOE_FILL_FORM_SDK_OPTIONS.compName,
|
|
4799
4891
|
routerType: XIAOE_FILL_FORM_SDK_OPTIONS.routerType,
|
|
@@ -4819,7 +4911,8 @@ function renderXiaoEFillFormMarkdown(params) {
|
|
|
4819
4911
|
* - `durationMs` = 命令入口 → 结果产出;
|
|
4820
4912
|
* - `apiDurations` = 每个接口(并行批次合成一个 key,取墙钟、不叠加);
|
|
4821
4913
|
* - `apiSlowest` = 每个**真并行**批里谁最慢(`[{ batch, name, ms, items }]`,`ms` 是该接口自身耗时,
|
|
4822
|
-
* `items` 是批内每个成员的 `{ name, at, ms }`,按 `ms`
|
|
4914
|
+
* `items` 是批内每个成员的 `{ name, at, ms, fetchAt, fetchEnd, fetchCost }`,按 `ms` 降序;
|
|
4915
|
+
* `fetchAt`/`fetchEnd`/`fetchCost` 描述其中纯 fetch 那一段);
|
|
4823
4916
|
* - `authMs` = 登录取凭据(首次会话解析)的墙钟 —— 这一段走 auth 层自己的 fetch、不经
|
|
4824
4917
|
* `host.workflowRequest`,`apiDurations` 统计不到,单独给一个数才能对上账。
|
|
4825
4918
|
*
|
|
@@ -5448,15 +5541,27 @@ function apiShortName(path) {
|
|
|
5448
5541
|
* 给 host 套一层**逐接口计时**(只包请求,不改返回、不吞异常)。
|
|
5449
5542
|
*
|
|
5450
5543
|
* `finally` 里落片段:请求失败(超时 / 业务错误 / 抛错)同样要记 —— 恰恰是这类请求最需要看到耗时。
|
|
5544
|
+
*
|
|
5545
|
+
* 片段里除整段耗时外,还记**纯 fetch** 那一段(`fetchMs`,2026-10-30 用户要求):它由
|
|
5546
|
+
* `runWithFetchTiming` 开一个旁路 sink、`E10RequestRuntime` 在 fetch 前后各打一枪得到,
|
|
5547
|
+
* 两条链路都只读不改请求/返回值。
|
|
5451
5548
|
*/
|
|
5452
5549
|
function withApiTiming(host, spans) {
|
|
5453
5550
|
const record = async (path, run) => {
|
|
5454
5551
|
const start = Date.now();
|
|
5552
|
+
const fetchTiming = createFetchTimingSink();
|
|
5455
5553
|
try {
|
|
5456
|
-
return await run
|
|
5554
|
+
return await runWithFetchTiming(fetchTiming, run);
|
|
5457
5555
|
}
|
|
5458
5556
|
finally {
|
|
5459
|
-
spans.push({
|
|
5557
|
+
spans.push({
|
|
5558
|
+
name: apiShortName(path),
|
|
5559
|
+
start,
|
|
5560
|
+
end: Date.now(),
|
|
5561
|
+
fetchStart: fetchTiming.fetchStart,
|
|
5562
|
+
fetchEnd: fetchTiming.fetchEnd,
|
|
5563
|
+
fetchMs: fetchTiming.fetchMs,
|
|
5564
|
+
});
|
|
5460
5565
|
}
|
|
5461
5566
|
};
|
|
5462
5567
|
return {
|
|
@@ -5485,7 +5590,9 @@ function withApiTiming(host, spans) {
|
|
|
5485
5590
|
* - 批内**全是同一个接口**时也不产(如 5 个并发的 `getWorkflowRequest` 取历史详情):请求都一样,
|
|
5486
5591
|
* "谁最慢"没有区分意义,只有批的墙钟有用(2026-10-22 用户第二轮裁定);
|
|
5487
5592
|
* - `ms` 取该接口**自身**耗时(`end - start`),不是批墙钟;
|
|
5488
|
-
* - 每条另带 `items`:批内**每个**成员的 `{name, at, ms}`(`at`
|
|
5593
|
+
* - 每条另带 `items`:批内**每个**成员的 `{name, at, ms, fetchAt, fetchEnd, fetchCost}`(`at` 相对批
|
|
5594
|
+
* 起点;`ms` 自身耗时;`fetchAt`/`fetchEnd` 是其中**纯 fetch**(发出请求 → 收到响应头)的起止偏移、
|
|
5595
|
+
* `fetchCost` 是它的耗时,2026-10-30 用户要求),按 `ms` 降序。
|
|
5489
5596
|
* 2026-10-26 用户要求:只看最慢项判断不出「优化它值不值」——若批内多个接口耗时接近,
|
|
5490
5597
|
* 砍掉最慢那个的收益有限,得看整条关键路径的分布;
|
|
5491
5598
|
* - 顺序=批的时间顺序,与 `apiDurations` 的 key 一一对应。
|
|
@@ -5520,13 +5627,17 @@ function summarizeApiSpans(spans) {
|
|
|
5520
5627
|
// 批内全是同一个接口 ⇒ 不产最慢项("5 个 getWorkflowRequest 里谁最慢"没有区分意义)。
|
|
5521
5628
|
if (group.length > 1 && new Set(names).size > 1) {
|
|
5522
5629
|
const origin = Math.min(...group.map((item) => item.start));
|
|
5523
|
-
// 批内逐个成员都留一条(`at` 相对批起点,`ms`
|
|
5524
|
-
//
|
|
5630
|
+
// 批内逐个成员都留一条(`at` 相对批起点,`ms` 自身耗时;`fetchAt`/`fetchEnd` 是其中纯 fetch
|
|
5631
|
+
// 的起止偏移、`fetchCost` 是它自身的耗时),按耗时降序;并列取先开始的(`at` 升序),
|
|
5632
|
+
// 保证同一份输入每次输出一致。`name`/`ms` 就取这一项。
|
|
5525
5633
|
const items = group
|
|
5526
5634
|
.map((item) => ({
|
|
5527
5635
|
name: item.name,
|
|
5528
5636
|
at: Math.max(0, Math.round(item.start - origin)),
|
|
5529
5637
|
ms: Math.max(0, Math.round(item.end - item.start)),
|
|
5638
|
+
fetchAt: item.fetchStart === null ? null : Math.max(0, Math.round(item.fetchStart - origin)),
|
|
5639
|
+
fetchEnd: item.fetchEnd === null ? null : Math.max(0, Math.round(item.fetchEnd - origin)),
|
|
5640
|
+
fetchCost: Math.max(0, Math.round(item.fetchMs)),
|
|
5530
5641
|
}))
|
|
5531
5642
|
.sort((a, b) => (b.ms - a.ms) || (a.at - b.at));
|
|
5532
5643
|
slowest.push({ batch: key, name: items[0].name, ms: items[0].ms, items });
|
|
@@ -5534,6 +5645,26 @@ function summarizeApiSpans(spans) {
|
|
|
5534
5645
|
}
|
|
5535
5646
|
return { durations, slowest };
|
|
5536
5647
|
}
|
|
5648
|
+
/**
|
|
5649
|
+
* `createRequestDirect` 的**隐藏入参** `getHistory` 取值(2026-10-30 用户裁定)。
|
|
5650
|
+
*
|
|
5651
|
+
* 只在 CLI 实现层支持:**不写进** `inputSchema`、不写进 skill 文档,模型侧看不到、也没法从
|
|
5652
|
+
* `workflow schema` 里读到;需要时由调用方(桌面端 / 脚本)自己塞进 `--input-json`。
|
|
5653
|
+
*
|
|
5654
|
+
* 口径:缺省、`null`、`undefined`、空串、其它非 `false` 的真值 ⇒ `true`(与从前的行为完全一致);
|
|
5655
|
+
* 只有明确表达"不要"的写法才关掉:`false` / `0` / `"false"` / `"0"`(大小写、首尾空格都不敏感)。
|
|
5656
|
+
* 宽松接受字符串是为了调用方从环境变量或配置里透传时不必先转类型。
|
|
5657
|
+
*/
|
|
5658
|
+
function readHiddenGetHistory(value) {
|
|
5659
|
+
if (value === false || value === 0)
|
|
5660
|
+
return false;
|
|
5661
|
+
if (typeof value === 'string') {
|
|
5662
|
+
const text = value.trim().toLowerCase();
|
|
5663
|
+
if (text === 'false' || text === '0')
|
|
5664
|
+
return false;
|
|
5665
|
+
}
|
|
5666
|
+
return true;
|
|
5667
|
+
}
|
|
5537
5668
|
/**
|
|
5538
5669
|
* `workflow.createRequestDirect` —— **取数命令**(2026-10-22 用户裁定,语义已变)。
|
|
5539
5670
|
*
|
|
@@ -5555,6 +5686,10 @@ function summarizeApiSpans(spans) {
|
|
|
5555
5686
|
* 5. **输出降级**(按 20,000 **字符**,与 `createForm` 同一个宿主口径):
|
|
5556
5687
|
* 全量超线 ⇒ `historyRequestData` 留空数组(键还在);仍超 ⇒ `userMemory` 留空串(键还在;小e 档没有
|
|
5557
5688
|
* 这个键,不补);**`fields` 自己也超线时不再裁**(宁大不丢)—— 它是唯一不可省的,砍了这条命令就没有意义。
|
|
5689
|
+
* 6. **隐藏入参 `getHistory`**(2026-10-30 用户裁定):只在实现层支持,**不进 schema、不进 skill**。
|
|
5690
|
+
* 不传 = `true`(原行为);传 `false` 时整段「历史发起流程」取数(`getMineListData` 列表 + 明细)
|
|
5691
|
+
* 一次都不发,输出里 `historyRequestData` 直接是 `null`(不是空数组——空数组的意思是"查了但没数据")。
|
|
5692
|
+
* 这一档也不参与上面的输出降级。
|
|
5558
5693
|
*
|
|
5559
5694
|
* ## 耗时
|
|
5560
5695
|
* 与 `createForm` 完全同口径,全部收在 `timing` 一个桶里:`durationMs`(整条命令)/
|
|
@@ -5567,9 +5702,15 @@ async function commandCreateRequestDirect(args, env) {
|
|
|
5567
5702
|
// 计时从**命令入口**开始算(含会话解析、工作流消歧、表单载入)。
|
|
5568
5703
|
const spans = [];
|
|
5569
5704
|
const timedEnv = { ...env, host: withApiTiming(env.host, spans) };
|
|
5705
|
+
// 隐藏入参(不进 schema / skill):`false` 时不跑「历史发起流程」那段取数。
|
|
5706
|
+
const getHistory = readHiddenGetHistory(args.getHistory);
|
|
5570
5707
|
// 取数段本身已经不碰 `chatScene`(`createForm` 自 2026-10-23 起不再接 `userQuestion`),
|
|
5571
|
-
//
|
|
5572
|
-
|
|
5708
|
+
// 这里不必再置空任何入参。`detailMark` 也是**本命令独有**:明细字段标 `isDetail: true`、
|
|
5709
|
+
// 不再下发 `subFormId`(`createForm` 仍走老口径,见 `buildCreateFormData`)。
|
|
5710
|
+
const { payload, authMs } = await prepareCreateFormPayload(args, timedEnv, {
|
|
5711
|
+
getHistory,
|
|
5712
|
+
detailMark: 'isDetail',
|
|
5713
|
+
});
|
|
5573
5714
|
const contextId = String(payload.contextId ?? '');
|
|
5574
5715
|
if (!contextId) {
|
|
5575
5716
|
// `prepareCreateFormPayload` 正常返回时 contextId 必然存在;这里只用来判断
|
|
@@ -5604,8 +5745,10 @@ async function commandCreateRequestDirect(args, env) {
|
|
|
5604
5745
|
const overLine = () => finalStdoutChars({ ...data, ...reserve }, 'workflow.createRequestDirect') > CREATE_FORM_STDOUT_SAFE_CHARS;
|
|
5605
5746
|
// 两级降级:先砍历史(留空 key)→ 再砍记忆(留空 key)。`fields` 不参与裁剪。
|
|
5606
5747
|
// 小e 档没有 `userMemory` 这个键,第二级跳过(不能借"写空串"把它重新加回来)。
|
|
5748
|
+
// `getHistory:false` 时历史那一档本来就没查(值是 `null`)⇒ 不参与降级,否则会把"没查"说成"查了没数据"。
|
|
5607
5749
|
if (overLine()) {
|
|
5608
|
-
|
|
5750
|
+
if (getHistory)
|
|
5751
|
+
data.historyRequestData = [];
|
|
5609
5752
|
if ('userMemory' in data && overLine())
|
|
5610
5753
|
data.userMemory = '';
|
|
5611
5754
|
}
|
|
@@ -5628,10 +5771,30 @@ function formatRemark(value) {
|
|
|
5628
5771
|
return text;
|
|
5629
5772
|
return `_weaverMte_<p>${text.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>')}</p>`;
|
|
5630
5773
|
}
|
|
5774
|
+
/**
|
|
5775
|
+
* 表单所属模块名:建模表单(`relateType=WEA_EBUILDER`)按接口取自己的 service 名,其余是 `workflow`。
|
|
5776
|
+
*
|
|
5777
|
+
* 服务端按请求体里的 `module` 解析 `@Service("<module>_FormCoreService")`:建模表单传 `workflow`
|
|
5778
|
+
* 会直接 500「未找到名为 FormCoreService 的实例对象」(2026-10-29 e-cology 建模流程实测:只把该值
|
|
5779
|
+
* 改成 `ebuildercard` 即 200)。所以凡是请求体带 `module` 的表单接口(布局 / 附件 / 保存 / 联动)
|
|
5780
|
+
* 都必须按表单类型取值,不能硬编码。
|
|
5781
|
+
*
|
|
5782
|
+
* ⚠️ 建模表单内部**不是同一个值**,必须按接口分别给(均为真机请求体实证):
|
|
5783
|
+
* - `getFormLayout` / `saveFormData` / 附件上传 → `ebuildercard`
|
|
5784
|
+
* - `executeFdLinkage` / `getFormDataAndLayout` → `ebuilderform`
|
|
5785
|
+
*
|
|
5786
|
+
* 注意这两个值**不按目录/同族划分**:`getFormDataAndLayout` 与 `getFormLayout` 同在 `form/core` 下,
|
|
5787
|
+
* 前者是 `ebuilderform`、后者是 `ebuildercard`。所以只能按接口真机样例取值,不能靠推断。
|
|
5788
|
+
*/
|
|
5789
|
+
function formModuleName(relateType, ebModule = 'ebuildercard') {
|
|
5790
|
+
return String(relateType ?? '').trim() === 'WEA_EBUILDER' ? ebModule : 'workflow';
|
|
5791
|
+
}
|
|
5631
5792
|
function buildSaveBody(context, prepared) {
|
|
5632
5793
|
const runtime = context.runtime;
|
|
5794
|
+
// 顶层 `module` 与 `formData.module` 是同一条判据:建模表单的 saveFormData 也走 ebuilder 的服务。
|
|
5795
|
+
const moduleName = formModuleName(context.frame?.relate_type);
|
|
5633
5796
|
return {
|
|
5634
|
-
module:
|
|
5797
|
+
module: moduleName,
|
|
5635
5798
|
customParam: {
|
|
5636
5799
|
isCreate: true,
|
|
5637
5800
|
requestId: runtime.request_id,
|
|
@@ -5649,7 +5812,7 @@ function buildSaveBody(context, prepared) {
|
|
|
5649
5812
|
},
|
|
5650
5813
|
employeeId: runtime.employee_id,
|
|
5651
5814
|
formData: {
|
|
5652
|
-
module:
|
|
5815
|
+
module: moduleName,
|
|
5653
5816
|
presetDataId: runtime.request_id,
|
|
5654
5817
|
dataDetails: prepared.dataDetails,
|
|
5655
5818
|
client: 'pc',
|
|
@@ -6150,12 +6313,15 @@ async function runCreateNodeFieldVerification(env, context, switches) {
|
|
|
6150
6313
|
// ---------------------------------------------------------------------------
|
|
6151
6314
|
// editLoad / editPrepare / editSave
|
|
6152
6315
|
// ---------------------------------------------------------------------------
|
|
6153
|
-
function buildEditDataLayoutRequest(requestId, workflowId, nodeId, formId, dataId, layoutMultiId, viewFormNodeId, permissionType, runtime) {
|
|
6316
|
+
function buildEditDataLayoutRequest(requestId, workflowId, nodeId, formId, dataId, layoutMultiId, viewFormNodeId, permissionType, runtime, relateType) {
|
|
6154
6317
|
return {
|
|
6155
6318
|
terminalType: 'PC',
|
|
6156
6319
|
dataId,
|
|
6157
6320
|
formId,
|
|
6158
|
-
|
|
6321
|
+
// 建模表单取 `ebuilderform`(2026-10-30 真机请求体实证),**不是** `ebuildercard`:
|
|
6322
|
+
// 同为 `form/core` 下的接口,`getFormLayout` / `saveFormData` 是 `ebuildercard`,
|
|
6323
|
+
// 本接口与 `executeFdLinkage` 是 `ebuilderform` —— 建模表单内部不能按"同族"推定。
|
|
6324
|
+
module: formModuleName(relateType, 'ebuilderform'),
|
|
6159
6325
|
newLayout: true,
|
|
6160
6326
|
cacheUid: null,
|
|
6161
6327
|
layoutMultiId,
|
|
@@ -6229,7 +6395,7 @@ async function commandEditLoad(args, env) {
|
|
|
6229
6395
|
tenantSetting = {};
|
|
6230
6396
|
}
|
|
6231
6397
|
const dataId = requestId;
|
|
6232
|
-
const dlResp = await requestJson(env, 'POST', formApiUrl(FORM_ENDPOINTS.formDataAndLayout, frame.relate_type), { formId: frame.form_id, dataId, ...AJAX_QUERY }, buildEditDataLayoutRequest(requestId, workflowId, runtime.node_id, frame.form_id, dataId, frame.layout_multi_id, frame.view_form_node_id, frame.permission_type, runtime));
|
|
6398
|
+
const dlResp = await requestJson(env, 'POST', formApiUrl(FORM_ENDPOINTS.formDataAndLayout, frame.relate_type), { formId: frame.form_id, dataId, ...AJAX_QUERY }, buildEditDataLayoutRequest(requestId, workflowId, runtime.node_id, frame.form_id, dataId, frame.layout_multi_id, frame.view_form_node_id, frame.permission_type, runtime, frame.relate_type));
|
|
6233
6399
|
const dlData = dlResp;
|
|
6234
6400
|
if (!dlData || typeof dlData !== 'object')
|
|
6235
6401
|
throw workflowApiError('format_error', 'getFormDataAndLayout 未返回有效 data');
|
|
@@ -6537,8 +6703,10 @@ async function commandEditPrepare(args, env) {
|
|
|
6537
6703
|
}
|
|
6538
6704
|
function buildEditSaveBody(context, prepared) {
|
|
6539
6705
|
const runtime = context.runtime || {};
|
|
6706
|
+
// 同 `buildSaveBody`:改已有表单时也按表单类型取 module,建模表单要 `ebuildercard`。
|
|
6707
|
+
const moduleName = formModuleName(context.frame?.relate_type);
|
|
6540
6708
|
return {
|
|
6541
|
-
module:
|
|
6709
|
+
module: moduleName,
|
|
6542
6710
|
customParam: {
|
|
6543
6711
|
isCreate: false,
|
|
6544
6712
|
requestId: context.requestId ?? context.request_id,
|
|
@@ -6558,7 +6726,7 @@ function buildEditSaveBody(context, prepared) {
|
|
|
6558
6726
|
formData: {
|
|
6559
6727
|
id: context.data_id,
|
|
6560
6728
|
updateTimeStamp: context.update_time_stamp || '',
|
|
6561
|
-
module:
|
|
6729
|
+
module: moduleName,
|
|
6562
6730
|
dataDelRows: [],
|
|
6563
6731
|
dataDetails: prepared.dataDetails || [],
|
|
6564
6732
|
client: 'pc',
|