weaver-work-cli 0.1.38 → 0.1.39
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -2
- package/dist/chunks/{archive-PDV724YK.js → archive-ENZYBBME.js} +556 -66
- package/dist/chunks/{archive-oa-4XE4MNXQ.js → archive-oa-YWLEC5V4.js} +2 -2
- package/dist/chunks/{asset-PDL2QE2N.js → asset-OOV6DWPA.js} +2 -2
- package/dist/chunks/asset-idle-RE632MY5.js +670 -0
- package/dist/chunks/{attachment-content-MDDGOE5E.js → attachment-content-RWN2FCLL.js} +3 -3
- package/dist/chunks/{blog-UYR3EUXW.js → blog-PEPOJAL7.js} +2 -2
- package/dist/chunks/{caizhilian-LG2X5NMF.js → caizhilian-WYIQDVPJ.js} +2 -2
- package/dist/chunks/{calendar-FG4BAZHE.js → calendar-CIARBAOX.js} +2 -2
- package/dist/chunks/{chunk-6FTTSA45.js → chunk-36DIFZAH.js} +2 -2
- package/dist/chunks/{chunk-UJJD4QWF.js → chunk-BJGXMFGD.js} +2 -2
- package/dist/chunks/{chunk-ELYDWBZJ.js → chunk-CQHGNCK2.js} +1 -1
- package/dist/chunks/{chunk-XJY7G4DD.js → chunk-EINRJHQ3.js} +3 -3
- package/dist/chunks/{chunk-UZZBA6PV.js → chunk-EZGFHJFW.js} +28 -6
- package/dist/chunks/{chunk-NI6GIPIM.js → chunk-F2EQXUEE.js} +438 -387
- package/dist/chunks/{chunk-VRYHGG6O.js → chunk-GVPJZXJ2.js} +3 -3
- package/dist/chunks/{chunk-IZUDA353.js → chunk-HJYVHXUQ.js} +1 -1
- package/dist/chunks/{chunk-KKRL3REV.js → chunk-I2HB737U.js} +2 -2
- package/dist/chunks/{chunk-NR6RKXPA.js → chunk-K3RUEEOL.js} +4 -2
- package/dist/chunks/{chunk-6LTFIFLM.js → chunk-KTCB5R5H.js} +2 -2
- package/dist/chunks/{chunk-J7USS3ED.js → chunk-L4N7B7ZD.js} +4 -4
- package/dist/chunks/{chunk-CORFRD7Q.js → chunk-MUQUHKPG.js} +2 -2
- package/dist/chunks/{chunk-DMV2TOMH.js → chunk-NLK2RZKG.js} +46 -46
- package/dist/chunks/{chunk-JSMFPO43.js → chunk-P2DAISYW.js} +1 -1
- package/dist/chunks/{chunk-GGJFMNJM.js → chunk-T7JDJJ7H.js} +3 -3
- package/dist/chunks/{chunk-OJQUJZQF.js → chunk-XXJOSZTQ.js} +2 -0
- package/dist/chunks/{chunk-Z32KWY6G.js → chunk-YS5DPN4T.js} +1 -1
- package/dist/chunks/{chunk-EG6ZU444.js → chunk-ZUX3P6BQ.js} +10 -5
- package/dist/chunks/{chunk-FUWVHMVV.js → chunk-ZXRNHZTE.js} +2 -2
- package/dist/chunks/{conflict-BQZEQ4SP.js → conflict-DRMDOL56.js} +2 -2
- package/dist/chunks/{contract-XIRAFTEV.js → contract-73MERZWN.js} +2 -2
- package/dist/chunks/{cowork-BLG62BL2.js → cowork-HNGBPD7A.js} +2 -2
- package/dist/chunks/{ebuilder-form-NUKG5QW4.js → ebuilder-form-OY6DVNRK.js} +3 -3
- package/dist/chunks/{ehr-2STW5ILH.js → ehr-RAQNEQO7.js} +2 -2
- package/dist/chunks/{esb-UUDQUNKY.js → esb-6XV7C7YV.js} +4 -4
- package/dist/chunks/{fna-6RCY4NU5.js → fna-XTSRB7G7.js} +2 -2
- package/dist/chunks/{host-RHM3NPXV.js → host-3F5UM5GN.js} +3 -3
- package/dist/chunks/{host-EJZFROU3.js → host-A7J6GDUP.js} +3 -3
- package/dist/chunks/{host-FWDOSRH5.js → host-VGPVP7YF.js} +3 -3
- package/dist/chunks/{host-7RXEDMAH.js → host-YAQAPYNP.js} +3 -3
- package/dist/chunks/{host-UFF33TWJ.js → host-YMBXWFWX.js} +3 -3
- package/dist/chunks/{hrm-PKJ6ELSH.js → hrm-TLHKC545.js} +3 -3
- package/dist/chunks/{im-YJAXS7CO.js → im-YOUCFMUK.js} +3 -3
- package/dist/chunks/{invoice-HWVSXGX6.js → invoice-WNBS2B4C.js} +3 -3
- package/dist/chunks/{jiuchuanhui-L7VKILZB.js → jiuchuanhui-XABWS5RN.js} +2 -2
- package/dist/chunks/{lazy-dispatch-NMYEIHRH.js → lazy-dispatch-NLZ5UQQI.js} +5 -5
- package/dist/chunks/{mail-B42RRU7G.js → mail-LRYMBFNL.js} +2 -2
- package/dist/chunks/{meeting-CFYVBJSS.js → meeting-ESXL6MFI.js} +10 -10
- package/dist/chunks/{okr-GCLF6V7W.js → okr-EOV65SSF.js} +2 -2
- package/dist/chunks/{plan-ZVL7GBRI.js → plan-YFPVKW6Y.js} +2 -2
- package/dist/chunks/{project-4YWAAE2K.js → project-MDVZUYQW.js} +2 -2
- package/dist/chunks/{registry-EP4VTHZS.js → registry-QCLZEDAP.js} +8 -8
- package/dist/chunks/{registry-FRJ6H7BT.js → registry-VT5Y2HLA.js} +4 -4
- package/dist/chunks/{registry-SG2PGVCF.js → registry-YX4CSEMD.js} +3 -3
- package/dist/chunks/{room-recommend-R3JVUUAC.js → room-recommend-L3MWH4JW.js} +4 -4
- package/dist/chunks/{schedule-NIJBTYDO.js → schedule-UASAVDVD.js} +4 -4
- package/dist/chunks/{workflow-BB24DFBY.js → workflow-KDGIUCNW.js} +9 -6
- package/dist/core/output.js +16 -6
- package/dist/index.js +33 -28
- package/dist/internal/e10/auth/messages.js +1 -0
- package/dist/internal/e10/auth-recovery.js +13 -6
- package/dist/internal/e10/context.js +16 -3
- package/dist/internal/e10/request-runtime.js +3 -1
- package/dist/shortcuts/archive/host.js +2 -0
- package/dist/shortcuts/archive/manifest.js +1 -1
- package/dist/shortcuts/archive/operations/borrow-list.js +13 -1
- package/dist/shortcuts/archive/operations/flow-url.js +1 -1
- package/dist/shortcuts/archive/operations/prelib.js +472 -0
- package/dist/shortcuts/archive/operations/registry.js +2 -0
- package/dist/shortcuts/archive/operations/upload.js +1 -1
- package/dist/shortcuts/asset-idle/errors.js +44 -0
- package/dist/shortcuts/asset-idle/host.js +161 -0
- package/dist/shortcuts/asset-idle/index.js +114 -0
- package/dist/shortcuts/asset-idle/manifest.js +159 -0
- package/dist/shortcuts/asset-idle/operations/idle.js +47 -0
- package/dist/shortcuts/asset-idle/operations/registry.js +33 -0
- package/dist/shortcuts/asset-idle/operations/shared.js +142 -0
- package/dist/shortcuts/asset-idle/operations/types.js +9 -0
- package/dist/shortcuts/asset-idle/operations.js +15 -0
- package/dist/shortcuts/index.js +5 -0
- package/dist/shortcuts/workflow/host.js +3 -0
- package/dist/shortcuts/workflow/index.js +1 -1
- package/dist/shortcuts/workflow/operations/form.js +46 -171
- package/dist/shortcuts/workflow/operations/todoSmartConvert/aigroupRules.js +77 -26
- package/dist/shortcuts/workflow/operations/todoSmartConvert/aigroupStore.js +6 -0
- package/dist/shortcuts/workflow/operations/todoSmartConvert/summaryCache.js +59 -117
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoDetailCache.js +44 -7
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoDetailFetcher.js +37 -29
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.collect.js +20 -6
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.detail.js +22 -18
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.groupSummary.js +34 -10
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.js +4 -2
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.smartGroup.js +9 -2
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.summary.js +110 -20
- package/docs/_catalog.md +3 -0
- package/docs/asset-idle.md +45 -0
- package/docs/e10-auth.md +1 -1
- package/docs/todo-smart-convert/subgroup-rules.md +1 -1
- package/package.json +1 -1
- package/scripts/package-skill.mjs +2 -0
- package/skill-template/business-info.json +14 -1
- package/skill-template/domains/asset-idle.md +13 -0
- package/skill-template/domains/wenshuding.md +3 -0
- package/skills/weaver-e10-archive-oa/SKILL.md +1 -0
- package/skills/weaver-e10-archive-oa/references/my-borrow.md +49 -0
- package/skills/weaver-e10-asset-idle/SKILL.md +73 -0
- package/skills/weaver-e10-asset-idle/references/idle-list.md +62 -0
- package/skills/weaver-e10-asset-idle/references/idle-stats-and-charts.md +65 -0
- package/skills/weaver-e10-asset-idle/references/source-manifest.json +193 -0
- package/skills/weaver-e10-asset-idle/references/widget-style.md +205 -0
- package/skills/weaver-e10-caizhilian/SKILL.md +29 -11
- package/skills/weaver-e10-caizhilian/references/auth-and-install.md +12 -0
- package/skills/weaver-e10-caizhilian/references/files.md +1 -1
- package/skills/weaver-e10-caizhilian/references/setting-encrypt.md +1 -1
- package/skills/weaver-e10-caizhilian/references/source-manifest.json +45 -45
- package/skills/weaver-e10-cowork/SKILL.md +2 -0
- package/skills/weaver-e10-jucailin/SKILL.md +2 -0
- package/skills/weaver-e10-jucailin/references/recruit-read.md +2 -0
- package/skills/weaver-e10-jucailin/references/recruit-write.md +1 -1
- package/skills/weaver-e10-mail/SKILL.md +3 -0
- package/skills/weaver-e10-shared/SKILL.md +5 -5
- package/skills/weaver-e10-shared/references/e10-auth-and-session.md +3 -3
- package/skills/weaver-e10-wenshuding/SKILL.md +29 -6
- package/skills/weaver-e10-wenshuding/references/archive-borrow-list.md +14 -0
- package/skills/weaver-e10-wenshuding/references/archive-download.md +2 -0
- package/skills/weaver-e10-wenshuding/references/archive-flow.md +1 -1
- package/skills/weaver-e10-wenshuding/references/archive-prelib-arrange.md +76 -0
- package/skills/weaver-e10-wenshuding/references/archive-prelib-list.md +107 -0
- package/skills/weaver-e10-wenshuding/references/archive-prelib-open.md +59 -0
- package/skills/weaver-e10-wenshuding/references/archive-upload.md +4 -1
- package/skills/weaver-e10-wenshuding/references/source-manifest.json +108 -65
- package/skills/weaver-e10-workflow/SKILL.md +5 -2
- package/skills/weaver-e10-workflow/aigroup/default.json +154 -19
- package/skills/weaver-e10-workflow/references/todo-smart-convert.md +59 -27
- package/skills/weaver-e10-workflow/tools/todo-serve.cjs +113 -25
- package/skills/weaver-e10-workflow/tools/todo-summary.cjs +292 -42
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
} from "./chunk-FMPJJYYI.js";
|
|
16
16
|
import {
|
|
17
17
|
stringifyForStdout
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-ZUX3P6BQ.js";
|
|
19
19
|
import {
|
|
20
20
|
stateRoot
|
|
21
21
|
} from "./chunk-AJ62BGAW.js";
|
|
@@ -24,7 +24,7 @@ import {
|
|
|
24
24
|
createFetchTimingSink,
|
|
25
25
|
hasXiaoEEnv,
|
|
26
26
|
runWithFetchTiming
|
|
27
|
-
} from "./chunk-
|
|
27
|
+
} from "./chunk-XXJOSZTQ.js";
|
|
28
28
|
|
|
29
29
|
// src/shortcuts/workflow/operations/form.ts
|
|
30
30
|
import { randomUUID } from "node:crypto";
|
|
@@ -5079,17 +5079,47 @@ async function runWorkflowSearch(args, env) {
|
|
|
5079
5079
|
var TEXTAREA_COMPONENTS = /* @__PURE__ */ new Set(["textarea", "richtext", "editor", "html", "htmltext"]);
|
|
5080
5080
|
var SELECT_COMPONENTS = /* @__PURE__ */ new Set(["select", "selectmultiple", "radiobox", "checkbox", "radio", "multiselect"]);
|
|
5081
5081
|
var BROWSER_COMPONENTS = /* @__PURE__ */ new Set([
|
|
5082
|
+
// 人员 / 组织类
|
|
5082
5083
|
"employee",
|
|
5083
5084
|
"department",
|
|
5084
5085
|
"subcompany",
|
|
5085
5086
|
"jobtitle",
|
|
5086
5087
|
"job",
|
|
5087
|
-
"
|
|
5088
|
-
"
|
|
5089
|
-
"
|
|
5088
|
+
"employeeorganization",
|
|
5089
|
+
"employeeshare",
|
|
5090
|
+
"employeeauthshare",
|
|
5091
|
+
"odocreceivecomponent",
|
|
5092
|
+
// 关联类型(设计器「表单组件 / 关联类型」面板)
|
|
5090
5093
|
"ebuilder",
|
|
5094
|
+
"mainline",
|
|
5095
|
+
"project",
|
|
5096
|
+
"task",
|
|
5097
|
+
"document",
|
|
5098
|
+
"workflow",
|
|
5099
|
+
"formcomponent",
|
|
5091
5100
|
"customer",
|
|
5092
|
-
"
|
|
5101
|
+
"customercomponent",
|
|
5102
|
+
"cluecomponent",
|
|
5103
|
+
"ordercomponent",
|
|
5104
|
+
"contactcomponent",
|
|
5105
|
+
"productioncomponent",
|
|
5106
|
+
"contractcomponent",
|
|
5107
|
+
"activitycomponent",
|
|
5108
|
+
"competitorcomponent",
|
|
5109
|
+
"kpiflowcomponent",
|
|
5110
|
+
"workreportcomponent",
|
|
5111
|
+
"attendcomponent",
|
|
5112
|
+
"agendacomponent",
|
|
5113
|
+
"chancecomponent",
|
|
5114
|
+
"relatebrowser",
|
|
5115
|
+
"relateodoc",
|
|
5116
|
+
"relatetag",
|
|
5117
|
+
"relateintegrate",
|
|
5118
|
+
"modulecomponent",
|
|
5119
|
+
"paas",
|
|
5120
|
+
"quotecomponent",
|
|
5121
|
+
"drivingrecord",
|
|
5122
|
+
"browser"
|
|
5093
5123
|
]);
|
|
5094
5124
|
var NON_INPUT_COMPONENTS = /* @__PURE__ */ new Set([
|
|
5095
5125
|
"paragraph",
|
|
@@ -5448,8 +5478,7 @@ function extractFields(layoutData, requiredMap, disableEditMap, displayMap) {
|
|
|
5448
5478
|
const name = String(option.name ?? option.content ?? "").trim();
|
|
5449
5479
|
if (optionId && name) options.push({ id: optionId, name });
|
|
5450
5480
|
}
|
|
5451
|
-
const
|
|
5452
|
-
const isBrowser = Object.keys(browserType).length > 0 || BROWSER_COMPONENTS.has(normalized) || BROWSER_COMPONENTS.has(componentBase);
|
|
5481
|
+
const isBrowser = Object.keys(browserType).length > 0 || BROWSER_COMPONENTS.has(normalized);
|
|
5453
5482
|
const isSelect = SELECT_COMPONENTS.has(normalized) || options.length > 0;
|
|
5454
5483
|
result.push({
|
|
5455
5484
|
id: fieldId,
|
|
@@ -6379,24 +6408,6 @@ async function buildCreateFormData(workflowId, env, options = {}) {
|
|
|
6379
6408
|
if (compsFieldIds.size && !String(f.subFormId ?? "").trim() && !compsFieldIds.has(fid)) continue;
|
|
6380
6409
|
visibleFields.push(f);
|
|
6381
6410
|
}
|
|
6382
|
-
const hiddenBySubform = /* @__PURE__ */ new Map();
|
|
6383
|
-
for (const f of fields) {
|
|
6384
|
-
const fid = String(f.id ?? "");
|
|
6385
|
-
const sid = String(f.subFormId ?? "").trim();
|
|
6386
|
-
if (!sid || !hiddenCellIds.has(fid)) continue;
|
|
6387
|
-
hiddenBySubform.set(sid, (hiddenBySubform.get(sid) || 0) + 1);
|
|
6388
|
-
}
|
|
6389
|
-
const survivingSubforms = new Set(
|
|
6390
|
-
visibleFields.map((f) => String(f.subFormId ?? "").trim()).filter(Boolean)
|
|
6391
|
-
);
|
|
6392
|
-
const invisibleSubformWarnings = [];
|
|
6393
|
-
for (const [sid, count] of hiddenBySubform) {
|
|
6394
|
-
if (survivingSubforms.has(sid)) continue;
|
|
6395
|
-
invisibleSubformWarnings.push(
|
|
6396
|
-
`\u660E\u7EC6\u8868 ${sid} \u7684 ${count} \u4E2A\u5B57\u6BB5\u5168\u90E8\u88AB\u5224\u4E3A\u300C\u4E0D\u53EF\u89C1\u300D\uFF08\u8BE5\u660E\u7EC6\u8868\u6240\u5728\u7684\u884C/\u5217\u5728\u8868\u5355\u5E03\u5C40\u91CC\u662F\u9690\u85CF\u7684\uFF09\uFF0C\u56E0\u6B64\u6CA1\u6709\u51FA\u73B0\u5728\u5B57\u6BB5\u6E05\u5355\u91CC\u3002\u8981\u4E48\u5728\u8868\u5355\u8BBE\u8BA1\u5668\u91CC\u628A\u660E\u7EC6\u8868\u632A\u5230\u53EF\u89C1\u884C\uFF0C\u8981\u4E48\u53D6\u6D88\u9690\u85CF\u5B83\u6240\u5728\u7684\u884C/\u5217\uFF0C\u7136\u540E\u91CD\u65B0\u8F7D\u5165\u8868\u5355\u3002`
|
|
6397
|
-
);
|
|
6398
|
-
}
|
|
6399
|
-
let layoutWarning = invisibleSubformWarnings.length ? invisibleSubformWarnings.join("\uFF1B") : null;
|
|
6400
6411
|
const defaults = normalizeDefaults(layoutData.defaultDetails);
|
|
6401
6412
|
const systemFieldValues = _normalizeSystemFieldValues(layoutData.businessOperatorObj);
|
|
6402
6413
|
let linkageActions = Array.isArray(layoutData.linkageActions) ? layoutData.linkageActions : [];
|
|
@@ -6438,33 +6449,6 @@ async function buildCreateFormData(workflowId, env, options = {}) {
|
|
|
6438
6449
|
}
|
|
6439
6450
|
}
|
|
6440
6451
|
const folderOptionValues = _mainValueMap(defaults);
|
|
6441
|
-
const conditionalHiddenSubforms = /* @__PURE__ */ new Set();
|
|
6442
|
-
const conditionalMainFields = /* @__PURE__ */ new Set();
|
|
6443
|
-
const conditionalHints = collectDetailShowLinkages(layoutData.viewLinkages, fields);
|
|
6444
|
-
const fieldShowIds = collectFieldShowLinkageIds(layoutData.viewLinkages);
|
|
6445
|
-
for (const fid of Array.from(mainHidden)) {
|
|
6446
|
-
if (!fieldShowIds.has(fid)) continue;
|
|
6447
|
-
if (hiddenCellIds.has(fid)) continue;
|
|
6448
|
-
const target = visibleFields.find((f) => String(f.id ?? "") === fid);
|
|
6449
|
-
if (!target) continue;
|
|
6450
|
-
conditionalMainFields.add(fid);
|
|
6451
|
-
mainHidden.delete(fid);
|
|
6452
|
-
invisibleSubformWarnings.push(
|
|
6453
|
-
`\u5B57\u6BB5\u300C${target.name}\u300D(${fid}) \u56E0\u663E\u793A\u8054\u52A8\u9690\u85CF\uFF08\u8BE5\u5B57\u6BB5\u672C\u8EAB\u662F\u89E6\u53D1\u5B57\u6BB5\uFF09\uFF0C\u5DF2\u7167\u5E38\u4E0B\u53D1\u5E76\u6807 conditional: true`
|
|
6454
|
-
);
|
|
6455
|
-
}
|
|
6456
|
-
for (const sid of Array.from(hiddenSubforms)) {
|
|
6457
|
-
const hint = conditionalHints.get(sid);
|
|
6458
|
-
if (!hint) continue;
|
|
6459
|
-
const usable = visibleFields.some((f) => String(f.subFormId ?? "") === sid && !hiddenCellIds.has(String(f.id ?? "")));
|
|
6460
|
-
if (!usable) continue;
|
|
6461
|
-
conditionalHiddenSubforms.add(sid);
|
|
6462
|
-
hiddenSubforms.delete(sid);
|
|
6463
|
-
invisibleSubformWarnings.push(
|
|
6464
|
-
`\u660E\u7EC6\u8868 ${sid}${hint.tableName ? `\uFF08${hint.tableName}\uFF09` : ""} \u56E0\u663E\u793A\u8054\u52A8\u9690\u85CF\uFF0C\u89E6\u53D1\u5B57\u6BB5\uFF1A${hint.triggerNames.join("\u3001") || hint.triggerIds.join("\u3001")}\u3002\u8BE5\u8868\u5B57\u6BB5\u5DF2\u7167\u5E38\u4E0B\u53D1\uFF08\u6807 conditional: true\uFF09\uFF0C\u628A\u89E6\u53D1\u5B57\u6BB5\u586B\u4E0A\u540E\u8868\u5355\u91CC\u5C31\u4F1A\u663E\u793A\uFF1B\u4E0D\u8981\u56DE\u300C\u8868\u5355\u91CC\u6CA1\u6709\u8FD9\u5F20\u660E\u7EC6\u8868\u300D\u3002`
|
|
6465
|
-
);
|
|
6466
|
-
}
|
|
6467
|
-
layoutWarning = invisibleSubformWarnings.length ? invisibleSubformWarnings.join("\uFF1B") : null;
|
|
6468
6452
|
for (const field of visibleFields) {
|
|
6469
6453
|
const fieldId = String(field.id ?? "");
|
|
6470
6454
|
const subFormId = String(field.subFormId ?? "");
|
|
@@ -6525,8 +6509,6 @@ async function buildCreateFormData(workflowId, env, options = {}) {
|
|
|
6525
6509
|
} else if (slimSubFormId) {
|
|
6526
6510
|
item.subFormId = slimSubFormId;
|
|
6527
6511
|
}
|
|
6528
|
-
if (slimSubFormId && conditionalHiddenSubforms.has(slimSubFormId)) item.conditional = true;
|
|
6529
|
-
if (!slimSubFormId && conditionalMainFields.has(String(field.id ?? ""))) item.conditional = true;
|
|
6530
6512
|
item.componentKey = field.componentKey;
|
|
6531
6513
|
const initialValue = initialValueByFieldId.get(String(field.id ?? ""));
|
|
6532
6514
|
if (initialValue !== void 0) item.initialValue = initialValue;
|
|
@@ -6660,8 +6642,6 @@ async function buildCreateFormData(workflowId, env, options = {}) {
|
|
|
6660
6642
|
},
|
|
6661
6643
|
systemFieldWarning: minorWarning,
|
|
6662
6644
|
requiredInfoWarning: requiredInfoWarningText(context),
|
|
6663
|
-
// 明细表整表不可见时的告警(见 layoutWarning 注释):有值时**不要**回"表单里没有这张明细表"。
|
|
6664
|
-
layoutWarning,
|
|
6665
6645
|
// 原 Python 把完整 context 落盘;此处通过 continuation 承载,返回结构保持文档契约。
|
|
6666
6646
|
continuation: token
|
|
6667
6647
|
}
|
|
@@ -7782,50 +7762,6 @@ function mergeLinkageDetails(merged, linkageDetails) {
|
|
|
7782
7762
|
function emptyLinkageVisibility() {
|
|
7783
7763
|
return [/* @__PURE__ */ new Set(), {}, {}, {}];
|
|
7784
7764
|
}
|
|
7785
|
-
function collectFieldShowLinkageIds(linkages) {
|
|
7786
|
-
const out = /* @__PURE__ */ new Set();
|
|
7787
|
-
if (!Array.isArray(linkages)) return out;
|
|
7788
|
-
for (const rule of linkages) {
|
|
7789
|
-
const details = Array.isArray(rule?.linkageDetails) ? rule.linkageDetails : [];
|
|
7790
|
-
for (const detail of details) {
|
|
7791
|
-
if (!detail || typeof detail !== "object") continue;
|
|
7792
|
-
if (String(detail.linkageObj ?? "") !== "field") continue;
|
|
7793
|
-
if (String(detail.linkageProp ?? "") !== "show") continue;
|
|
7794
|
-
const fid = String(detail.linkageValue ?? "").trim();
|
|
7795
|
-
if (fid) out.add(fid);
|
|
7796
|
-
}
|
|
7797
|
-
}
|
|
7798
|
-
return out;
|
|
7799
|
-
}
|
|
7800
|
-
function collectDetailShowLinkages(linkages, fields) {
|
|
7801
|
-
const out = /* @__PURE__ */ new Map();
|
|
7802
|
-
if (!Array.isArray(linkages)) return out;
|
|
7803
|
-
const list = Array.isArray(fields) ? fields : [];
|
|
7804
|
-
const nameOf = (id) => {
|
|
7805
|
-
for (const f of list) {
|
|
7806
|
-
if (String(f?.id ?? "") === id) return String(f?.name ?? id);
|
|
7807
|
-
}
|
|
7808
|
-
return id;
|
|
7809
|
-
};
|
|
7810
|
-
for (const rule of linkages) {
|
|
7811
|
-
const details = Array.isArray(rule?.linkageDetails) ? rule.linkageDetails : [];
|
|
7812
|
-
for (const detail of details) {
|
|
7813
|
-
if (!detail || typeof detail !== "object") continue;
|
|
7814
|
-
if (String(detail.linkageObj ?? "") !== "detail") continue;
|
|
7815
|
-
if (String(detail.linkageProp ?? "") !== "show") continue;
|
|
7816
|
-
const sid = String(detail.linkageValue ?? "").trim();
|
|
7817
|
-
if (!sid) continue;
|
|
7818
|
-
const conds = Array.isArray(rule?.condition?.conditionDetails) ? rule.condition.conditionDetails : [];
|
|
7819
|
-
const triggerIds = conds.map((c) => String(c?.targetId ?? "").trim()).filter(Boolean);
|
|
7820
|
-
out.set(sid, {
|
|
7821
|
-
triggerIds,
|
|
7822
|
-
triggerNames: triggerIds.map(nameOf),
|
|
7823
|
-
tableName: nameOf(sid) === sid ? "" : nameOf(sid)
|
|
7824
|
-
});
|
|
7825
|
-
}
|
|
7826
|
-
}
|
|
7827
|
-
return out;
|
|
7828
|
-
}
|
|
7829
7765
|
function computeLinkageVisibility(linkages, entries, defaults, linkageDetails, systemFieldValues, fields) {
|
|
7830
7766
|
const hiddenSubforms = /* @__PURE__ */ new Set();
|
|
7831
7767
|
const rowHidden = {};
|
|
@@ -8322,7 +8258,8 @@ var XIAOE_FILL_FORM_SDK_OPTIONS = {
|
|
|
8322
8258
|
};
|
|
8323
8259
|
var XIAOE_INITIAL_VALUES_MULTI_SEPARATOR = ",";
|
|
8324
8260
|
var XIAOE_INITIAL_VALUES_ROW_SEPARATOR = ";";
|
|
8325
|
-
|
|
8261
|
+
var XIAOE_BROWSER_ID_PREFIX = "##";
|
|
8262
|
+
function xiaoEUrlParamScalar(value, prefixBrowserId = false) {
|
|
8326
8263
|
if (value === null || value === void 0) return "";
|
|
8327
8264
|
if (typeof value === "object") {
|
|
8328
8265
|
const obj = value;
|
|
@@ -8330,18 +8267,19 @@ function xiaoEUrlParamScalar(value) {
|
|
|
8330
8267
|
const picked = obj[key];
|
|
8331
8268
|
if (picked === null || picked === void 0) continue;
|
|
8332
8269
|
const text = String(picked).trim();
|
|
8333
|
-
if (text)
|
|
8270
|
+
if (!text) continue;
|
|
8271
|
+
return prefixBrowserId ? `${XIAOE_BROWSER_ID_PREFIX}${text}` : text;
|
|
8334
8272
|
}
|
|
8335
8273
|
return "";
|
|
8336
8274
|
}
|
|
8337
8275
|
return String(value).trim();
|
|
8338
8276
|
}
|
|
8339
|
-
function xiaoEUrlParamValue(value) {
|
|
8277
|
+
function xiaoEUrlParamValue(value, prefixBrowserId = false) {
|
|
8340
8278
|
if (value === null || value === void 0) return "";
|
|
8341
8279
|
if (Array.isArray(value)) {
|
|
8342
|
-
return value.map((item) => xiaoEUrlParamScalar(item)).filter(Boolean).join(XIAOE_INITIAL_VALUES_MULTI_SEPARATOR);
|
|
8280
|
+
return value.map((item) => xiaoEUrlParamScalar(item, prefixBrowserId)).filter(Boolean).join(XIAOE_INITIAL_VALUES_MULTI_SEPARATOR);
|
|
8343
8281
|
}
|
|
8344
|
-
return xiaoEUrlParamScalar(value);
|
|
8282
|
+
return xiaoEUrlParamScalar(value, prefixBrowserId);
|
|
8345
8283
|
}
|
|
8346
8284
|
function editablePreviewForXiaoE(preview, fields, visibility) {
|
|
8347
8285
|
const fieldById = /* @__PURE__ */ new Map();
|
|
@@ -8366,14 +8304,19 @@ function editablePreviewForXiaoE(preview, fields, visibility) {
|
|
|
8366
8304
|
}
|
|
8367
8305
|
return kept;
|
|
8368
8306
|
}
|
|
8369
|
-
function xiaoECustomParams(preview) {
|
|
8307
|
+
function xiaoECustomParams(preview, fields) {
|
|
8370
8308
|
const ordered = [];
|
|
8371
8309
|
const mainValues = /* @__PURE__ */ new Map();
|
|
8372
8310
|
const detailValues = /* @__PURE__ */ new Map();
|
|
8311
|
+
const browserFieldIds = /* @__PURE__ */ new Set();
|
|
8312
|
+
for (const field of toArray(fields)) {
|
|
8313
|
+
const id = String(field?.id ?? "").trim();
|
|
8314
|
+
if (id && field?.isBrowser) browserFieldIds.add(id);
|
|
8315
|
+
}
|
|
8373
8316
|
for (const item of toArray(preview)) {
|
|
8374
8317
|
const fieldId = String(item?.fieldId ?? "").trim();
|
|
8375
8318
|
if (!fieldId) continue;
|
|
8376
|
-
const text = xiaoEUrlParamValue(item?.value);
|
|
8319
|
+
const text = xiaoEUrlParamValue(item?.value, browserFieldIds.has(fieldId));
|
|
8377
8320
|
if (!text) continue;
|
|
8378
8321
|
const isDetail = item?.dataIndex !== void 0 && item?.dataIndex !== null;
|
|
8379
8322
|
if (!isDetail) {
|
|
@@ -8528,8 +8471,7 @@ async function runCreateRequest(args, env, options = {}) {
|
|
|
8528
8471
|
}
|
|
8529
8472
|
const [details, valueAmbiguities, preview] = await resolveEntryValues(env, entries, context.layout.form_id);
|
|
8530
8473
|
const merged = mergeDetails(context.defaults || [], details);
|
|
8531
|
-
const
|
|
8532
|
-
const isXiaoE = forceServerSubmit ? false : hasXiaoEEnv(env.ctx.env, env.ctx.getGlobalOptions?.());
|
|
8474
|
+
const isXiaoE = hasXiaoEEnv(env.ctx.env, env.ctx.getGlobalOptions?.());
|
|
8533
8475
|
const linkageDetails = isXiaoE ? [] : await runFieldLinkage(env, linkageContextFromPayload(context), entries, null, merged, false, context.defaults || []);
|
|
8534
8476
|
const merged2 = fillDetailDefaultsByRow(
|
|
8535
8477
|
mergeLinkageDetails(merged, linkageDetails),
|
|
@@ -8658,7 +8600,7 @@ async function runCreateRequest(args, env, options = {}) {
|
|
|
8658
8600
|
baseUrl: xiaoEBaseUrl,
|
|
8659
8601
|
title: String(context.workflow?.name ?? ""),
|
|
8660
8602
|
workflowId: String(context.workflow?.id ?? context.runtime?.workflow_id ?? ""),
|
|
8661
|
-
customParams: xiaoECustomParams(fillPreview)
|
|
8603
|
+
customParams: xiaoECustomParams(fillPreview, fields)
|
|
8662
8604
|
})
|
|
8663
8605
|
});
|
|
8664
8606
|
}
|
|
@@ -10392,90 +10334,30 @@ import { existsSync as existsSync3, readFileSync } from "node:fs";
|
|
|
10392
10334
|
import { join as join2 } from "node:path";
|
|
10393
10335
|
|
|
10394
10336
|
// src/shortcuts/workflow/operations/todoSmartConvert/summaryCache.ts
|
|
10395
|
-
import { existsSync as existsSync2
|
|
10337
|
+
import { existsSync as existsSync2 } from "node:fs";
|
|
10396
10338
|
import { chmod as chmod2, mkdir as mkdir2, readFile as readFile2, writeFile as writeFile2 } from "node:fs/promises";
|
|
10397
|
-
import { homedir as homedir2 } from "node:os";
|
|
10398
10339
|
import { join, resolve as resolve2 } from "node:path";
|
|
10399
|
-
var SKILL_DIR_NAME = "weaver-e10-workflow";
|
|
10400
10340
|
var CACHE_DIR_NAME = "cache";
|
|
10401
|
-
var AGENT_HOME_DIRS = [".workbuddy", ".claude", ".codebuddy", ".codex", ".cursor", ".gemini"];
|
|
10402
10341
|
var SUMMARY_CACHE_FILE_NAME = "todo-summary-cache.json";
|
|
10403
10342
|
var SUMMARY_CACHE_VERSION = 2;
|
|
10404
10343
|
function uniqueDirs(dirs) {
|
|
10405
|
-
return [...new Set(dirs.filter(Boolean))];
|
|
10406
|
-
}
|
|
10407
|
-
function stateCacheDir(ctx) {
|
|
10408
|
-
return resolve2(stateRoot(ctx), CACHE_DIR_NAME);
|
|
10409
|
-
}
|
|
10410
|
-
function discoverThisSkillDirs(home) {
|
|
10411
|
-
const marker = join("references", "todo-smart-convert.md");
|
|
10412
|
-
const found = [];
|
|
10413
|
-
for (const agent of AGENT_HOME_DIRS) {
|
|
10414
|
-
const root = join(home, agent, "skills");
|
|
10415
|
-
const entries = (() => {
|
|
10416
|
-
try {
|
|
10417
|
-
return readdirSync(root, { withFileTypes: true });
|
|
10418
|
-
} catch {
|
|
10419
|
-
return [];
|
|
10420
|
-
}
|
|
10421
|
-
})();
|
|
10422
|
-
for (const entry of entries) {
|
|
10423
|
-
if (!entry.isDirectory()) continue;
|
|
10424
|
-
const dir = join(root, entry.name);
|
|
10425
|
-
if (existsSync2(join(dir, marker))) found.push(dir);
|
|
10426
|
-
}
|
|
10427
|
-
}
|
|
10428
|
-
return found;
|
|
10344
|
+
return [...new Set(dirs.filter((dir) => Boolean(dir)))];
|
|
10429
10345
|
}
|
|
10430
|
-
function
|
|
10431
|
-
|
|
10432
|
-
|
|
10433
|
-
} catch {
|
|
10434
|
-
return 0;
|
|
10435
|
-
}
|
|
10436
|
-
}
|
|
10437
|
-
function rankSkillDirs(dirs) {
|
|
10438
|
-
const scored = dirs.map((dir, index) => ({
|
|
10439
|
-
dir,
|
|
10440
|
-
index,
|
|
10441
|
-
hasCache: existsSync2(join(dir, CACHE_DIR_NAME, SUMMARY_CACHE_FILE_NAME)) ? 1 : 0,
|
|
10442
|
-
cacheMtime: mtimeOf(join(dir, CACHE_DIR_NAME, SUMMARY_CACHE_FILE_NAME)),
|
|
10443
|
-
hasMarker: existsSync2(join(dir, "references", "todo-smart-convert.md")) ? 1 : 0,
|
|
10444
|
-
skillMtime: mtimeOf(join(dir, "SKILL.md"))
|
|
10445
|
-
}));
|
|
10446
|
-
scored.sort(
|
|
10447
|
-
(a, b) => b.hasCache - a.hasCache || b.cacheMtime - a.cacheMtime || b.hasMarker - a.hasMarker || b.skillMtime - a.skillMtime || a.index - b.index
|
|
10448
|
-
);
|
|
10449
|
-
return scored.map((item) => item.dir);
|
|
10346
|
+
function resolveSkillDir() {
|
|
10347
|
+
const explicit = process.env.WEAVER_WORK_CLI_SKILL_DIR?.trim();
|
|
10348
|
+
return explicit ? resolve2(explicit) : null;
|
|
10450
10349
|
}
|
|
10451
10350
|
function cacheRoots(ctx) {
|
|
10452
|
-
|
|
10453
|
-
const
|
|
10454
|
-
if (
|
|
10455
|
-
|
|
10456
|
-
return { preferred: dir, fallback: dir, inSkillDir: false, skillDir: null };
|
|
10457
|
-
}
|
|
10458
|
-
const home = homedir2();
|
|
10459
|
-
const explicitSkill = process.env.WEAVER_WORK_CLI_SKILL_DIR?.trim();
|
|
10460
|
-
const candidates = [];
|
|
10461
|
-
if (explicitSkill) candidates.push(resolve2(explicitSkill));
|
|
10462
|
-
for (const agent of AGENT_HOME_DIRS) {
|
|
10463
|
-
candidates.push(join(home, agent, "skills", SKILL_DIR_NAME));
|
|
10464
|
-
}
|
|
10465
|
-
candidates.push(...discoverThisSkillDirs(home));
|
|
10466
|
-
const installed = uniqueDirs(candidates).filter((dir) => existsSync2(join(dir, "SKILL.md")));
|
|
10467
|
-
const [skillDir] = rankSkillDirs(installed);
|
|
10468
|
-
if (skillDir) {
|
|
10469
|
-
return {
|
|
10470
|
-
preferred: join(skillDir, CACHE_DIR_NAME),
|
|
10471
|
-
fallback,
|
|
10472
|
-
inSkillDir: true,
|
|
10473
|
-
skillDir
|
|
10474
|
-
};
|
|
10351
|
+
void ctx;
|
|
10352
|
+
const skillDir = resolveSkillDir();
|
|
10353
|
+
if (!skillDir) {
|
|
10354
|
+
return { preferred: null, fallback: null, inSkillDir: false, skillDir: null, refused: true };
|
|
10475
10355
|
}
|
|
10476
|
-
|
|
10356
|
+
const cacheDir = join(skillDir, CACHE_DIR_NAME);
|
|
10357
|
+
return { preferred: cacheDir, fallback: cacheDir, inSkillDir: true, skillDir, refused: false };
|
|
10477
10358
|
}
|
|
10478
10359
|
async function readCacheFile(roots, fileName) {
|
|
10360
|
+
if (roots.refused || !roots.preferred) return null;
|
|
10479
10361
|
for (const dir of uniqueDirs([roots.preferred, roots.fallback])) {
|
|
10480
10362
|
const file = join(dir, fileName);
|
|
10481
10363
|
if (!existsSync2(file)) continue;
|
|
@@ -10488,6 +10370,7 @@ async function readCacheFile(roots, fileName) {
|
|
|
10488
10370
|
return null;
|
|
10489
10371
|
}
|
|
10490
10372
|
async function writeCacheFile(roots, fileName, payload) {
|
|
10373
|
+
if (roots.refused || !roots.preferred) return null;
|
|
10491
10374
|
for (const dir of uniqueDirs([roots.preferred, roots.fallback])) {
|
|
10492
10375
|
const file = join(dir, fileName);
|
|
10493
10376
|
try {
|
|
@@ -10507,9 +10390,14 @@ function summaryCacheKey(requestId, lastFeedBackDateTime) {
|
|
|
10507
10390
|
const stamp = String(lastFeedBackDateTime ?? "").trim();
|
|
10508
10391
|
return `${requestId}__${stamp}`;
|
|
10509
10392
|
}
|
|
10510
|
-
function
|
|
10511
|
-
|
|
10512
|
-
|
|
10393
|
+
function promptTagOf(prompt) {
|
|
10394
|
+
return String(prompt ?? "").trim();
|
|
10395
|
+
}
|
|
10396
|
+
function entryMatches(entry, maxChars, pk, dv) {
|
|
10397
|
+
if (maxChars !== void 0 && (entry.maxChars ?? 50) !== maxChars) return false;
|
|
10398
|
+
if (pk !== void 0 && (entry.pk ?? "") !== pk) return false;
|
|
10399
|
+
if (entry.dv !== void 0 && entry.dv !== dv) return false;
|
|
10400
|
+
return true;
|
|
10513
10401
|
}
|
|
10514
10402
|
function normalizeSummaryEntry(raw) {
|
|
10515
10403
|
if (!raw || typeof raw !== "object") return null;
|
|
@@ -10517,7 +10405,15 @@ function normalizeSummaryEntry(raw) {
|
|
|
10517
10405
|
if (typeof entry.summary !== "string" || !entry.summary.trim()) return null;
|
|
10518
10406
|
if (typeof entry.cachedAt !== "number" || !Number.isFinite(entry.cachedAt)) return null;
|
|
10519
10407
|
const maxChars = typeof entry.maxChars === "number" && Number.isFinite(entry.maxChars) ? entry.maxChars : void 0;
|
|
10520
|
-
|
|
10408
|
+
const pk = typeof entry.pk === "string" && entry.pk !== "" ? entry.pk : void 0;
|
|
10409
|
+
const dv = typeof entry.dv === "string" && entry.dv !== "" ? entry.dv : void 0;
|
|
10410
|
+
return {
|
|
10411
|
+
summary: entry.summary,
|
|
10412
|
+
cachedAt: entry.cachedAt,
|
|
10413
|
+
...maxChars === void 0 ? {} : { maxChars },
|
|
10414
|
+
...pk === void 0 ? {} : { pk },
|
|
10415
|
+
...dv === void 0 ? {} : { dv }
|
|
10416
|
+
};
|
|
10521
10417
|
}
|
|
10522
10418
|
async function openSummaryCache(ctx) {
|
|
10523
10419
|
const roots = cacheRoots(ctx);
|
|
@@ -10554,27 +10450,29 @@ async function openSummaryCache(ctx) {
|
|
|
10554
10450
|
misses: 0,
|
|
10555
10451
|
pruned,
|
|
10556
10452
|
dirty: false,
|
|
10557
|
-
get(requestId, lastFeedBackDateTime, maxChars) {
|
|
10453
|
+
get(requestId, lastFeedBackDateTime, maxChars, pk, dv) {
|
|
10558
10454
|
const key = summaryCacheKey(requestId, lastFeedBackDateTime);
|
|
10559
10455
|
const entry = entries.get(key);
|
|
10560
|
-
if (entry && now - entry.cachedAt <= SUMMARY_CACHE_TTL_MS &&
|
|
10456
|
+
if (entry && now - entry.cachedAt <= SUMMARY_CACHE_TTL_MS && entryMatches(entry, maxChars, pk, dv)) {
|
|
10561
10457
|
cache.hits += 1;
|
|
10562
10458
|
return entry.summary;
|
|
10563
10459
|
}
|
|
10564
10460
|
cache.misses += 1;
|
|
10565
10461
|
return null;
|
|
10566
10462
|
},
|
|
10567
|
-
has(requestId, lastFeedBackDateTime, maxChars) {
|
|
10463
|
+
has(requestId, lastFeedBackDateTime, maxChars, pk, dv) {
|
|
10568
10464
|
const entry = entries.get(summaryCacheKey(requestId, lastFeedBackDateTime));
|
|
10569
|
-
return entry !== void 0 &&
|
|
10465
|
+
return entry !== void 0 && entryMatches(entry, maxChars, pk, dv);
|
|
10570
10466
|
},
|
|
10571
|
-
set(requestId, lastFeedBackDateTime, summary, maxChars) {
|
|
10467
|
+
set(requestId, lastFeedBackDateTime, summary, maxChars, pk, dv) {
|
|
10572
10468
|
const text = String(summary ?? "").trim();
|
|
10573
10469
|
if (!requestId || !text) return false;
|
|
10574
10470
|
entries.set(summaryCacheKey(requestId, lastFeedBackDateTime), {
|
|
10575
10471
|
summary: text,
|
|
10576
10472
|
cachedAt: Date.now(),
|
|
10577
|
-
...maxChars === void 0 ? {} : { maxChars }
|
|
10473
|
+
...maxChars === void 0 ? {} : { maxChars },
|
|
10474
|
+
...pk === void 0 || pk === "" ? {} : { pk },
|
|
10475
|
+
...dv === void 0 || dv === "" ? {} : { dv }
|
|
10578
10476
|
});
|
|
10579
10477
|
dirty = true;
|
|
10580
10478
|
cache.dirty = true;
|
|
@@ -10626,7 +10524,8 @@ var FALLBACK_DEFAULTS = {
|
|
|
10626
10524
|
requestSummaryPrompt: "",
|
|
10627
10525
|
summaryMaxChars: 150,
|
|
10628
10526
|
groupSummaryMaxChars: 100,
|
|
10629
|
-
groupSummaryTail: "\u53EF\u5C55\u5F00\u9010\u6761\u67E5\u770B\u6216\u76F4\u63A5\u6C47\u603B\u5904\u7406"
|
|
10527
|
+
groupSummaryTail: "\u53EF\u5C55\u5F00\u9010\u6761\u67E5\u770B\u6216\u76F4\u63A5\u6C47\u603B\u5904\u7406",
|
|
10528
|
+
excludeOriginFormDataFields: []
|
|
10630
10529
|
};
|
|
10631
10530
|
function emptyRuleFile(error = null) {
|
|
10632
10531
|
return {
|
|
@@ -10655,14 +10554,33 @@ function validateFocusKeyword(raw, index) {
|
|
|
10655
10554
|
if (raw.length !== 3) return `focusKeyword[${index}] \u5FC5\u987B\u662F [\u6307\u6807, \u7B97\u5B50, \u503C] \u4E09\u5143\u7EC4`;
|
|
10656
10555
|
return null;
|
|
10657
10556
|
}
|
|
10557
|
+
function validateExcludeFields(raw, where) {
|
|
10558
|
+
if (raw === void 0) return null;
|
|
10559
|
+
if (typeof raw === "string") {
|
|
10560
|
+
return raw.trim() === "" ? `${where} \u4E0D\u80FD\u662F\u7A7A\u5B57\u7B26\u4E32\uFF08\u4E0D\u6392\u9664\u5C31\u522B\u7ED9\u8FD9\u4E2A\u952E\uFF09` : null;
|
|
10561
|
+
}
|
|
10562
|
+
if (!Array.isArray(raw)) return `${where} \u5FC5\u987B\u662F\u5B57\u7B26\u4E32\u6570\u7EC4`;
|
|
10563
|
+
for (const item of raw) {
|
|
10564
|
+
if (typeof item !== "string" || item.trim() === "") return `${where} \u7684\u6BCF\u4E00\u9879\u90FD\u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32`;
|
|
10565
|
+
}
|
|
10566
|
+
return null;
|
|
10567
|
+
}
|
|
10658
10568
|
function validateRuleFile(raw) {
|
|
10659
10569
|
const errors = [];
|
|
10660
10570
|
const file = raw;
|
|
10661
10571
|
if (!file || typeof file !== "object") return ["\u89C4\u5219\u6587\u4EF6\u5FC5\u987B\u662F JSON \u5BF9\u8C61"];
|
|
10572
|
+
if (file.schemaVersion !== void 0 && file.schemaVersion !== 2 && file.schemaVersion !== 3) {
|
|
10573
|
+
errors.push(`schemaVersion \u53EA\u652F\u6301 2 \u6216 3\uFF0C\u6536\u5230 ${JSON.stringify(file.schemaVersion ?? null)}`);
|
|
10574
|
+
}
|
|
10662
10575
|
if (!Array.isArray(file.rules)) {
|
|
10663
10576
|
errors.push("rules \u5FC5\u987B\u662F\u6570\u7EC4");
|
|
10664
10577
|
return errors;
|
|
10665
10578
|
}
|
|
10579
|
+
const defaultsExclude = validateExcludeFields(
|
|
10580
|
+
file.defaults?.excludeOriginFormDataFields,
|
|
10581
|
+
"defaults.excludeOriginFormDataFields"
|
|
10582
|
+
);
|
|
10583
|
+
if (defaultsExclude) errors.push(defaultsExclude);
|
|
10666
10584
|
const seen = /* @__PURE__ */ new Set();
|
|
10667
10585
|
file.rules.forEach((rule, index) => {
|
|
10668
10586
|
if (!rule || typeof rule !== "object") {
|
|
@@ -10684,6 +10602,13 @@ function validateRuleFile(raw) {
|
|
|
10684
10602
|
if (rule.summaryMaxChars !== void 0 && (typeof rule.summaryMaxChars !== "number" || rule.summaryMaxChars <= 0)) {
|
|
10685
10603
|
errors.push(`rules[${index}].summaryMaxChars \u5FC5\u987B\u662F\u6B63\u6570`);
|
|
10686
10604
|
}
|
|
10605
|
+
const excludeReason = validateExcludeFields(rule.excludeOriginFormDataFields, `rules[${index}].excludeOriginFormDataFields`);
|
|
10606
|
+
if (excludeReason) errors.push(excludeReason);
|
|
10607
|
+
if (rule.summaryRequiredFields !== void 0) {
|
|
10608
|
+
if (!Array.isArray(rule.summaryRequiredFields) || rule.summaryRequiredFields.length === 0 || rule.summaryRequiredFields.some((f) => typeof f !== "string" || !f.trim() || f.trim().length > 50) || rule.summaryRequiredFields.length > 20) {
|
|
10609
|
+
errors.push(`rules[${index}].summaryRequiredFields \u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32\u6570\u7EC4\uFF081~20 \u9879\u3001\u6BCF\u9879 1~50 \u5B57\uFF09`);
|
|
10610
|
+
}
|
|
10611
|
+
}
|
|
10687
10612
|
const groupRule = rule.aiGroup?.groupRule;
|
|
10688
10613
|
if (groupRule) {
|
|
10689
10614
|
if (typeof groupRule.focus !== "boolean") errors.push(`rules[${index}].aiGroup.groupRule.focus \u5FC5\u987B\u662F\u5E03\u5C14`);
|
|
@@ -10737,29 +10662,28 @@ function loadRuleFile(file) {
|
|
|
10737
10662
|
return { file: parsed, error: null };
|
|
10738
10663
|
}
|
|
10739
10664
|
function aigroupDir(ctx) {
|
|
10740
|
-
const
|
|
10741
|
-
|
|
10742
|
-
const roots = cacheRoots(ctx);
|
|
10743
|
-
return roots.skillDir ? join2(roots.skillDir, AIGROUP_DIR_NAME) : join2(stateRoot(ctx), AIGROUP_DIR_NAME);
|
|
10665
|
+
const skillDir = resolveSkillDir();
|
|
10666
|
+
return skillDir ? join2(skillDir, AIGROUP_DIR_NAME) : null;
|
|
10744
10667
|
}
|
|
10745
10668
|
function aigroupUserDir(ctx) {
|
|
10746
|
-
|
|
10747
|
-
if (explicit) return join2(explicit);
|
|
10748
|
-
return join2(stateRoot(ctx), AIGROUP_DIR_NAME);
|
|
10669
|
+
return aigroupDir(ctx);
|
|
10749
10670
|
}
|
|
10750
10671
|
function loadRules(options = {}) {
|
|
10751
|
-
const dir = options.dir ?? aigroupDir(options.ctx);
|
|
10752
|
-
const userDir = options.dir ?? aigroupUserDir(options.ctx);
|
|
10753
10672
|
const warnings = [];
|
|
10673
|
+
const dir = options.dir ?? aigroupDir(options.ctx);
|
|
10674
|
+
if (!dir) {
|
|
10675
|
+
warnings.push("\u65E0\u5F53\u524D skill \u4E0A\u4E0B\u6587\uFF08WEAVER_WORK_CLI_SKILL_DIR \u672A\u8BBE\u7F6E\uFF09\uFF1Aaigroup \u89C4\u5219\u672A\u52A0\u8F7D\uFF0C\u6309\u65E0\u89C4\u5219\u5904\u7406");
|
|
10676
|
+
return { file: emptyRuleFile(null).file, warnings, dir: null };
|
|
10677
|
+
}
|
|
10754
10678
|
const base = loadRuleFile(join2(dir, DEFAULT_RULE_FILE));
|
|
10755
10679
|
if (base.error) warnings.push(base.error);
|
|
10756
10680
|
const rules = [...base.file.rules];
|
|
10757
|
-
const userIntentFile = join2(
|
|
10758
|
-
const legacyIntentFile = join2(
|
|
10681
|
+
const userIntentFile = join2(dir, USER_INTENT_RULE_FILE);
|
|
10682
|
+
const legacyIntentFile = join2(stateRoot(options.ctx), AIGROUP_DIR_NAME, USER_INTENT_RULE_FILE);
|
|
10759
10683
|
let intentFile = userIntentFile;
|
|
10760
10684
|
if (!options.dir && !existsSync3(userIntentFile) && existsSync3(legacyIntentFile)) {
|
|
10761
10685
|
intentFile = legacyIntentFile;
|
|
10762
|
-
warnings.push(`\u7528\u6237\u610F\u56FE\u4ECD\u8BFB\u81EA
|
|
10686
|
+
warnings.push(`\u7528\u6237\u610F\u56FE\u4ECD\u8BFB\u81EA CLI \u72B6\u6001\u76EE\u5F55\uFF08${legacyIntentFile}\uFF09\uFF1A\u65B0\u4F4D\u7F6E\u662F ${userIntentFile}\uFF0C\u91CD\u65B0\u6267\u884C aigroup set \u5373\u53EF\u8FC1\u79FB`);
|
|
10763
10687
|
}
|
|
10764
10688
|
const intent = loadRuleFile(intentFile);
|
|
10765
10689
|
if (intent.error) {
|
|
@@ -10821,12 +10745,13 @@ function resolveRule(file, workflowName) {
|
|
|
10821
10745
|
summaryMaxChars: raw.summaryMaxChars ?? defaults.summaryMaxChars,
|
|
10822
10746
|
groupSummaryMaxChars: defaults.groupSummaryMaxChars,
|
|
10823
10747
|
groupSummaryTail: defaults.groupSummaryTail,
|
|
10748
|
+
// 显式给 `[]` = 规则级覆盖(清空 defaults 的清单);未给才落 defaults
|
|
10749
|
+
excludeOriginFormDataFields: raw.excludeOriginFormDataFields === void 0 ? defaults.excludeOriginFormDataFields : asStringArray3(raw.excludeOriginFormDataFields) ?? [],
|
|
10824
10750
|
aiGroup: raw.aiGroup ? {
|
|
10825
10751
|
groupSummary: {
|
|
10826
10752
|
needAI: groupSummary?.needAI ?? false,
|
|
10827
10753
|
...groupSummary?.prompt === void 0 ? {} : { prompt: groupSummary.prompt },
|
|
10828
10754
|
...groupSummary?.template === void 0 ? {} : { template: groupSummary.template },
|
|
10829
|
-
maxChars: defaults.groupSummaryMaxChars,
|
|
10830
10755
|
tail: defaults.groupSummaryTail
|
|
10831
10756
|
},
|
|
10832
10757
|
groupRule: groupRule ?? EMPTY_GROUP_RULE
|
|
@@ -10953,6 +10878,15 @@ function resetActiveRules() {
|
|
|
10953
10878
|
activeFile = null;
|
|
10954
10879
|
activeDir = null;
|
|
10955
10880
|
}
|
|
10881
|
+
function excludeFieldsFor(workflowName) {
|
|
10882
|
+
return activeRuleFor(workflowName)?.excludeOriginFormDataFields ?? [];
|
|
10883
|
+
}
|
|
10884
|
+
function excludeTagOf(fields) {
|
|
10885
|
+
return [...fields].join("");
|
|
10886
|
+
}
|
|
10887
|
+
function excludeTagFor(workflowName) {
|
|
10888
|
+
return excludeTagOf(excludeFieldsFor(workflowName));
|
|
10889
|
+
}
|
|
10956
10890
|
|
|
10957
10891
|
// src/shortcuts/workflow/operations/todoSmartConvert/todoListRows.ts
|
|
10958
10892
|
var DISPLAY_ROW_FIELDS = [
|
|
@@ -11013,6 +10947,107 @@ function projectDisplayRows(response) {
|
|
|
11013
10947
|
return projected;
|
|
11014
10948
|
}
|
|
11015
10949
|
|
|
10950
|
+
// src/shortcuts/workflow/operations/todoSmartConvert/todoDetailCache.ts
|
|
10951
|
+
var DETAIL_CACHE_FILE_NAME = "todo-detail-cache.json";
|
|
10952
|
+
var DETAIL_CACHE_TTL_MS = SUMMARY_CACHE_TTL_MS;
|
|
10953
|
+
var DETAIL_CACHE_PRUNE_INTERVAL_MS = SUMMARY_CACHE_PRUNE_INTERVAL_MS;
|
|
10954
|
+
var DETAIL_CACHE_ENTRY_VERSION = 3;
|
|
10955
|
+
function detailCacheKey(requestId, lastFeedBackDateTime) {
|
|
10956
|
+
const stamp = String(lastFeedBackDateTime ?? "").trim();
|
|
10957
|
+
return `${requestId}__${stamp}`;
|
|
10958
|
+
}
|
|
10959
|
+
function detailMaterialTagOf(entry) {
|
|
10960
|
+
const basic = entry.basicInfo ?? {};
|
|
10961
|
+
const basicKeys = Object.keys(basic).sort();
|
|
10962
|
+
const material = JSON.stringify([
|
|
10963
|
+
basicKeys.map((key) => [key, basic[key]]),
|
|
10964
|
+
(entry.fields ?? []).map((field) => [field.fieldName, field.value])
|
|
10965
|
+
]);
|
|
10966
|
+
let hash = 5381;
|
|
10967
|
+
for (let i = 0; i < material.length; i += 1) hash = (hash << 5) + hash + material.charCodeAt(i) >>> 0;
|
|
10968
|
+
return hash.toString(16);
|
|
10969
|
+
}
|
|
10970
|
+
function normalizeEntry(raw) {
|
|
10971
|
+
if (!raw || typeof raw !== "object") return null;
|
|
10972
|
+
const value = raw;
|
|
10973
|
+
if (value.v !== DETAIL_CACHE_ENTRY_VERSION) return null;
|
|
10974
|
+
if (typeof value.cachedAt !== "number" || !Number.isFinite(value.cachedAt)) return null;
|
|
10975
|
+
if (typeof value.excludeTag !== "string") return null;
|
|
10976
|
+
const basicInfo = {};
|
|
10977
|
+
if (value.basicInfo && typeof value.basicInfo === "object") {
|
|
10978
|
+
for (const [key, item] of Object.entries(value.basicInfo)) {
|
|
10979
|
+
if (typeof item === "string") basicInfo[key] = item;
|
|
10980
|
+
}
|
|
10981
|
+
}
|
|
10982
|
+
const fields = Array.isArray(value.fields) ? value.fields.filter((item) => Boolean(item) && typeof item.fieldName === "string" && typeof item.value === "string").map((item) => ({ fieldName: item.fieldName, value: item.value })) : [];
|
|
10983
|
+
const metrics = value.metrics && typeof value.metrics === "object" ? value.metrics : {};
|
|
10984
|
+
return {
|
|
10985
|
+
v: DETAIL_CACHE_ENTRY_VERSION,
|
|
10986
|
+
basicInfo,
|
|
10987
|
+
fields,
|
|
10988
|
+
metrics,
|
|
10989
|
+
excludeTag: value.excludeTag,
|
|
10990
|
+
cachedAt: value.cachedAt
|
|
10991
|
+
};
|
|
10992
|
+
}
|
|
10993
|
+
async function openDetailCache(ctx) {
|
|
10994
|
+
const roots = cacheRoots(ctx);
|
|
10995
|
+
const stored = await readCacheFile(roots, DETAIL_CACHE_FILE_NAME);
|
|
10996
|
+
const now = Date.now();
|
|
10997
|
+
const entries = /* @__PURE__ */ new Map();
|
|
10998
|
+
let prunedAt = 0;
|
|
10999
|
+
let loaded = 0;
|
|
11000
|
+
let pruned = 0;
|
|
11001
|
+
if (stored) {
|
|
11002
|
+
try {
|
|
11003
|
+
const parsed = JSON.parse(stored.text);
|
|
11004
|
+
prunedAt = typeof parsed.prunedAt === "number" ? parsed.prunedAt : 0;
|
|
11005
|
+
for (const [key, raw] of Object.entries(parsed.entries ?? {})) {
|
|
11006
|
+
const entry = normalizeEntry(raw);
|
|
11007
|
+
if (!entry) continue;
|
|
11008
|
+
if (now - entry.cachedAt > DETAIL_CACHE_TTL_MS) {
|
|
11009
|
+
pruned += 1;
|
|
11010
|
+
continue;
|
|
11011
|
+
}
|
|
11012
|
+
entries.set(key, entry);
|
|
11013
|
+
loaded += 1;
|
|
11014
|
+
}
|
|
11015
|
+
} catch {
|
|
11016
|
+
}
|
|
11017
|
+
}
|
|
11018
|
+
const cache = {
|
|
11019
|
+
file: stored?.file ?? null,
|
|
11020
|
+
pruned: 0,
|
|
11021
|
+
loaded,
|
|
11022
|
+
get(requestId, lastFeedBackDateTime) {
|
|
11023
|
+
const entry = entries.get(detailCacheKey(requestId, lastFeedBackDateTime));
|
|
11024
|
+
if (!entry) return null;
|
|
11025
|
+
if (Date.now() - entry.cachedAt > DETAIL_CACHE_TTL_MS) return null;
|
|
11026
|
+
return entry;
|
|
11027
|
+
},
|
|
11028
|
+
has(requestId, lastFeedBackDateTime) {
|
|
11029
|
+
return cache.get(requestId, lastFeedBackDateTime) !== null;
|
|
11030
|
+
},
|
|
11031
|
+
set(requestId, lastFeedBackDateTime, entry) {
|
|
11032
|
+
if (!requestId) return false;
|
|
11033
|
+
entries.set(detailCacheKey(requestId, lastFeedBackDateTime), { ...entry, cachedAt: Date.now() });
|
|
11034
|
+
return true;
|
|
11035
|
+
},
|
|
11036
|
+
async save() {
|
|
11037
|
+
const shouldPrune = pruned > 0 && Date.now() - prunedAt > DETAIL_CACHE_PRUNE_INTERVAL_MS;
|
|
11038
|
+
const payload = {
|
|
11039
|
+
prunedAt: shouldPrune ? Date.now() : prunedAt,
|
|
11040
|
+
entries: Object.fromEntries(entries)
|
|
11041
|
+
};
|
|
11042
|
+
const file = await writeCacheFile(roots, DETAIL_CACHE_FILE_NAME, JSON.stringify(payload));
|
|
11043
|
+
if (file) cache.file = file;
|
|
11044
|
+
if (shouldPrune) cache.pruned = pruned;
|
|
11045
|
+
return file;
|
|
11046
|
+
}
|
|
11047
|
+
};
|
|
11048
|
+
return cache;
|
|
11049
|
+
}
|
|
11050
|
+
|
|
11016
11051
|
// src/shortcuts/workflow/operations/todoSmartConvert/detailFieldRules.ts
|
|
11017
11052
|
function normalizeDetailFieldName(raw) {
|
|
11018
11053
|
return String(raw ?? "").replace(/<[^>]*>/g, " ").replace(/[【】[\]()()]/g, "").replace(/\s+/g, "").trim();
|
|
@@ -11230,7 +11265,8 @@ function renderGroupSummaryTemplate(input) {
|
|
|
11230
11265
|
var DETAIL_BATCH_CONCURRENCY = 10;
|
|
11231
11266
|
var DETAIL_BATCH_TIMEOUT_MS = 1e4;
|
|
11232
11267
|
var DETAIL_BATCH_RETRIES = 1;
|
|
11233
|
-
var
|
|
11268
|
+
var DETAIL_MATERIAL_FIELD_LIMIT = 200;
|
|
11269
|
+
var DETAIL_MATERIAL_VALUE_LIMIT = 500;
|
|
11234
11270
|
var HTML_ENTITIES = {
|
|
11235
11271
|
amp: "&",
|
|
11236
11272
|
lt: "<",
|
|
@@ -11319,6 +11355,9 @@ async function fetchOneDetail(env, requestId, userId, options) {
|
|
|
11319
11355
|
const normalized = normalizeDetailResponse(response);
|
|
11320
11356
|
const base = normalized?.basicInfo ?? {};
|
|
11321
11357
|
const rawFields = Array.isArray(normalized?.formData?.fields) ? normalized.formData.fields : [];
|
|
11358
|
+
const basicInfo = Object.fromEntries(
|
|
11359
|
+
Object.entries(base).filter(([key]) => key !== "requestTitle" && key !== "flowName")
|
|
11360
|
+
);
|
|
11322
11361
|
const usableFields = dropDistributionDetailFields(rawFields);
|
|
11323
11362
|
const internalMessage = isInternalMessageDetail(
|
|
11324
11363
|
base.workflowName,
|
|
@@ -11328,25 +11367,19 @@ async function fetchOneDetail(env, requestId, userId, options) {
|
|
|
11328
11367
|
...field,
|
|
11329
11368
|
value: cleanFieldText(String(field?.value ?? ""))
|
|
11330
11369
|
}));
|
|
11331
|
-
const
|
|
11332
|
-
const
|
|
11370
|
+
const excludeFields = excludeFieldsFor(base.workflowName);
|
|
11371
|
+
const excludeSet = new Set(excludeFields.map((name) => normalizeDetailFieldName(name)));
|
|
11372
|
+
const picked = (internalMessage ? pickInternalMessageFieldPairs(cleanedFields, base) : cleanedFields.filter((field) => !excludeSet.has(normalizeDetailFieldName(field?.fieldName)))).slice(0, DETAIL_MATERIAL_FIELD_LIMIT).map((field) => ({
|
|
11333
11373
|
fieldName: String(field?.fieldName ?? "").trim(),
|
|
11334
|
-
value: String(field?.value ?? "")
|
|
11374
|
+
value: String(field?.value ?? "").slice(0, DETAIL_MATERIAL_VALUE_LIMIT)
|
|
11335
11375
|
})).filter((field) => field.fieldName && field.value);
|
|
11336
11376
|
const metrics = extractRowMetrics(usableFields);
|
|
11337
11377
|
return {
|
|
11338
11378
|
requestId,
|
|
11339
|
-
basicInfo
|
|
11340
|
-
|
|
11341
|
-
|
|
11342
|
-
|
|
11343
|
-
createdAt: String(base.createdAt ?? ""),
|
|
11344
|
-
currentNode: String(base.currentNode ?? ""),
|
|
11345
|
-
requestLevel: String(base.requestLevel ?? ""),
|
|
11346
|
-
flowStatus: String(base.flowStatus ?? "")
|
|
11347
|
-
},
|
|
11348
|
-
summaryFields,
|
|
11349
|
-
contextAvailable: summaryFields.length > 0,
|
|
11379
|
+
basicInfo,
|
|
11380
|
+
formFields: picked,
|
|
11381
|
+
contextAvailable: picked.length > 0,
|
|
11382
|
+
excludeTag: excludeTagOf(excludeFields),
|
|
11350
11383
|
metrics
|
|
11351
11384
|
};
|
|
11352
11385
|
}
|
|
@@ -11398,17 +11431,10 @@ async function fetchRequestDetailsBatch(env, requestIds, options = {}) {
|
|
|
11398
11431
|
failures.push({ requestId, error: reason });
|
|
11399
11432
|
details.set(requestId, {
|
|
11400
11433
|
requestId,
|
|
11401
|
-
basicInfo: {
|
|
11402
|
-
|
|
11403
|
-
workflowName: "",
|
|
11404
|
-
creatorName: "",
|
|
11405
|
-
createdAt: "",
|
|
11406
|
-
currentNode: "",
|
|
11407
|
-
requestLevel: "",
|
|
11408
|
-
flowStatus: ""
|
|
11409
|
-
},
|
|
11410
|
-
summaryFields: [],
|
|
11434
|
+
basicInfo: {},
|
|
11435
|
+
formFields: [],
|
|
11411
11436
|
contextAvailable: false,
|
|
11437
|
+
excludeTag: "",
|
|
11412
11438
|
metrics: {},
|
|
11413
11439
|
error: reason
|
|
11414
11440
|
});
|
|
@@ -11431,90 +11457,11 @@ async function fetchRequestDetailsBatch(env, requestIds, options = {}) {
|
|
|
11431
11457
|
};
|
|
11432
11458
|
}
|
|
11433
11459
|
|
|
11434
|
-
// src/shortcuts/workflow/operations/todoSmartConvert/todoDetailCache.ts
|
|
11435
|
-
var DETAIL_CACHE_FILE_NAME = "todo-detail-cache.json";
|
|
11436
|
-
var DETAIL_CACHE_TTL_MS = SUMMARY_CACHE_TTL_MS;
|
|
11437
|
-
var DETAIL_CACHE_PRUNE_INTERVAL_MS = SUMMARY_CACHE_PRUNE_INTERVAL_MS;
|
|
11438
|
-
function detailCacheKey(requestId, lastFeedBackDateTime) {
|
|
11439
|
-
const stamp = String(lastFeedBackDateTime ?? "").trim();
|
|
11440
|
-
return `${requestId}__${stamp}`;
|
|
11441
|
-
}
|
|
11442
|
-
function normalizeEntry(raw) {
|
|
11443
|
-
if (!raw || typeof raw !== "object") return null;
|
|
11444
|
-
const value = raw;
|
|
11445
|
-
if (typeof value.cachedAt !== "number" || !Number.isFinite(value.cachedAt)) return null;
|
|
11446
|
-
if (typeof value.context !== "string") return null;
|
|
11447
|
-
const fields = Array.isArray(value.fields) ? value.fields.filter((item) => Boolean(item) && typeof item.fieldName === "string" && typeof item.value === "string").map((item) => ({ fieldName: item.fieldName, value: item.value })) : [];
|
|
11448
|
-
const metrics = value.metrics && typeof value.metrics === "object" ? value.metrics : {};
|
|
11449
|
-
return {
|
|
11450
|
-
context: value.context,
|
|
11451
|
-
contextAvailable: value.contextAvailable === true,
|
|
11452
|
-
metrics,
|
|
11453
|
-
fields,
|
|
11454
|
-
cachedAt: value.cachedAt
|
|
11455
|
-
};
|
|
11456
|
-
}
|
|
11457
|
-
async function openDetailCache(ctx) {
|
|
11458
|
-
const roots = cacheRoots(ctx);
|
|
11459
|
-
const stored = await readCacheFile(roots, DETAIL_CACHE_FILE_NAME);
|
|
11460
|
-
const now = Date.now();
|
|
11461
|
-
const entries = /* @__PURE__ */ new Map();
|
|
11462
|
-
let prunedAt = 0;
|
|
11463
|
-
let loaded = 0;
|
|
11464
|
-
let pruned = 0;
|
|
11465
|
-
if (stored) {
|
|
11466
|
-
try {
|
|
11467
|
-
const parsed = JSON.parse(stored.text);
|
|
11468
|
-
prunedAt = typeof parsed.prunedAt === "number" ? parsed.prunedAt : 0;
|
|
11469
|
-
for (const [key, raw] of Object.entries(parsed.entries ?? {})) {
|
|
11470
|
-
const entry = normalizeEntry(raw);
|
|
11471
|
-
if (!entry) continue;
|
|
11472
|
-
if (now - entry.cachedAt > DETAIL_CACHE_TTL_MS) {
|
|
11473
|
-
pruned += 1;
|
|
11474
|
-
continue;
|
|
11475
|
-
}
|
|
11476
|
-
entries.set(key, entry);
|
|
11477
|
-
loaded += 1;
|
|
11478
|
-
}
|
|
11479
|
-
} catch {
|
|
11480
|
-
}
|
|
11481
|
-
}
|
|
11482
|
-
const cache = {
|
|
11483
|
-
file: stored?.file ?? null,
|
|
11484
|
-
pruned: 0,
|
|
11485
|
-
loaded,
|
|
11486
|
-
get(requestId, lastFeedBackDateTime) {
|
|
11487
|
-
const entry = entries.get(detailCacheKey(requestId, lastFeedBackDateTime));
|
|
11488
|
-
if (!entry) return null;
|
|
11489
|
-
if (Date.now() - entry.cachedAt > DETAIL_CACHE_TTL_MS) return null;
|
|
11490
|
-
return entry;
|
|
11491
|
-
},
|
|
11492
|
-
has(requestId, lastFeedBackDateTime) {
|
|
11493
|
-
return cache.get(requestId, lastFeedBackDateTime) !== null;
|
|
11494
|
-
},
|
|
11495
|
-
set(requestId, lastFeedBackDateTime, entry) {
|
|
11496
|
-
if (!requestId) return false;
|
|
11497
|
-
entries.set(detailCacheKey(requestId, lastFeedBackDateTime), { ...entry, cachedAt: Date.now() });
|
|
11498
|
-
return true;
|
|
11499
|
-
},
|
|
11500
|
-
async save() {
|
|
11501
|
-
const shouldPrune = pruned > 0 && Date.now() - prunedAt > DETAIL_CACHE_PRUNE_INTERVAL_MS;
|
|
11502
|
-
const payload = {
|
|
11503
|
-
prunedAt: shouldPrune ? Date.now() : prunedAt,
|
|
11504
|
-
entries: Object.fromEntries(entries)
|
|
11505
|
-
};
|
|
11506
|
-
const file = await writeCacheFile(roots, DETAIL_CACHE_FILE_NAME, JSON.stringify(payload));
|
|
11507
|
-
if (file) cache.file = file;
|
|
11508
|
-
if (shouldPrune) cache.pruned = pruned;
|
|
11509
|
-
return file;
|
|
11510
|
-
}
|
|
11511
|
-
};
|
|
11512
|
-
return cache;
|
|
11513
|
-
}
|
|
11514
|
-
|
|
11515
11460
|
// src/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.detail.ts
|
|
11516
11461
|
function contextOfDetail(detail) {
|
|
11517
|
-
|
|
11462
|
+
const basicLines = Object.entries(detail.basicInfo ?? {}).filter(([, value]) => String(value ?? "").trim() !== "").map(([key, value]) => `${key}:${String(value).trim()}`);
|
|
11463
|
+
const fieldLines = (detail.formFields ?? []).map((field) => `${field.fieldName}:${field.value}`);
|
|
11464
|
+
return [...basicLines, ...fieldLines].join("\n");
|
|
11518
11465
|
}
|
|
11519
11466
|
var EMPTY_DETAIL_STATS = {
|
|
11520
11467
|
requested: 0,
|
|
@@ -11526,8 +11473,6 @@ var EMPTY_DETAIL_STATS = {
|
|
|
11526
11473
|
concurrency: 0,
|
|
11527
11474
|
durationMs: 0
|
|
11528
11475
|
};
|
|
11529
|
-
var DETAIL_MATERIAL_FIELD_LIMIT = 8;
|
|
11530
|
-
var DETAIL_MATERIAL_VALUE_LIMIT = 80;
|
|
11531
11476
|
function stampsOfRows(rows) {
|
|
11532
11477
|
const stamps = /* @__PURE__ */ new Map();
|
|
11533
11478
|
for (const row of rows) {
|
|
@@ -11540,7 +11485,7 @@ function stampsOfRows(rows) {
|
|
|
11540
11485
|
return stamps;
|
|
11541
11486
|
}
|
|
11542
11487
|
function materialFieldsOf(detail) {
|
|
11543
|
-
return detail.
|
|
11488
|
+
return detail.formFields.map((field) => ({ fieldName: field.fieldName, value: field.value }));
|
|
11544
11489
|
}
|
|
11545
11490
|
async function fetchDetailFacts(env, requestIds, args, stamps) {
|
|
11546
11491
|
const unique = [...new Set(requestIds.filter(Boolean))];
|
|
@@ -11554,13 +11499,13 @@ async function fetchDetailFacts(env, requestIds, args, stamps) {
|
|
|
11554
11499
|
const missing = [];
|
|
11555
11500
|
for (const requestId of unique) {
|
|
11556
11501
|
const hit = cache.get(requestId, stamps?.get(requestId));
|
|
11557
|
-
if (!hit) {
|
|
11502
|
+
if (!hit || hit.excludeTag !== excludeTagFor(hit.basicInfo.workflowName ?? "")) {
|
|
11558
11503
|
missing.push(requestId);
|
|
11559
11504
|
continue;
|
|
11560
11505
|
}
|
|
11561
11506
|
facts.set(requestId, {
|
|
11562
|
-
context: hit.
|
|
11563
|
-
contextAvailable: hit.
|
|
11507
|
+
context: contextOfDetail({ basicInfo: hit.basicInfo, formFields: hit.fields }),
|
|
11508
|
+
contextAvailable: hit.fields.length > 0,
|
|
11564
11509
|
metrics: hit.metrics,
|
|
11565
11510
|
fields: hit.fields
|
|
11566
11511
|
});
|
|
@@ -11578,7 +11523,7 @@ async function fetchDetailFacts(env, requestIds, args, stamps) {
|
|
|
11578
11523
|
for (const [requestId, detail] of details) {
|
|
11579
11524
|
const fact = {
|
|
11580
11525
|
context: contextOfDetail(detail),
|
|
11581
|
-
contextAvailable: detail.
|
|
11526
|
+
contextAvailable: detail.formFields.length > 0,
|
|
11582
11527
|
metrics: detail.metrics ?? {},
|
|
11583
11528
|
fields: materialFieldsOf(detail)
|
|
11584
11529
|
};
|
|
@@ -11587,10 +11532,11 @@ async function fetchDetailFacts(env, requestIds, args, stamps) {
|
|
|
11587
11532
|
if (fact.contextAvailable) stats.contextAvailable += 1;
|
|
11588
11533
|
else stats.contextEmpty += 1;
|
|
11589
11534
|
if (cache.set(requestId, stamps?.get(requestId), {
|
|
11590
|
-
|
|
11591
|
-
|
|
11535
|
+
v: DETAIL_CACHE_ENTRY_VERSION,
|
|
11536
|
+
basicInfo: detail.basicInfo,
|
|
11592
11537
|
metrics: fact.metrics,
|
|
11593
|
-
fields: fact.fields
|
|
11538
|
+
fields: fact.fields,
|
|
11539
|
+
excludeTag: detail.excludeTag
|
|
11594
11540
|
})) written += 1;
|
|
11595
11541
|
}
|
|
11596
11542
|
} catch (error) {
|
|
@@ -12071,16 +12017,32 @@ async function collectRawTodos(args, env) {
|
|
|
12071
12017
|
});
|
|
12072
12018
|
wfIdGroup = grouped.wfIdGroup ?? [];
|
|
12073
12019
|
const summaryCache = await openSummaryCache(env.ctx);
|
|
12074
|
-
const
|
|
12075
|
-
|
|
12076
|
-
"
|
|
12077
|
-
|
|
12078
|
-
|
|
12079
|
-
|
|
12080
|
-
|
|
12020
|
+
const collectMaxCharsByGroup = /* @__PURE__ */ new Map();
|
|
12021
|
+
const collectMaxCharsFor = (workflowName) => {
|
|
12022
|
+
const key = workflowName ?? "";
|
|
12023
|
+
const hit = collectMaxCharsByGroup.get(key);
|
|
12024
|
+
if (hit !== void 0) return hit;
|
|
12025
|
+
const value = readBoundedInt(
|
|
12026
|
+
args.summaryMaxChars ?? activeRuleFor(key)?.summaryMaxChars,
|
|
12027
|
+
"summaryMaxChars",
|
|
12028
|
+
DEFAULT_REQUEST_SUMMARY_MAX,
|
|
12029
|
+
10,
|
|
12030
|
+
500
|
|
12031
|
+
);
|
|
12032
|
+
collectMaxCharsByGroup.set(key, value);
|
|
12033
|
+
return value;
|
|
12034
|
+
};
|
|
12081
12035
|
const cachedSummaryIds = /* @__PURE__ */ new Set();
|
|
12036
|
+
const detailCacheForTag = await openDetailCache(env.ctx);
|
|
12082
12037
|
for (const row of items) {
|
|
12083
|
-
const
|
|
12038
|
+
const detailEntry = detailCacheForTag.get(row.requestId, row.lastFeedBackDateTime);
|
|
12039
|
+
const cached = summaryCache.get(
|
|
12040
|
+
row.requestId,
|
|
12041
|
+
row.lastFeedBackDateTime,
|
|
12042
|
+
collectMaxCharsFor(row.workflowName),
|
|
12043
|
+
promptTagOf(activeRuleFor(row.workflowName ?? "")?.requestSummaryPrompt ?? ""),
|
|
12044
|
+
detailEntry ? detailMaterialTagOf(detailEntry) : void 0
|
|
12045
|
+
);
|
|
12084
12046
|
if (!cached) continue;
|
|
12085
12047
|
row.summary = cached;
|
|
12086
12048
|
cachedSummaryIds.add(row.requestId);
|
|
@@ -12157,7 +12119,7 @@ async function collectRawTodos(args, env) {
|
|
|
12157
12119
|
}
|
|
12158
12120
|
if (!summaryCache.inSkillDir) {
|
|
12159
12121
|
warnings.push(
|
|
12160
|
-
"\
|
|
12122
|
+
"\u65E0\u5F53\u524D skill \u4E0A\u4E0B\u6587\uFF08WEAVER_WORK_CLI_SKILL_DIR \u672A\u8BBE\u7F6E\uFF09\uFF1A\u6458\u8981\u7F13\u5B58\u4E0E aigroup \u89C4\u5219\u5747\u672A\u8BFB\u5199\uFF0C\u672C\u6B21\u6309\u300C\u4ECE\u672A\u751F\u6210\u8FC7\u300D\u8D70\u5B9E\u65F6\u903B\u8F91\uFF1B\u8BF7\u7ECF skill \u7684 tools \u811A\u672C\u8C03\u7528"
|
|
12161
12123
|
);
|
|
12162
12124
|
}
|
|
12163
12125
|
}
|
|
@@ -12444,12 +12406,23 @@ async function runSmartGroup(args, env, options = {}) {
|
|
|
12444
12406
|
);
|
|
12445
12407
|
const skipDetail = args.withDetailContext === false;
|
|
12446
12408
|
const summaryCache = await openSummaryCache(env.ctx);
|
|
12409
|
+
const detailCacheForTag = skipDetail ? null : await openDetailCache(env.ctx);
|
|
12410
|
+
const materialTagOfRow = (requestId, stamp) => {
|
|
12411
|
+
const entry = detailCacheForTag?.get(requestId, stamp);
|
|
12412
|
+
return entry ? detailMaterialTagOf(entry) : void 0;
|
|
12413
|
+
};
|
|
12447
12414
|
const cachedIds = /* @__PURE__ */ new Set();
|
|
12448
12415
|
const allRows = [];
|
|
12449
12416
|
for (const group of groups) {
|
|
12450
12417
|
for (const row of group.requestDatas ?? []) {
|
|
12451
12418
|
allRows.push(row);
|
|
12452
|
-
if (summaryCache.get(
|
|
12419
|
+
if (summaryCache.get(
|
|
12420
|
+
row.requestId,
|
|
12421
|
+
row.lastFeedBackDateTime,
|
|
12422
|
+
summaryMaxChars,
|
|
12423
|
+
promptTagOf(activeRuleFor(group.title)?.requestSummaryPrompt ?? ""),
|
|
12424
|
+
materialTagOfRow(row.requestId, row.lastFeedBackDateTime)
|
|
12425
|
+
)) cachedIds.add(row.requestId);
|
|
12453
12426
|
}
|
|
12454
12427
|
}
|
|
12455
12428
|
const detailIds = [...new Set(allRows.map((row) => row.requestId).filter(Boolean))];
|
|
@@ -12699,6 +12672,21 @@ async function runSmartGroup(args, env, options = {}) {
|
|
|
12699
12672
|
function needAiSummary(workflowName) {
|
|
12700
12673
|
return activeRuleFor(workflowName)?.needSummary ?? true;
|
|
12701
12674
|
}
|
|
12675
|
+
function requestMaxCharsFor(args, workflowName) {
|
|
12676
|
+
return readBoundedInt(
|
|
12677
|
+
args.summaryMaxChars ?? activeRuleFor(workflowName)?.summaryMaxChars,
|
|
12678
|
+
"summaryMaxChars",
|
|
12679
|
+
DEFAULT_REQUEST_SUMMARY_MAX3,
|
|
12680
|
+
10,
|
|
12681
|
+
500
|
|
12682
|
+
);
|
|
12683
|
+
}
|
|
12684
|
+
function requestPromptFor(workflowName) {
|
|
12685
|
+
return (activeRuleFor(workflowName)?.requestSummaryPrompt ?? "").trim();
|
|
12686
|
+
}
|
|
12687
|
+
function distinctBatchMaxChars(batches) {
|
|
12688
|
+
return [...new Set(batches.map((batch) => batch.suggestedMaxChars))].sort((left, right) => left - right);
|
|
12689
|
+
}
|
|
12702
12690
|
var DEFAULT_MAX_CHARS_PER_BATCH = 24e3;
|
|
12703
12691
|
var DEFAULT_MAX_ITEMS_PER_BATCH = 100;
|
|
12704
12692
|
var DEFAULT_REQUEST_SUMMARY_MAX3 = 50;
|
|
@@ -12869,20 +12857,35 @@ async function runSummaryContext(args, env, prefetched) {
|
|
|
12869
12857
|
const units = collectSummaryUnits(groups);
|
|
12870
12858
|
const skippedSatisfaction = groups.filter((group) => !needAiSummary(group.title)).reduce((sum, group) => sum + rowsOfGroup(group).length, 0);
|
|
12871
12859
|
const requestIds = [...new Set(units.flatMap((unit) => unit.rows.map((row) => row.requestId)))].filter(Boolean);
|
|
12872
|
-
const summaryMaxChars = readBoundedInt(
|
|
12873
|
-
args.summaryMaxChars,
|
|
12874
|
-
"summaryMaxChars",
|
|
12875
|
-
DEFAULT_REQUEST_SUMMARY_MAX3,
|
|
12876
|
-
10,
|
|
12877
|
-
500
|
|
12878
|
-
);
|
|
12879
12860
|
const summaryCache = await openSummaryCache(env.ctx);
|
|
12861
|
+
const detailCacheForTag = await openDetailCache(env.ctx);
|
|
12862
|
+
const materialTagOfRow = (requestId, stamp) => {
|
|
12863
|
+
const entry = detailCacheForTag.get(requestId, stamp);
|
|
12864
|
+
return entry ? detailMaterialTagOf(entry) : void 0;
|
|
12865
|
+
};
|
|
12880
12866
|
let prefilled = 0;
|
|
12881
12867
|
const prefilledIds = /* @__PURE__ */ new Set();
|
|
12882
12868
|
const needsDetail = [];
|
|
12869
|
+
const workflowTitleByRequest = /* @__PURE__ */ new Map();
|
|
12883
12870
|
for (const unit of units) {
|
|
12871
|
+
if (unit.groupId === "priority") continue;
|
|
12884
12872
|
for (const row of unit.rows) {
|
|
12885
|
-
|
|
12873
|
+
if (row.requestId && !workflowTitleByRequest.has(row.requestId)) {
|
|
12874
|
+
workflowTitleByRequest.set(row.requestId, unit.groupTitle);
|
|
12875
|
+
}
|
|
12876
|
+
}
|
|
12877
|
+
}
|
|
12878
|
+
const ruleNameForRow = (unit, row) => unit.groupId === "priority" ? workflowTitleByRequest.get(row.requestId ?? "") ?? unit.groupTitle : unit.groupTitle;
|
|
12879
|
+
for (const unit of units) {
|
|
12880
|
+
for (const row of unit.rows) {
|
|
12881
|
+
const name = ruleNameForRow(unit, row);
|
|
12882
|
+
const cached = summaryCache.get(
|
|
12883
|
+
row.requestId,
|
|
12884
|
+
row.lastFeedBackDateTime,
|
|
12885
|
+
requestMaxCharsFor(args, name),
|
|
12886
|
+
promptTagOf(requestPromptFor(name)),
|
|
12887
|
+
materialTagOfRow(row.requestId, row.lastFeedBackDateTime)
|
|
12888
|
+
);
|
|
12886
12889
|
if (cached) {
|
|
12887
12890
|
row.summary = cached;
|
|
12888
12891
|
prefilled += 1;
|
|
@@ -12901,13 +12904,17 @@ async function runSummaryContext(args, env, prefetched) {
|
|
|
12901
12904
|
let contextEmpty = 0;
|
|
12902
12905
|
let titleCopied = 0;
|
|
12903
12906
|
const claimed = /* @__PURE__ */ new Set();
|
|
12904
|
-
|
|
12907
|
+
const orderedUnits = [...units].sort(
|
|
12908
|
+
(a, b) => Number(a.groupId === "priority") - Number(b.groupId === "priority")
|
|
12909
|
+
);
|
|
12910
|
+
for (const unit of orderedUnits) {
|
|
12905
12911
|
let bucket = [];
|
|
12906
12912
|
let chars = 0;
|
|
12907
12913
|
let seq = 0;
|
|
12908
12914
|
const flush = () => {
|
|
12909
12915
|
if (bucket.length === 0) return;
|
|
12910
12916
|
seq += 1;
|
|
12917
|
+
const firstName = ruleNameForRow(unit, { requestId: bucket[0].requestId });
|
|
12911
12918
|
batches.push({
|
|
12912
12919
|
batchId: `${unit.subGroupId}#${seq}`,
|
|
12913
12920
|
groupId: unit.groupId,
|
|
@@ -12918,7 +12925,8 @@ async function runSummaryContext(args, env, prefetched) {
|
|
|
12918
12925
|
charCount: chars,
|
|
12919
12926
|
kind: unit.kind,
|
|
12920
12927
|
...unit.kind === "internal-message" ? { hint: INTERNAL_MESSAGE_SUMMARY_HINT } : {},
|
|
12921
|
-
|
|
12928
|
+
...requestPromptFor(firstName) ? { prompt: requestPromptFor(firstName) } : {},
|
|
12929
|
+
suggestedMaxChars: requestMaxCharsFor(args, firstName),
|
|
12922
12930
|
items: bucket
|
|
12923
12931
|
});
|
|
12924
12932
|
bucket = [];
|
|
@@ -12989,8 +12997,8 @@ async function runSummaryContext(args, env, prefetched) {
|
|
|
12989
12997
|
titleCopied,
|
|
12990
12998
|
/** 本地摘要命中、跳过 AI 的条数 */
|
|
12991
12999
|
prefilled,
|
|
12992
|
-
/**
|
|
12993
|
-
suggestedMaxChars:
|
|
13000
|
+
/** 单条摘要的目标字数:口径一致时给数字,各组口径不同时给 distinct 列表 */
|
|
13001
|
+
...distinctBatchMaxChars(batches).length === 1 ? { suggestedMaxChars: distinctBatchMaxChars(batches)[0] } : { suggestedMaxCharsList: distinctBatchMaxChars(batches) },
|
|
12994
13002
|
/** 内部留言类批次:摘要要按「最低推理强度」写 */
|
|
12995
13003
|
internalMessageBatches: batches.filter((batch) => batch.kind === "internal-message").length,
|
|
12996
13004
|
skippedSatisfaction,
|
|
@@ -13054,16 +13062,30 @@ function readAiSummaries(value) {
|
|
|
13054
13062
|
async function runSummary(args, env) {
|
|
13055
13063
|
const groups = await readFinalGroups(args, env);
|
|
13056
13064
|
const summaries = readAiSummaries(args.aiSummaries);
|
|
13057
|
-
const
|
|
13058
|
-
|
|
13059
|
-
|
|
13060
|
-
|
|
13061
|
-
|
|
13062
|
-
|
|
13063
|
-
|
|
13065
|
+
const maxCharsByGroup = /* @__PURE__ */ new Map();
|
|
13066
|
+
const maxCharsFor = (workflowName) => {
|
|
13067
|
+
const hit = maxCharsByGroup.get(workflowName);
|
|
13068
|
+
if (hit !== void 0) return hit;
|
|
13069
|
+
const value = requestMaxCharsFor(args, workflowName);
|
|
13070
|
+
maxCharsByGroup.set(workflowName, value);
|
|
13071
|
+
return value;
|
|
13072
|
+
};
|
|
13064
13073
|
const summaryCache = await openSummaryCache(env.ctx);
|
|
13074
|
+
const detailCacheForTag = await openDetailCache(env.ctx);
|
|
13075
|
+
const materialTagOfRow = (requestId, stamp) => {
|
|
13076
|
+
const entry = detailCacheForTag.get(requestId, stamp);
|
|
13077
|
+
return entry ? detailMaterialTagOf(entry) : void 0;
|
|
13078
|
+
};
|
|
13065
13079
|
let cacheWritten = 0;
|
|
13066
13080
|
let titleSummary = 0;
|
|
13081
|
+
const wfTitleByRequest = /* @__PURE__ */ new Map();
|
|
13082
|
+
for (const group of groups) {
|
|
13083
|
+
if (group.topPriority) continue;
|
|
13084
|
+
for (const row of rowsOfGroup(group)) {
|
|
13085
|
+
if (row?.requestId && !wfTitleByRequest.has(row.requestId)) wfTitleByRequest.set(row.requestId, group.title);
|
|
13086
|
+
}
|
|
13087
|
+
}
|
|
13088
|
+
const ruleNameForGroup = (group, row) => group.topPriority ? wfTitleByRequest.get(row?.requestId ?? "") ?? group.title : group.title;
|
|
13067
13089
|
for (const group of groups) {
|
|
13068
13090
|
if (!needAiSummary(group.title)) {
|
|
13069
13091
|
for (const row of rowsOfGroup(group)) {
|
|
@@ -13075,7 +13097,14 @@ async function runSummary(args, env) {
|
|
|
13075
13097
|
}
|
|
13076
13098
|
for (const row of rowsOfGroup(group)) {
|
|
13077
13099
|
if (!row?.requestId || (row.summary ?? "").trim()) continue;
|
|
13078
|
-
const
|
|
13100
|
+
const name = ruleNameForGroup(group, row);
|
|
13101
|
+
const cached = summaryCache.get(
|
|
13102
|
+
row.requestId,
|
|
13103
|
+
row.lastFeedBackDateTime,
|
|
13104
|
+
maxCharsFor(name),
|
|
13105
|
+
promptTagOf(requestPromptFor(name)),
|
|
13106
|
+
materialTagOfRow(row.requestId, row.lastFeedBackDateTime)
|
|
13107
|
+
);
|
|
13079
13108
|
if (cached) {
|
|
13080
13109
|
row.summary = cached;
|
|
13081
13110
|
}
|
|
@@ -13103,7 +13132,7 @@ async function runSummary(args, env) {
|
|
|
13103
13132
|
let titleKept = 0;
|
|
13104
13133
|
let prefilledKept = 0;
|
|
13105
13134
|
const countedIds = /* @__PURE__ */ new Set();
|
|
13106
|
-
const applyAll = (rows) => {
|
|
13135
|
+
const applyAll = (rows, meta) => {
|
|
13107
13136
|
for (const row of rows) {
|
|
13108
13137
|
const summary = summaries.get(row.requestId) ?? "";
|
|
13109
13138
|
const firstTime = !row.requestId || !countedIds.has(row.requestId);
|
|
@@ -13118,9 +13147,9 @@ async function runSummary(args, env) {
|
|
|
13118
13147
|
if (summary) {
|
|
13119
13148
|
if (firstTime) {
|
|
13120
13149
|
filled += 1;
|
|
13121
|
-
if (summary.length >
|
|
13150
|
+
if (summary.length > meta(row).maxChars) tooLong += 1;
|
|
13122
13151
|
}
|
|
13123
|
-
if (summaryCache.set(row.requestId, row.lastFeedBackDateTime, summary,
|
|
13152
|
+
if (summaryCache.set(row.requestId, row.lastFeedBackDateTime, summary, meta(row).maxChars, meta(row).pk, materialTagOfRow(row.requestId, row.lastFeedBackDateTime))) cacheWritten += 1;
|
|
13124
13153
|
} else if (firstTime) {
|
|
13125
13154
|
empty += 1;
|
|
13126
13155
|
}
|
|
@@ -13130,17 +13159,28 @@ async function runSummary(args, env) {
|
|
|
13130
13159
|
for (const group of groups) {
|
|
13131
13160
|
if (!needAiSummary(group.title)) continue;
|
|
13132
13161
|
if (group.topPriority) {
|
|
13133
|
-
applyAll(rowsOfGroup(group))
|
|
13162
|
+
applyAll(rowsOfGroup(group), (row) => {
|
|
13163
|
+
const name = ruleNameForGroup(group, row);
|
|
13164
|
+
return { maxChars: maxCharsFor(name), pk: promptTagOf(requestPromptFor(name)) };
|
|
13165
|
+
});
|
|
13134
13166
|
continue;
|
|
13135
13167
|
}
|
|
13136
13168
|
for (const item of group.displayItems) {
|
|
13137
13169
|
if (item.type === "group") {
|
|
13138
|
-
applyAll(item.requestDatas)
|
|
13170
|
+
applyAll(item.requestDatas, (row) => {
|
|
13171
|
+
const name = ruleNameForGroup(group, row);
|
|
13172
|
+
return { maxChars: maxCharsFor(name), pk: promptTagOf(requestPromptFor(name)) };
|
|
13173
|
+
});
|
|
13139
13174
|
continue;
|
|
13140
13175
|
}
|
|
13141
|
-
applyAll([item.requestData])
|
|
13176
|
+
applyAll([item.requestData], (row) => {
|
|
13177
|
+
const name = ruleNameForGroup(group, row);
|
|
13178
|
+
return { maxChars: maxCharsFor(name), pk: promptTagOf(requestPromptFor(name)) };
|
|
13179
|
+
});
|
|
13142
13180
|
}
|
|
13143
13181
|
}
|
|
13182
|
+
const usedMaxChars = [...new Set(maxCharsByGroup.values())].sort((left, right) => left - right);
|
|
13183
|
+
const maxCharsHint = usedMaxChars.length > 0 ? usedMaxChars.join("/") : String(DEFAULT_REQUEST_SUMMARY_MAX3);
|
|
13144
13184
|
if (empty > 0) {
|
|
13145
13185
|
warnings.push(`\u6709 ${empty} \u6761\u6CA1\u6709\u62FF\u5230 AI \u6458\u8981\uFF0Csummary \u4FDD\u6301\u7A7A\u4E32\uFF08\u672A\u7528\u6807\u9898\u515C\u5E95\u3001\u672A\u7F16\u9020\uFF09`);
|
|
13146
13186
|
}
|
|
@@ -13149,7 +13189,7 @@ async function runSummary(args, env) {
|
|
|
13149
13189
|
}
|
|
13150
13190
|
if (tooLong > 0) {
|
|
13151
13191
|
warnings.push(
|
|
13152
|
-
`\u6709 ${tooLong} \u6761\u6458\u8981\u8D85\u8FC7\u76EE\u6807\u957F\u5EA6 ${
|
|
13192
|
+
`\u6709 ${tooLong} \u6761\u6458\u8981\u8D85\u8FC7\u76EE\u6807\u957F\u5EA6 ${maxCharsHint} \u5B57\uFF08\u53EF\u6309\u7528\u6237\u53E3\u5F84\u8C03\u6574\uFF09\uFF0C\u5DF2\u539F\u6837\u4FDD\u7559\uFF1B\u5982\u9700\u63A7\u5236\u957F\u5EA6\u8BF7\u91CD\u8DD1\u6A21\u578B\u4FA7\uFF08CLI \u4E0D\u6539\u5199\u6587\u6848\uFF09`
|
|
13153
13193
|
);
|
|
13154
13194
|
}
|
|
13155
13195
|
if (prefilledKept > 0) {
|
|
@@ -13174,8 +13214,8 @@ async function runSummary(args, env) {
|
|
|
13174
13214
|
meta: {
|
|
13175
13215
|
summarized: filled,
|
|
13176
13216
|
empty,
|
|
13177
|
-
/**
|
|
13178
|
-
suggestedMaxChars:
|
|
13217
|
+
/** 单条摘要的目标字数:各组口径一致时给数字,不一致时给 distinct 列表 */
|
|
13218
|
+
...usedMaxChars.length === 1 ? { suggestedMaxChars: usedMaxChars[0] } : { suggestedMaxCharsList: usedMaxChars },
|
|
13179
13219
|
titleCopied: titleKept,
|
|
13180
13220
|
/** 本地摘要缓存命中、未重新生成的条数 */
|
|
13181
13221
|
prefilled: prefilledKept,
|
|
@@ -13194,6 +13234,22 @@ async function runSummary(args, env) {
|
|
|
13194
13234
|
var INTERNAL_MESSAGE_SUMMARY_HINT2 = "\u5185\u90E8\u7559\u8A00\uFF1A\u53EA\u6309\u539F\u6587\u76F4\u63A5\u6982\u62EC\u300C\u8C01\u8BF4\u4E86\u4EC0\u4E48\u300D\uFF0C\u4E0D\u8981\u8FC7\u5EA6\u89E3\u8BFB\u3001\u4E0D\u8981\u63A8\u6D4B\u52A8\u673A\u6216\u5F71\u54CD\uFF0C\u4E25\u683C\u6309\u672C\u6279 suggestedMaxChars \u63A7\u5236\u5B57\u6570";
|
|
13195
13235
|
var GROUP_SUMMARY_TAIL = GROUP_SUMMARY_TAIL_TEXT;
|
|
13196
13236
|
var DEFAULT_GROUP_SUMMARY_MAX = 100;
|
|
13237
|
+
function makeGroupMaxCharsResolver(args) {
|
|
13238
|
+
const cache = /* @__PURE__ */ new Map();
|
|
13239
|
+
return (workflowName) => {
|
|
13240
|
+
const hit = cache.get(workflowName);
|
|
13241
|
+
if (hit !== void 0) return hit;
|
|
13242
|
+
const value = readBoundedInt(
|
|
13243
|
+
args.groupSummaryMaxChars ?? activeRuleFor(workflowName)?.groupSummaryMaxChars,
|
|
13244
|
+
"groupSummaryMaxChars",
|
|
13245
|
+
DEFAULT_GROUP_SUMMARY_MAX,
|
|
13246
|
+
20,
|
|
13247
|
+
1e3
|
|
13248
|
+
);
|
|
13249
|
+
cache.set(workflowName, value);
|
|
13250
|
+
return value;
|
|
13251
|
+
};
|
|
13252
|
+
}
|
|
13197
13253
|
var GROUP_AMOUNT_PATTERNS = [
|
|
13198
13254
|
/[¥¥]\s*(\d[\d,]*(?:\.\d{1,2})?)/u,
|
|
13199
13255
|
/(\d[\d,]*(?:\.\d{1,2})?)\s*元/u
|
|
@@ -13212,7 +13268,7 @@ function createrPhraseOf(creators) {
|
|
|
13212
13268
|
if (creators.length <= 3) return `\u7531${creators.join("\u3001")} \u53D1\u8D77`;
|
|
13213
13269
|
return `\u7531${creators.slice(0, 3).join("\u3001")} \u7B49 ${creators.length} \u4EBA\u53D1\u8D77`;
|
|
13214
13270
|
}
|
|
13215
|
-
function collectGroupSummaryBatches(groups, isCtxEmpty,
|
|
13271
|
+
function collectGroupSummaryBatches(groups, isCtxEmpty, maxCharsFor = () => DEFAULT_GROUP_SUMMARY_MAX) {
|
|
13216
13272
|
const batches = [];
|
|
13217
13273
|
for (const group of groups) {
|
|
13218
13274
|
if (group.topPriority) continue;
|
|
@@ -13241,6 +13297,7 @@ function collectGroupSummaryBatches(groups, isCtxEmpty, maxChars = DEFAULT_GROUP
|
|
|
13241
13297
|
if (amount !== null) amounts.push(amount);
|
|
13242
13298
|
}
|
|
13243
13299
|
const amountReliable = items.length >= 2 && amounts.length === items.length;
|
|
13300
|
+
const groupPrompt = (activeRuleFor(group.title)?.aiGroup?.groupSummary?.prompt ?? "").trim();
|
|
13244
13301
|
batches.push({
|
|
13245
13302
|
groupId: sub.id,
|
|
13246
13303
|
parentGroupId: group.id,
|
|
@@ -13250,7 +13307,8 @@ function collectGroupSummaryBatches(groups, isCtxEmpty, maxChars = DEFAULT_GROUP
|
|
|
13250
13307
|
totalCount: allRows.length,
|
|
13251
13308
|
kind,
|
|
13252
13309
|
...kind === "internal-message" ? { hint: INTERNAL_MESSAGE_SUMMARY_HINT2 } : {},
|
|
13253
|
-
|
|
13310
|
+
...groupPrompt ? { prompt: groupPrompt } : {},
|
|
13311
|
+
suggestedMaxChars: maxCharsFor(group.title),
|
|
13254
13312
|
...emptySkipped > 0 ? { emptySkipped } : {},
|
|
13255
13313
|
items,
|
|
13256
13314
|
stats: {
|
|
@@ -13295,14 +13353,9 @@ async function loadCtxEmptyPredicate(env, groups, args = {}) {
|
|
|
13295
13353
|
async function runGroupSummaryContext(args, env) {
|
|
13296
13354
|
const groups = await readFinalGroups(args, env);
|
|
13297
13355
|
const { isCtxEmpty, warnings: emptyWarnings } = await loadCtxEmptyPredicate(env, groups, args);
|
|
13298
|
-
const
|
|
13299
|
-
|
|
13300
|
-
|
|
13301
|
-
DEFAULT_GROUP_SUMMARY_MAX,
|
|
13302
|
-
20,
|
|
13303
|
-
1e3
|
|
13304
|
-
);
|
|
13305
|
-
const batches = collectGroupSummaryBatches(groups, isCtxEmpty, groupSummaryMaxChars);
|
|
13356
|
+
const groupMaxCharsFor = makeGroupMaxCharsResolver(args);
|
|
13357
|
+
const batches = collectGroupSummaryBatches(groups, isCtxEmpty, groupMaxCharsFor);
|
|
13358
|
+
const distinctChars = [...new Set(batches.map((batch) => batch.suggestedMaxChars))].sort((left, right) => left - right);
|
|
13306
13359
|
const totalCount = totalTodoCount(groups);
|
|
13307
13360
|
const warnings = [...emptyWarnings];
|
|
13308
13361
|
const skippedEmpty = batches.reduce((sum, batch) => sum + (batch.emptySkipped ?? 0), 0);
|
|
@@ -13338,7 +13391,7 @@ async function runGroupSummaryContext(args, env) {
|
|
|
13338
13391
|
/** CLI 固定文案的汇总项个数(不进批次,`smartGroup` 阶段已写好) */
|
|
13339
13392
|
deterministicGroups,
|
|
13340
13393
|
tail: GROUP_SUMMARY_TAIL,
|
|
13341
|
-
suggestedMaxChars:
|
|
13394
|
+
...distinctChars.length === 1 ? { suggestedMaxChars: distinctChars[0] } : { suggestedMaxCharsList: distinctChars }
|
|
13342
13395
|
}
|
|
13343
13396
|
},
|
|
13344
13397
|
warnings
|
|
@@ -13389,14 +13442,9 @@ async function runGroupSummary(args, env) {
|
|
|
13389
13442
|
const groups = await readFinalGroups(args, env);
|
|
13390
13443
|
const summaries = readAiGroupSummaries(args.aiGroupSummaries);
|
|
13391
13444
|
const { isCtxEmpty, warnings: emptyWarnings } = await loadCtxEmptyPredicate(env, groups, args);
|
|
13392
|
-
const
|
|
13393
|
-
|
|
13394
|
-
|
|
13395
|
-
DEFAULT_GROUP_SUMMARY_MAX,
|
|
13396
|
-
20,
|
|
13397
|
-
1e3
|
|
13398
|
-
);
|
|
13399
|
-
const batches = collectGroupSummaryBatches(groups, isCtxEmpty, groupSummaryMaxChars);
|
|
13445
|
+
const groupMaxCharsFor = makeGroupMaxCharsResolver(args);
|
|
13446
|
+
const batches = collectGroupSummaryBatches(groups, isCtxEmpty, groupMaxCharsFor);
|
|
13447
|
+
const distinctChars = [...new Set(batches.map((batch) => batch.suggestedMaxChars))].sort((left, right) => left - right);
|
|
13400
13448
|
const knownGroupIds = new Set(batches.map((batch) => batch.groupId));
|
|
13401
13449
|
for (const groupId of summaries.keys()) {
|
|
13402
13450
|
if (!knownGroupIds.has(groupId)) {
|
|
@@ -13417,6 +13465,7 @@ async function runGroupSummary(args, env) {
|
|
|
13417
13465
|
for (const group of groups) {
|
|
13418
13466
|
if (group.topPriority) continue;
|
|
13419
13467
|
const kind = detectBusinessKind(group.title);
|
|
13468
|
+
const groupMaxChars = groupMaxCharsFor(group.title);
|
|
13420
13469
|
for (const sub of groupItemsOf(group)) {
|
|
13421
13470
|
if (isDeterministicGroupKind(kind)) {
|
|
13422
13471
|
if ((sub.summary ?? "").trim() === "") {
|
|
@@ -13428,7 +13477,7 @@ async function runGroupSummary(args, env) {
|
|
|
13428
13477
|
}
|
|
13429
13478
|
filled += 1;
|
|
13430
13479
|
summarizedGroupCount += 1;
|
|
13431
|
-
if (summary2.length >
|
|
13480
|
+
if (summary2.length > groupMaxChars) tooLong += 1;
|
|
13432
13481
|
const batch2 = batches.find((item) => item.groupId === sub.id);
|
|
13433
13482
|
if (batch2 && batch2.stats.createrPhrase && !summary2.includes(batch2.stats.createrPhrase)) {
|
|
13434
13483
|
missingCreater += 1;
|
|
@@ -13447,7 +13496,7 @@ async function runGroupSummary(args, env) {
|
|
|
13447
13496
|
}
|
|
13448
13497
|
filled += 1;
|
|
13449
13498
|
summarizedGroupCount += 1;
|
|
13450
|
-
if (summary.length >
|
|
13499
|
+
if (summary.length > groupMaxChars) tooLong += 1;
|
|
13451
13500
|
const batch = batches.find((item) => item.groupId === sub.id);
|
|
13452
13501
|
if (batch && batch.stats.createrPhrase && !summary.includes(batch.stats.createrPhrase)) {
|
|
13453
13502
|
missingCreater += 1;
|
|
@@ -13456,7 +13505,7 @@ async function runGroupSummary(args, env) {
|
|
|
13456
13505
|
}
|
|
13457
13506
|
if (empty > 0) warnings.push(`\u6709 ${empty} \u4E2A\u6C47\u603B\u9879\u6CA1\u6709\u62FF\u5230\u7EC4\u6458\u8981\uFF0Csummary \u4FDD\u6301\u7A7A\u4E32\uFF08\u672A\u7F16\u9020\uFF09`);
|
|
13458
13507
|
if (tooLong > 0) {
|
|
13459
|
-
warnings.push(`\u6709 ${tooLong} \u4E2A\u7EC4\u6458\u8981\u8D85\u8FC7\u5EFA\u8BAE\u7684 ${
|
|
13508
|
+
warnings.push(`\u6709 ${tooLong} \u4E2A\u7EC4\u6458\u8981\u8D85\u8FC7\u5EFA\u8BAE\u7684 ${distinctChars.length > 0 ? distinctChars.join("/") : DEFAULT_GROUP_SUMMARY_MAX} \u5B57\uFF0C\u5DF2\u539F\u6837\u4FDD\u7559\uFF08CLI \u4E0D\u6539\u5199\u6587\u6848\uFF09`);
|
|
13460
13509
|
}
|
|
13461
13510
|
if (missingCreater > 0) {
|
|
13462
13511
|
warnings.push(
|
|
@@ -13560,8 +13609,10 @@ var inputSchema = schemaOf({
|
|
|
13560
13609
|
groupFocus: { type: "string" },
|
|
13561
13610
|
maxCharsPerBatch: { type: "integer", minimum: 500, maximum: 2e5, default: 24e3 },
|
|
13562
13611
|
maxItemsPerBatch: { type: "integer", minimum: 1, maximum: 500, default: 100 },
|
|
13563
|
-
|
|
13564
|
-
|
|
13612
|
+
// 字数口径不设 schema 默认:默认值来自 aigroup 规则(default.json 的 defaults),
|
|
13613
|
+
// 入参只在用户当轮明确给口径时覆盖规则(2026-10-30 用户要求「摘要规则必须从 JSON 取」)。
|
|
13614
|
+
summaryMaxChars: { type: "integer", minimum: 10, maximum: 500 },
|
|
13615
|
+
groupSummaryMaxChars: { type: "integer", minimum: 20, maximum: 1e3 },
|
|
13565
13616
|
detailConcurrency: { type: "integer", minimum: 1, maximum: 32, default: 10 },
|
|
13566
13617
|
detailTimeoutMs: { type: "integer", minimum: 1e3, maximum: 6e4, default: 1e4 },
|
|
13567
13618
|
skillTiming: { type: "object" },
|