weaver-work-cli 0.1.36 → 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-XBVH7JU7.js → archive-ENZYBBME.js} +559 -68
- package/dist/chunks/{archive-oa-MZM3EKFQ.js → archive-oa-YWLEC5V4.js} +4 -3
- package/dist/chunks/{asset-4XO7UOUW.js → asset-OOV6DWPA.js} +8 -7
- package/dist/chunks/asset-idle-RE632MY5.js +670 -0
- package/dist/chunks/{attachment-content-VXSWANAC.js → attachment-content-RWN2FCLL.js} +3 -3
- package/dist/chunks/{blog-PGZKOPSC.js → blog-PEPOJAL7.js} +5 -4
- package/dist/chunks/{caizhilian-BH4ZVGUN.js → caizhilian-WYIQDVPJ.js} +5 -4
- package/dist/chunks/{calendar-MXEMTIO4.js → calendar-CIARBAOX.js} +4 -3
- package/dist/chunks/{chunk-NCOVUAZK.js → chunk-36DIFZAH.js} +4 -3
- package/dist/chunks/{chunk-I6QGIBDM.js → chunk-BJGXMFGD.js} +4 -3
- package/dist/chunks/{chunk-TC6MZAO3.js → chunk-CQHGNCK2.js} +52 -2
- package/dist/chunks/{chunk-WXFPWCXG.js → chunk-EINRJHQ3.js} +3 -3
- package/dist/chunks/{chunk-JUXVYKII.js → chunk-EZGFHJFW.js} +201 -19
- package/dist/chunks/{chunk-VPUTVEMC.js → chunk-F2EQXUEE.js} +436 -290
- package/dist/chunks/{chunk-JYKABYCV.js → chunk-GVPJZXJ2.js} +3 -3
- package/dist/chunks/{chunk-6LLJFKJE.js → chunk-HJYVHXUQ.js} +1 -1
- package/dist/chunks/{chunk-T72N74ZT.js → chunk-I2HB737U.js} +5 -4
- package/dist/chunks/{chunk-VPXOPQJI.js → chunk-K3RUEEOL.js} +4 -2
- package/dist/chunks/{chunk-HXJQI5NM.js → chunk-KTCB5R5H.js} +3 -2
- package/dist/chunks/{chunk-XMGSYD6S.js → chunk-L4N7B7ZD.js} +4 -4
- package/dist/chunks/{chunk-QYGO5EE2.js → chunk-MUQUHKPG.js} +4 -3
- package/dist/chunks/{chunk-QHFANTX7.js → chunk-NLK2RZKG.js} +1348 -90
- package/dist/chunks/{chunk-F746NKNF.js → chunk-P2DAISYW.js} +1 -1
- package/dist/chunks/{chunk-BPE37FPB.js → chunk-T7JDJJ7H.js} +3 -3
- package/dist/chunks/{chunk-JNG42JKG.js → chunk-XXJOSZTQ.js} +6 -6
- package/dist/chunks/{chunk-5DQEEGCC.js → chunk-YS5DPN4T.js} +1 -1
- package/dist/chunks/{chunk-EG6ZU444.js → chunk-ZUX3P6BQ.js} +10 -5
- package/dist/chunks/{chunk-JCSN3JGM.js → chunk-ZXRNHZTE.js} +7 -6
- package/dist/chunks/{conflict-JAB2LJEZ.js → conflict-DRMDOL56.js} +2 -2
- package/dist/chunks/{contract-XI2EEIZU.js → contract-73MERZWN.js} +4 -3
- package/dist/chunks/{cowork-SCPGLBA4.js → cowork-HNGBPD7A.js} +4 -3
- package/dist/chunks/{ebuilder-form-EYLHNOTA.js → ebuilder-form-OY6DVNRK.js} +3 -3
- package/dist/chunks/{ehr-EAP77IMT.js → ehr-RAQNEQO7.js} +4 -3
- package/dist/chunks/{esb-2TGGXEE7.js → esb-6XV7C7YV.js} +4 -4
- package/dist/chunks/{fna-2X7ZE7BU.js → fna-XTSRB7G7.js} +4 -3
- package/dist/chunks/{host-Q4LZGCRU.js → host-3F5UM5GN.js} +3 -3
- package/dist/chunks/{host-XCLDDXKQ.js → host-A7J6GDUP.js} +3 -3
- package/dist/chunks/{host-I4NRK4MX.js → host-VGPVP7YF.js} +3 -3
- package/dist/chunks/{host-C6EL2RKL.js → host-YAQAPYNP.js} +3 -3
- package/dist/chunks/{host-UEI5FGDM.js → host-YMBXWFWX.js} +3 -3
- package/dist/chunks/{hrm-YXERJM76.js → hrm-TLHKC545.js} +3 -3
- package/dist/chunks/{im-A4VZN2TQ.js → im-YOUCFMUK.js} +3 -3
- package/dist/chunks/{invoice-2Z6YPMIS.js → invoice-WNBS2B4C.js} +3 -3
- package/dist/chunks/{jiuchuanhui-AR5GMKZB.js → jiuchuanhui-XABWS5RN.js} +4 -3
- package/dist/chunks/{lazy-dispatch-QXW7P4X3.js → lazy-dispatch-NLZ5UQQI.js} +5 -5
- package/dist/chunks/{mail-7GZ6CPBJ.js → mail-LRYMBFNL.js} +4 -3
- package/dist/chunks/{meeting-3NMGA3MB.js → meeting-ESXL6MFI.js} +13 -12
- package/dist/chunks/{okr-BZ6XUOAG.js → okr-EOV65SSF.js} +4 -3
- package/dist/chunks/{plan-DR5CMUYP.js → plan-YFPVKW6Y.js} +4 -3
- package/dist/chunks/{project-6J63MK33.js → project-MDVZUYQW.js} +4 -3
- package/dist/chunks/{registry-VRTNC6UR.js → registry-QCLZEDAP.js} +8 -8
- package/dist/chunks/{registry-KDD7DHNK.js → registry-VT5Y2HLA.js} +4 -4
- package/dist/chunks/{registry-TKX2E7C7.js → registry-YX4CSEMD.js} +3 -3
- package/dist/chunks/{room-recommend-XCWRMB5P.js → room-recommend-L3MWH4JW.js} +4 -4
- package/dist/chunks/{schedule-IVBICP32.js → schedule-UASAVDVD.js} +4 -4
- package/dist/chunks/{workflow-D74NFK3C.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 +127 -7
- package/dist/internal/e10/client.js +16 -2
- package/dist/internal/e10/context.js +16 -3
- package/dist/internal/e10/request-runtime.js +106 -8
- package/dist/shortcuts/archive/host.js +5 -2
- 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/archive-oa/host.js +2 -1
- package/dist/shortcuts/asset/host.js +6 -5
- 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/blog/host.js +3 -2
- package/dist/shortcuts/caizhilian/host.js +3 -2
- package/dist/shortcuts/calendar/host.js +2 -1
- package/dist/shortcuts/contract/host.js +2 -1
- package/dist/shortcuts/cowork/host.js +2 -1
- package/dist/shortcuts/ebuilder-form/host.js +3 -1
- package/dist/shortcuts/ehr/host.js +2 -1
- package/dist/shortcuts/esb/host.js +2 -1
- package/dist/shortcuts/fna/host.js +2 -1
- package/dist/shortcuts/hrm/host.js +2 -1
- package/dist/shortcuts/im/host.js +3 -2
- package/dist/shortcuts/index.js +5 -0
- package/dist/shortcuts/invoice/host.js +5 -4
- package/dist/shortcuts/jiuchuanhui/host.js +2 -1
- package/dist/shortcuts/mail/host.js +2 -1
- package/dist/shortcuts/meeting/host.js +3 -2
- package/dist/shortcuts/meeting/invitation/text.js +71 -0
- package/dist/shortcuts/meeting/operations/eb/create-flow.js +1073 -50
- package/dist/shortcuts/meeting/operations/eb/crm-search.js +478 -0
- package/dist/shortcuts/meeting/operations/eb/factory.js +60 -1
- package/dist/shortcuts/meeting/operations/eb/index.js +2 -0
- package/dist/shortcuts/meeting/operations/invitation.js +122 -9
- package/dist/shortcuts/okr/host.js +2 -1
- package/dist/shortcuts/plan/host.js +2 -1
- package/dist/shortcuts/project/host.js +2 -1
- package/dist/shortcuts/workflow/host.js +3 -0
- package/dist/shortcuts/workflow/index.js +1 -1
- package/dist/shortcuts/workflow/operations/form.js +44 -11
- 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-meeting/SKILL.md +250 -301
- package/skills/weaver-e10-meeting/references/meeting-eb.md +203 -0
- package/skills/weaver-e10-meeting/references/meeting-invitation.md +37 -5
- package/skills/weaver-e10-meeting.zip +0 -0
- package/skills/weaver-e10-okr/references/source-manifest.json +3 -3
- 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
- package/skills/weaver-e10-yimiaoban/references/source-manifest.json +3 -3
|
@@ -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",
|
|
@@ -8228,7 +8258,8 @@ var XIAOE_FILL_FORM_SDK_OPTIONS = {
|
|
|
8228
8258
|
};
|
|
8229
8259
|
var XIAOE_INITIAL_VALUES_MULTI_SEPARATOR = ",";
|
|
8230
8260
|
var XIAOE_INITIAL_VALUES_ROW_SEPARATOR = ";";
|
|
8231
|
-
|
|
8261
|
+
var XIAOE_BROWSER_ID_PREFIX = "##";
|
|
8262
|
+
function xiaoEUrlParamScalar(value, prefixBrowserId = false) {
|
|
8232
8263
|
if (value === null || value === void 0) return "";
|
|
8233
8264
|
if (typeof value === "object") {
|
|
8234
8265
|
const obj = value;
|
|
@@ -8236,18 +8267,19 @@ function xiaoEUrlParamScalar(value) {
|
|
|
8236
8267
|
const picked = obj[key];
|
|
8237
8268
|
if (picked === null || picked === void 0) continue;
|
|
8238
8269
|
const text = String(picked).trim();
|
|
8239
|
-
if (text)
|
|
8270
|
+
if (!text) continue;
|
|
8271
|
+
return prefixBrowserId ? `${XIAOE_BROWSER_ID_PREFIX}${text}` : text;
|
|
8240
8272
|
}
|
|
8241
8273
|
return "";
|
|
8242
8274
|
}
|
|
8243
8275
|
return String(value).trim();
|
|
8244
8276
|
}
|
|
8245
|
-
function xiaoEUrlParamValue(value) {
|
|
8277
|
+
function xiaoEUrlParamValue(value, prefixBrowserId = false) {
|
|
8246
8278
|
if (value === null || value === void 0) return "";
|
|
8247
8279
|
if (Array.isArray(value)) {
|
|
8248
|
-
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);
|
|
8249
8281
|
}
|
|
8250
|
-
return xiaoEUrlParamScalar(value);
|
|
8282
|
+
return xiaoEUrlParamScalar(value, prefixBrowserId);
|
|
8251
8283
|
}
|
|
8252
8284
|
function editablePreviewForXiaoE(preview, fields, visibility) {
|
|
8253
8285
|
const fieldById = /* @__PURE__ */ new Map();
|
|
@@ -8272,14 +8304,19 @@ function editablePreviewForXiaoE(preview, fields, visibility) {
|
|
|
8272
8304
|
}
|
|
8273
8305
|
return kept;
|
|
8274
8306
|
}
|
|
8275
|
-
function xiaoECustomParams(preview) {
|
|
8307
|
+
function xiaoECustomParams(preview, fields) {
|
|
8276
8308
|
const ordered = [];
|
|
8277
8309
|
const mainValues = /* @__PURE__ */ new Map();
|
|
8278
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
|
+
}
|
|
8279
8316
|
for (const item of toArray(preview)) {
|
|
8280
8317
|
const fieldId = String(item?.fieldId ?? "").trim();
|
|
8281
8318
|
if (!fieldId) continue;
|
|
8282
|
-
const text = xiaoEUrlParamValue(item?.value);
|
|
8319
|
+
const text = xiaoEUrlParamValue(item?.value, browserFieldIds.has(fieldId));
|
|
8283
8320
|
if (!text) continue;
|
|
8284
8321
|
const isDetail = item?.dataIndex !== void 0 && item?.dataIndex !== null;
|
|
8285
8322
|
if (!isDetail) {
|
|
@@ -8563,7 +8600,7 @@ async function runCreateRequest(args, env, options = {}) {
|
|
|
8563
8600
|
baseUrl: xiaoEBaseUrl,
|
|
8564
8601
|
title: String(context.workflow?.name ?? ""),
|
|
8565
8602
|
workflowId: String(context.workflow?.id ?? context.runtime?.workflow_id ?? ""),
|
|
8566
|
-
customParams: xiaoECustomParams(fillPreview)
|
|
8603
|
+
customParams: xiaoECustomParams(fillPreview, fields)
|
|
8567
8604
|
})
|
|
8568
8605
|
});
|
|
8569
8606
|
}
|
|
@@ -10297,90 +10334,30 @@ import { existsSync as existsSync3, readFileSync } from "node:fs";
|
|
|
10297
10334
|
import { join as join2 } from "node:path";
|
|
10298
10335
|
|
|
10299
10336
|
// src/shortcuts/workflow/operations/todoSmartConvert/summaryCache.ts
|
|
10300
|
-
import { existsSync as existsSync2
|
|
10337
|
+
import { existsSync as existsSync2 } from "node:fs";
|
|
10301
10338
|
import { chmod as chmod2, mkdir as mkdir2, readFile as readFile2, writeFile as writeFile2 } from "node:fs/promises";
|
|
10302
|
-
import { homedir as homedir2 } from "node:os";
|
|
10303
10339
|
import { join, resolve as resolve2 } from "node:path";
|
|
10304
|
-
var SKILL_DIR_NAME = "weaver-e10-workflow";
|
|
10305
10340
|
var CACHE_DIR_NAME = "cache";
|
|
10306
|
-
var AGENT_HOME_DIRS = [".workbuddy", ".claude", ".codebuddy", ".codex", ".cursor", ".gemini"];
|
|
10307
10341
|
var SUMMARY_CACHE_FILE_NAME = "todo-summary-cache.json";
|
|
10308
10342
|
var SUMMARY_CACHE_VERSION = 2;
|
|
10309
10343
|
function uniqueDirs(dirs) {
|
|
10310
|
-
return [...new Set(dirs.filter(Boolean))];
|
|
10311
|
-
}
|
|
10312
|
-
function stateCacheDir(ctx) {
|
|
10313
|
-
return resolve2(stateRoot(ctx), CACHE_DIR_NAME);
|
|
10314
|
-
}
|
|
10315
|
-
function discoverThisSkillDirs(home) {
|
|
10316
|
-
const marker = join("references", "todo-smart-convert.md");
|
|
10317
|
-
const found = [];
|
|
10318
|
-
for (const agent of AGENT_HOME_DIRS) {
|
|
10319
|
-
const root = join(home, agent, "skills");
|
|
10320
|
-
const entries = (() => {
|
|
10321
|
-
try {
|
|
10322
|
-
return readdirSync(root, { withFileTypes: true });
|
|
10323
|
-
} catch {
|
|
10324
|
-
return [];
|
|
10325
|
-
}
|
|
10326
|
-
})();
|
|
10327
|
-
for (const entry of entries) {
|
|
10328
|
-
if (!entry.isDirectory()) continue;
|
|
10329
|
-
const dir = join(root, entry.name);
|
|
10330
|
-
if (existsSync2(join(dir, marker))) found.push(dir);
|
|
10331
|
-
}
|
|
10332
|
-
}
|
|
10333
|
-
return found;
|
|
10334
|
-
}
|
|
10335
|
-
function mtimeOf(file) {
|
|
10336
|
-
try {
|
|
10337
|
-
return statSync(file).mtimeMs;
|
|
10338
|
-
} catch {
|
|
10339
|
-
return 0;
|
|
10340
|
-
}
|
|
10344
|
+
return [...new Set(dirs.filter((dir) => Boolean(dir)))];
|
|
10341
10345
|
}
|
|
10342
|
-
function
|
|
10343
|
-
const
|
|
10344
|
-
|
|
10345
|
-
index,
|
|
10346
|
-
hasCache: existsSync2(join(dir, CACHE_DIR_NAME, SUMMARY_CACHE_FILE_NAME)) ? 1 : 0,
|
|
10347
|
-
cacheMtime: mtimeOf(join(dir, CACHE_DIR_NAME, SUMMARY_CACHE_FILE_NAME)),
|
|
10348
|
-
hasMarker: existsSync2(join(dir, "references", "todo-smart-convert.md")) ? 1 : 0,
|
|
10349
|
-
skillMtime: mtimeOf(join(dir, "SKILL.md"))
|
|
10350
|
-
}));
|
|
10351
|
-
scored.sort(
|
|
10352
|
-
(a, b) => b.hasCache - a.hasCache || b.cacheMtime - a.cacheMtime || b.hasMarker - a.hasMarker || b.skillMtime - a.skillMtime || a.index - b.index
|
|
10353
|
-
);
|
|
10354
|
-
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;
|
|
10355
10349
|
}
|
|
10356
10350
|
function cacheRoots(ctx) {
|
|
10357
|
-
|
|
10358
|
-
const
|
|
10359
|
-
if (
|
|
10360
|
-
|
|
10361
|
-
return { preferred: dir, fallback: dir, inSkillDir: false, skillDir: null };
|
|
10362
|
-
}
|
|
10363
|
-
const home = homedir2();
|
|
10364
|
-
const explicitSkill = process.env.WEAVER_WORK_CLI_SKILL_DIR?.trim();
|
|
10365
|
-
const candidates = [];
|
|
10366
|
-
if (explicitSkill) candidates.push(resolve2(explicitSkill));
|
|
10367
|
-
for (const agent of AGENT_HOME_DIRS) {
|
|
10368
|
-
candidates.push(join(home, agent, "skills", SKILL_DIR_NAME));
|
|
10369
|
-
}
|
|
10370
|
-
candidates.push(...discoverThisSkillDirs(home));
|
|
10371
|
-
const installed = uniqueDirs(candidates).filter((dir) => existsSync2(join(dir, "SKILL.md")));
|
|
10372
|
-
const [skillDir] = rankSkillDirs(installed);
|
|
10373
|
-
if (skillDir) {
|
|
10374
|
-
return {
|
|
10375
|
-
preferred: join(skillDir, CACHE_DIR_NAME),
|
|
10376
|
-
fallback,
|
|
10377
|
-
inSkillDir: true,
|
|
10378
|
-
skillDir
|
|
10379
|
-
};
|
|
10351
|
+
void ctx;
|
|
10352
|
+
const skillDir = resolveSkillDir();
|
|
10353
|
+
if (!skillDir) {
|
|
10354
|
+
return { preferred: null, fallback: null, inSkillDir: false, skillDir: null, refused: true };
|
|
10380
10355
|
}
|
|
10381
|
-
|
|
10356
|
+
const cacheDir = join(skillDir, CACHE_DIR_NAME);
|
|
10357
|
+
return { preferred: cacheDir, fallback: cacheDir, inSkillDir: true, skillDir, refused: false };
|
|
10382
10358
|
}
|
|
10383
10359
|
async function readCacheFile(roots, fileName) {
|
|
10360
|
+
if (roots.refused || !roots.preferred) return null;
|
|
10384
10361
|
for (const dir of uniqueDirs([roots.preferred, roots.fallback])) {
|
|
10385
10362
|
const file = join(dir, fileName);
|
|
10386
10363
|
if (!existsSync2(file)) continue;
|
|
@@ -10393,6 +10370,7 @@ async function readCacheFile(roots, fileName) {
|
|
|
10393
10370
|
return null;
|
|
10394
10371
|
}
|
|
10395
10372
|
async function writeCacheFile(roots, fileName, payload) {
|
|
10373
|
+
if (roots.refused || !roots.preferred) return null;
|
|
10396
10374
|
for (const dir of uniqueDirs([roots.preferred, roots.fallback])) {
|
|
10397
10375
|
const file = join(dir, fileName);
|
|
10398
10376
|
try {
|
|
@@ -10412,9 +10390,14 @@ function summaryCacheKey(requestId, lastFeedBackDateTime) {
|
|
|
10412
10390
|
const stamp = String(lastFeedBackDateTime ?? "").trim();
|
|
10413
10391
|
return `${requestId}__${stamp}`;
|
|
10414
10392
|
}
|
|
10415
|
-
function
|
|
10416
|
-
|
|
10417
|
-
|
|
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;
|
|
10418
10401
|
}
|
|
10419
10402
|
function normalizeSummaryEntry(raw) {
|
|
10420
10403
|
if (!raw || typeof raw !== "object") return null;
|
|
@@ -10422,7 +10405,15 @@ function normalizeSummaryEntry(raw) {
|
|
|
10422
10405
|
if (typeof entry.summary !== "string" || !entry.summary.trim()) return null;
|
|
10423
10406
|
if (typeof entry.cachedAt !== "number" || !Number.isFinite(entry.cachedAt)) return null;
|
|
10424
10407
|
const maxChars = typeof entry.maxChars === "number" && Number.isFinite(entry.maxChars) ? entry.maxChars : void 0;
|
|
10425
|
-
|
|
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
|
+
};
|
|
10426
10417
|
}
|
|
10427
10418
|
async function openSummaryCache(ctx) {
|
|
10428
10419
|
const roots = cacheRoots(ctx);
|
|
@@ -10459,27 +10450,29 @@ async function openSummaryCache(ctx) {
|
|
|
10459
10450
|
misses: 0,
|
|
10460
10451
|
pruned,
|
|
10461
10452
|
dirty: false,
|
|
10462
|
-
get(requestId, lastFeedBackDateTime, maxChars) {
|
|
10453
|
+
get(requestId, lastFeedBackDateTime, maxChars, pk, dv) {
|
|
10463
10454
|
const key = summaryCacheKey(requestId, lastFeedBackDateTime);
|
|
10464
10455
|
const entry = entries.get(key);
|
|
10465
|
-
if (entry && now - entry.cachedAt <= SUMMARY_CACHE_TTL_MS &&
|
|
10456
|
+
if (entry && now - entry.cachedAt <= SUMMARY_CACHE_TTL_MS && entryMatches(entry, maxChars, pk, dv)) {
|
|
10466
10457
|
cache.hits += 1;
|
|
10467
10458
|
return entry.summary;
|
|
10468
10459
|
}
|
|
10469
10460
|
cache.misses += 1;
|
|
10470
10461
|
return null;
|
|
10471
10462
|
},
|
|
10472
|
-
has(requestId, lastFeedBackDateTime, maxChars) {
|
|
10463
|
+
has(requestId, lastFeedBackDateTime, maxChars, pk, dv) {
|
|
10473
10464
|
const entry = entries.get(summaryCacheKey(requestId, lastFeedBackDateTime));
|
|
10474
|
-
return entry !== void 0 &&
|
|
10465
|
+
return entry !== void 0 && entryMatches(entry, maxChars, pk, dv);
|
|
10475
10466
|
},
|
|
10476
|
-
set(requestId, lastFeedBackDateTime, summary, maxChars) {
|
|
10467
|
+
set(requestId, lastFeedBackDateTime, summary, maxChars, pk, dv) {
|
|
10477
10468
|
const text = String(summary ?? "").trim();
|
|
10478
10469
|
if (!requestId || !text) return false;
|
|
10479
10470
|
entries.set(summaryCacheKey(requestId, lastFeedBackDateTime), {
|
|
10480
10471
|
summary: text,
|
|
10481
10472
|
cachedAt: Date.now(),
|
|
10482
|
-
...maxChars === void 0 ? {} : { maxChars }
|
|
10473
|
+
...maxChars === void 0 ? {} : { maxChars },
|
|
10474
|
+
...pk === void 0 || pk === "" ? {} : { pk },
|
|
10475
|
+
...dv === void 0 || dv === "" ? {} : { dv }
|
|
10483
10476
|
});
|
|
10484
10477
|
dirty = true;
|
|
10485
10478
|
cache.dirty = true;
|
|
@@ -10531,7 +10524,8 @@ var FALLBACK_DEFAULTS = {
|
|
|
10531
10524
|
requestSummaryPrompt: "",
|
|
10532
10525
|
summaryMaxChars: 150,
|
|
10533
10526
|
groupSummaryMaxChars: 100,
|
|
10534
|
-
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: []
|
|
10535
10529
|
};
|
|
10536
10530
|
function emptyRuleFile(error = null) {
|
|
10537
10531
|
return {
|
|
@@ -10560,14 +10554,33 @@ function validateFocusKeyword(raw, index) {
|
|
|
10560
10554
|
if (raw.length !== 3) return `focusKeyword[${index}] \u5FC5\u987B\u662F [\u6307\u6807, \u7B97\u5B50, \u503C] \u4E09\u5143\u7EC4`;
|
|
10561
10555
|
return null;
|
|
10562
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
|
+
}
|
|
10563
10568
|
function validateRuleFile(raw) {
|
|
10564
10569
|
const errors = [];
|
|
10565
10570
|
const file = raw;
|
|
10566
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
|
+
}
|
|
10567
10575
|
if (!Array.isArray(file.rules)) {
|
|
10568
10576
|
errors.push("rules \u5FC5\u987B\u662F\u6570\u7EC4");
|
|
10569
10577
|
return errors;
|
|
10570
10578
|
}
|
|
10579
|
+
const defaultsExclude = validateExcludeFields(
|
|
10580
|
+
file.defaults?.excludeOriginFormDataFields,
|
|
10581
|
+
"defaults.excludeOriginFormDataFields"
|
|
10582
|
+
);
|
|
10583
|
+
if (defaultsExclude) errors.push(defaultsExclude);
|
|
10571
10584
|
const seen = /* @__PURE__ */ new Set();
|
|
10572
10585
|
file.rules.forEach((rule, index) => {
|
|
10573
10586
|
if (!rule || typeof rule !== "object") {
|
|
@@ -10589,6 +10602,13 @@ function validateRuleFile(raw) {
|
|
|
10589
10602
|
if (rule.summaryMaxChars !== void 0 && (typeof rule.summaryMaxChars !== "number" || rule.summaryMaxChars <= 0)) {
|
|
10590
10603
|
errors.push(`rules[${index}].summaryMaxChars \u5FC5\u987B\u662F\u6B63\u6570`);
|
|
10591
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
|
+
}
|
|
10592
10612
|
const groupRule = rule.aiGroup?.groupRule;
|
|
10593
10613
|
if (groupRule) {
|
|
10594
10614
|
if (typeof groupRule.focus !== "boolean") errors.push(`rules[${index}].aiGroup.groupRule.focus \u5FC5\u987B\u662F\u5E03\u5C14`);
|
|
@@ -10642,29 +10662,28 @@ function loadRuleFile(file) {
|
|
|
10642
10662
|
return { file: parsed, error: null };
|
|
10643
10663
|
}
|
|
10644
10664
|
function aigroupDir(ctx) {
|
|
10645
|
-
const
|
|
10646
|
-
|
|
10647
|
-
const roots = cacheRoots(ctx);
|
|
10648
|
-
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;
|
|
10649
10667
|
}
|
|
10650
10668
|
function aigroupUserDir(ctx) {
|
|
10651
|
-
|
|
10652
|
-
if (explicit) return join2(explicit);
|
|
10653
|
-
return join2(stateRoot(ctx), AIGROUP_DIR_NAME);
|
|
10669
|
+
return aigroupDir(ctx);
|
|
10654
10670
|
}
|
|
10655
10671
|
function loadRules(options = {}) {
|
|
10656
|
-
const dir = options.dir ?? aigroupDir(options.ctx);
|
|
10657
|
-
const userDir = options.dir ?? aigroupUserDir(options.ctx);
|
|
10658
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
|
+
}
|
|
10659
10678
|
const base = loadRuleFile(join2(dir, DEFAULT_RULE_FILE));
|
|
10660
10679
|
if (base.error) warnings.push(base.error);
|
|
10661
10680
|
const rules = [...base.file.rules];
|
|
10662
|
-
const userIntentFile = join2(
|
|
10663
|
-
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);
|
|
10664
10683
|
let intentFile = userIntentFile;
|
|
10665
10684
|
if (!options.dir && !existsSync3(userIntentFile) && existsSync3(legacyIntentFile)) {
|
|
10666
10685
|
intentFile = legacyIntentFile;
|
|
10667
|
-
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`);
|
|
10668
10687
|
}
|
|
10669
10688
|
const intent = loadRuleFile(intentFile);
|
|
10670
10689
|
if (intent.error) {
|
|
@@ -10726,12 +10745,13 @@ function resolveRule(file, workflowName) {
|
|
|
10726
10745
|
summaryMaxChars: raw.summaryMaxChars ?? defaults.summaryMaxChars,
|
|
10727
10746
|
groupSummaryMaxChars: defaults.groupSummaryMaxChars,
|
|
10728
10747
|
groupSummaryTail: defaults.groupSummaryTail,
|
|
10748
|
+
// 显式给 `[]` = 规则级覆盖(清空 defaults 的清单);未给才落 defaults
|
|
10749
|
+
excludeOriginFormDataFields: raw.excludeOriginFormDataFields === void 0 ? defaults.excludeOriginFormDataFields : asStringArray3(raw.excludeOriginFormDataFields) ?? [],
|
|
10729
10750
|
aiGroup: raw.aiGroup ? {
|
|
10730
10751
|
groupSummary: {
|
|
10731
10752
|
needAI: groupSummary?.needAI ?? false,
|
|
10732
10753
|
...groupSummary?.prompt === void 0 ? {} : { prompt: groupSummary.prompt },
|
|
10733
10754
|
...groupSummary?.template === void 0 ? {} : { template: groupSummary.template },
|
|
10734
|
-
maxChars: defaults.groupSummaryMaxChars,
|
|
10735
10755
|
tail: defaults.groupSummaryTail
|
|
10736
10756
|
},
|
|
10737
10757
|
groupRule: groupRule ?? EMPTY_GROUP_RULE
|
|
@@ -10858,6 +10878,15 @@ function resetActiveRules() {
|
|
|
10858
10878
|
activeFile = null;
|
|
10859
10879
|
activeDir = null;
|
|
10860
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
|
+
}
|
|
10861
10890
|
|
|
10862
10891
|
// src/shortcuts/workflow/operations/todoSmartConvert/todoListRows.ts
|
|
10863
10892
|
var DISPLAY_ROW_FIELDS = [
|
|
@@ -10918,6 +10947,107 @@ function projectDisplayRows(response) {
|
|
|
10918
10947
|
return projected;
|
|
10919
10948
|
}
|
|
10920
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
|
+
|
|
10921
11051
|
// src/shortcuts/workflow/operations/todoSmartConvert/detailFieldRules.ts
|
|
10922
11052
|
function normalizeDetailFieldName(raw) {
|
|
10923
11053
|
return String(raw ?? "").replace(/<[^>]*>/g, " ").replace(/[【】[\]()()]/g, "").replace(/\s+/g, "").trim();
|
|
@@ -11135,7 +11265,8 @@ function renderGroupSummaryTemplate(input) {
|
|
|
11135
11265
|
var DETAIL_BATCH_CONCURRENCY = 10;
|
|
11136
11266
|
var DETAIL_BATCH_TIMEOUT_MS = 1e4;
|
|
11137
11267
|
var DETAIL_BATCH_RETRIES = 1;
|
|
11138
|
-
var
|
|
11268
|
+
var DETAIL_MATERIAL_FIELD_LIMIT = 200;
|
|
11269
|
+
var DETAIL_MATERIAL_VALUE_LIMIT = 500;
|
|
11139
11270
|
var HTML_ENTITIES = {
|
|
11140
11271
|
amp: "&",
|
|
11141
11272
|
lt: "<",
|
|
@@ -11224,6 +11355,9 @@ async function fetchOneDetail(env, requestId, userId, options) {
|
|
|
11224
11355
|
const normalized = normalizeDetailResponse(response);
|
|
11225
11356
|
const base = normalized?.basicInfo ?? {};
|
|
11226
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
|
+
);
|
|
11227
11361
|
const usableFields = dropDistributionDetailFields(rawFields);
|
|
11228
11362
|
const internalMessage = isInternalMessageDetail(
|
|
11229
11363
|
base.workflowName,
|
|
@@ -11233,25 +11367,19 @@ async function fetchOneDetail(env, requestId, userId, options) {
|
|
|
11233
11367
|
...field,
|
|
11234
11368
|
value: cleanFieldText(String(field?.value ?? ""))
|
|
11235
11369
|
}));
|
|
11236
|
-
const
|
|
11237
|
-
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) => ({
|
|
11238
11373
|
fieldName: String(field?.fieldName ?? "").trim(),
|
|
11239
|
-
value: String(field?.value ?? "")
|
|
11374
|
+
value: String(field?.value ?? "").slice(0, DETAIL_MATERIAL_VALUE_LIMIT)
|
|
11240
11375
|
})).filter((field) => field.fieldName && field.value);
|
|
11241
11376
|
const metrics = extractRowMetrics(usableFields);
|
|
11242
11377
|
return {
|
|
11243
11378
|
requestId,
|
|
11244
|
-
basicInfo
|
|
11245
|
-
|
|
11246
|
-
|
|
11247
|
-
|
|
11248
|
-
createdAt: String(base.createdAt ?? ""),
|
|
11249
|
-
currentNode: String(base.currentNode ?? ""),
|
|
11250
|
-
requestLevel: String(base.requestLevel ?? ""),
|
|
11251
|
-
flowStatus: String(base.flowStatus ?? "")
|
|
11252
|
-
},
|
|
11253
|
-
summaryFields,
|
|
11254
|
-
contextAvailable: summaryFields.length > 0,
|
|
11379
|
+
basicInfo,
|
|
11380
|
+
formFields: picked,
|
|
11381
|
+
contextAvailable: picked.length > 0,
|
|
11382
|
+
excludeTag: excludeTagOf(excludeFields),
|
|
11255
11383
|
metrics
|
|
11256
11384
|
};
|
|
11257
11385
|
}
|
|
@@ -11303,17 +11431,10 @@ async function fetchRequestDetailsBatch(env, requestIds, options = {}) {
|
|
|
11303
11431
|
failures.push({ requestId, error: reason });
|
|
11304
11432
|
details.set(requestId, {
|
|
11305
11433
|
requestId,
|
|
11306
|
-
basicInfo: {
|
|
11307
|
-
|
|
11308
|
-
workflowName: "",
|
|
11309
|
-
creatorName: "",
|
|
11310
|
-
createdAt: "",
|
|
11311
|
-
currentNode: "",
|
|
11312
|
-
requestLevel: "",
|
|
11313
|
-
flowStatus: ""
|
|
11314
|
-
},
|
|
11315
|
-
summaryFields: [],
|
|
11434
|
+
basicInfo: {},
|
|
11435
|
+
formFields: [],
|
|
11316
11436
|
contextAvailable: false,
|
|
11437
|
+
excludeTag: "",
|
|
11317
11438
|
metrics: {},
|
|
11318
11439
|
error: reason
|
|
11319
11440
|
});
|
|
@@ -11336,90 +11457,11 @@ async function fetchRequestDetailsBatch(env, requestIds, options = {}) {
|
|
|
11336
11457
|
};
|
|
11337
11458
|
}
|
|
11338
11459
|
|
|
11339
|
-
// src/shortcuts/workflow/operations/todoSmartConvert/todoDetailCache.ts
|
|
11340
|
-
var DETAIL_CACHE_FILE_NAME = "todo-detail-cache.json";
|
|
11341
|
-
var DETAIL_CACHE_TTL_MS = SUMMARY_CACHE_TTL_MS;
|
|
11342
|
-
var DETAIL_CACHE_PRUNE_INTERVAL_MS = SUMMARY_CACHE_PRUNE_INTERVAL_MS;
|
|
11343
|
-
function detailCacheKey(requestId, lastFeedBackDateTime) {
|
|
11344
|
-
const stamp = String(lastFeedBackDateTime ?? "").trim();
|
|
11345
|
-
return `${requestId}__${stamp}`;
|
|
11346
|
-
}
|
|
11347
|
-
function normalizeEntry(raw) {
|
|
11348
|
-
if (!raw || typeof raw !== "object") return null;
|
|
11349
|
-
const value = raw;
|
|
11350
|
-
if (typeof value.cachedAt !== "number" || !Number.isFinite(value.cachedAt)) return null;
|
|
11351
|
-
if (typeof value.context !== "string") return null;
|
|
11352
|
-
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 })) : [];
|
|
11353
|
-
const metrics = value.metrics && typeof value.metrics === "object" ? value.metrics : {};
|
|
11354
|
-
return {
|
|
11355
|
-
context: value.context,
|
|
11356
|
-
contextAvailable: value.contextAvailable === true,
|
|
11357
|
-
metrics,
|
|
11358
|
-
fields,
|
|
11359
|
-
cachedAt: value.cachedAt
|
|
11360
|
-
};
|
|
11361
|
-
}
|
|
11362
|
-
async function openDetailCache(ctx) {
|
|
11363
|
-
const roots = cacheRoots(ctx);
|
|
11364
|
-
const stored = await readCacheFile(roots, DETAIL_CACHE_FILE_NAME);
|
|
11365
|
-
const now = Date.now();
|
|
11366
|
-
const entries = /* @__PURE__ */ new Map();
|
|
11367
|
-
let prunedAt = 0;
|
|
11368
|
-
let loaded = 0;
|
|
11369
|
-
let pruned = 0;
|
|
11370
|
-
if (stored) {
|
|
11371
|
-
try {
|
|
11372
|
-
const parsed = JSON.parse(stored.text);
|
|
11373
|
-
prunedAt = typeof parsed.prunedAt === "number" ? parsed.prunedAt : 0;
|
|
11374
|
-
for (const [key, raw] of Object.entries(parsed.entries ?? {})) {
|
|
11375
|
-
const entry = normalizeEntry(raw);
|
|
11376
|
-
if (!entry) continue;
|
|
11377
|
-
if (now - entry.cachedAt > DETAIL_CACHE_TTL_MS) {
|
|
11378
|
-
pruned += 1;
|
|
11379
|
-
continue;
|
|
11380
|
-
}
|
|
11381
|
-
entries.set(key, entry);
|
|
11382
|
-
loaded += 1;
|
|
11383
|
-
}
|
|
11384
|
-
} catch {
|
|
11385
|
-
}
|
|
11386
|
-
}
|
|
11387
|
-
const cache = {
|
|
11388
|
-
file: stored?.file ?? null,
|
|
11389
|
-
pruned: 0,
|
|
11390
|
-
loaded,
|
|
11391
|
-
get(requestId, lastFeedBackDateTime) {
|
|
11392
|
-
const entry = entries.get(detailCacheKey(requestId, lastFeedBackDateTime));
|
|
11393
|
-
if (!entry) return null;
|
|
11394
|
-
if (Date.now() - entry.cachedAt > DETAIL_CACHE_TTL_MS) return null;
|
|
11395
|
-
return entry;
|
|
11396
|
-
},
|
|
11397
|
-
has(requestId, lastFeedBackDateTime) {
|
|
11398
|
-
return cache.get(requestId, lastFeedBackDateTime) !== null;
|
|
11399
|
-
},
|
|
11400
|
-
set(requestId, lastFeedBackDateTime, entry) {
|
|
11401
|
-
if (!requestId) return false;
|
|
11402
|
-
entries.set(detailCacheKey(requestId, lastFeedBackDateTime), { ...entry, cachedAt: Date.now() });
|
|
11403
|
-
return true;
|
|
11404
|
-
},
|
|
11405
|
-
async save() {
|
|
11406
|
-
const shouldPrune = pruned > 0 && Date.now() - prunedAt > DETAIL_CACHE_PRUNE_INTERVAL_MS;
|
|
11407
|
-
const payload = {
|
|
11408
|
-
prunedAt: shouldPrune ? Date.now() : prunedAt,
|
|
11409
|
-
entries: Object.fromEntries(entries)
|
|
11410
|
-
};
|
|
11411
|
-
const file = await writeCacheFile(roots, DETAIL_CACHE_FILE_NAME, JSON.stringify(payload));
|
|
11412
|
-
if (file) cache.file = file;
|
|
11413
|
-
if (shouldPrune) cache.pruned = pruned;
|
|
11414
|
-
return file;
|
|
11415
|
-
}
|
|
11416
|
-
};
|
|
11417
|
-
return cache;
|
|
11418
|
-
}
|
|
11419
|
-
|
|
11420
11460
|
// src/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.detail.ts
|
|
11421
11461
|
function contextOfDetail(detail) {
|
|
11422
|
-
|
|
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");
|
|
11423
11465
|
}
|
|
11424
11466
|
var EMPTY_DETAIL_STATS = {
|
|
11425
11467
|
requested: 0,
|
|
@@ -11431,8 +11473,6 @@ var EMPTY_DETAIL_STATS = {
|
|
|
11431
11473
|
concurrency: 0,
|
|
11432
11474
|
durationMs: 0
|
|
11433
11475
|
};
|
|
11434
|
-
var DETAIL_MATERIAL_FIELD_LIMIT = 8;
|
|
11435
|
-
var DETAIL_MATERIAL_VALUE_LIMIT = 80;
|
|
11436
11476
|
function stampsOfRows(rows) {
|
|
11437
11477
|
const stamps = /* @__PURE__ */ new Map();
|
|
11438
11478
|
for (const row of rows) {
|
|
@@ -11445,7 +11485,7 @@ function stampsOfRows(rows) {
|
|
|
11445
11485
|
return stamps;
|
|
11446
11486
|
}
|
|
11447
11487
|
function materialFieldsOf(detail) {
|
|
11448
|
-
return detail.
|
|
11488
|
+
return detail.formFields.map((field) => ({ fieldName: field.fieldName, value: field.value }));
|
|
11449
11489
|
}
|
|
11450
11490
|
async function fetchDetailFacts(env, requestIds, args, stamps) {
|
|
11451
11491
|
const unique = [...new Set(requestIds.filter(Boolean))];
|
|
@@ -11459,13 +11499,13 @@ async function fetchDetailFacts(env, requestIds, args, stamps) {
|
|
|
11459
11499
|
const missing = [];
|
|
11460
11500
|
for (const requestId of unique) {
|
|
11461
11501
|
const hit = cache.get(requestId, stamps?.get(requestId));
|
|
11462
|
-
if (!hit) {
|
|
11502
|
+
if (!hit || hit.excludeTag !== excludeTagFor(hit.basicInfo.workflowName ?? "")) {
|
|
11463
11503
|
missing.push(requestId);
|
|
11464
11504
|
continue;
|
|
11465
11505
|
}
|
|
11466
11506
|
facts.set(requestId, {
|
|
11467
|
-
context: hit.
|
|
11468
|
-
contextAvailable: hit.
|
|
11507
|
+
context: contextOfDetail({ basicInfo: hit.basicInfo, formFields: hit.fields }),
|
|
11508
|
+
contextAvailable: hit.fields.length > 0,
|
|
11469
11509
|
metrics: hit.metrics,
|
|
11470
11510
|
fields: hit.fields
|
|
11471
11511
|
});
|
|
@@ -11483,7 +11523,7 @@ async function fetchDetailFacts(env, requestIds, args, stamps) {
|
|
|
11483
11523
|
for (const [requestId, detail] of details) {
|
|
11484
11524
|
const fact = {
|
|
11485
11525
|
context: contextOfDetail(detail),
|
|
11486
|
-
contextAvailable: detail.
|
|
11526
|
+
contextAvailable: detail.formFields.length > 0,
|
|
11487
11527
|
metrics: detail.metrics ?? {},
|
|
11488
11528
|
fields: materialFieldsOf(detail)
|
|
11489
11529
|
};
|
|
@@ -11492,10 +11532,11 @@ async function fetchDetailFacts(env, requestIds, args, stamps) {
|
|
|
11492
11532
|
if (fact.contextAvailable) stats.contextAvailable += 1;
|
|
11493
11533
|
else stats.contextEmpty += 1;
|
|
11494
11534
|
if (cache.set(requestId, stamps?.get(requestId), {
|
|
11495
|
-
|
|
11496
|
-
|
|
11535
|
+
v: DETAIL_CACHE_ENTRY_VERSION,
|
|
11536
|
+
basicInfo: detail.basicInfo,
|
|
11497
11537
|
metrics: fact.metrics,
|
|
11498
|
-
fields: fact.fields
|
|
11538
|
+
fields: fact.fields,
|
|
11539
|
+
excludeTag: detail.excludeTag
|
|
11499
11540
|
})) written += 1;
|
|
11500
11541
|
}
|
|
11501
11542
|
} catch (error) {
|
|
@@ -11976,16 +12017,32 @@ async function collectRawTodos(args, env) {
|
|
|
11976
12017
|
});
|
|
11977
12018
|
wfIdGroup = grouped.wfIdGroup ?? [];
|
|
11978
12019
|
const summaryCache = await openSummaryCache(env.ctx);
|
|
11979
|
-
const
|
|
11980
|
-
|
|
11981
|
-
"
|
|
11982
|
-
|
|
11983
|
-
|
|
11984
|
-
|
|
11985
|
-
|
|
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
|
+
};
|
|
11986
12035
|
const cachedSummaryIds = /* @__PURE__ */ new Set();
|
|
12036
|
+
const detailCacheForTag = await openDetailCache(env.ctx);
|
|
11987
12037
|
for (const row of items) {
|
|
11988
|
-
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
|
+
);
|
|
11989
12046
|
if (!cached) continue;
|
|
11990
12047
|
row.summary = cached;
|
|
11991
12048
|
cachedSummaryIds.add(row.requestId);
|
|
@@ -12062,7 +12119,7 @@ async function collectRawTodos(args, env) {
|
|
|
12062
12119
|
}
|
|
12063
12120
|
if (!summaryCache.inSkillDir) {
|
|
12064
12121
|
warnings.push(
|
|
12065
|
-
"\
|
|
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"
|
|
12066
12123
|
);
|
|
12067
12124
|
}
|
|
12068
12125
|
}
|
|
@@ -12349,12 +12406,23 @@ async function runSmartGroup(args, env, options = {}) {
|
|
|
12349
12406
|
);
|
|
12350
12407
|
const skipDetail = args.withDetailContext === false;
|
|
12351
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
|
+
};
|
|
12352
12414
|
const cachedIds = /* @__PURE__ */ new Set();
|
|
12353
12415
|
const allRows = [];
|
|
12354
12416
|
for (const group of groups) {
|
|
12355
12417
|
for (const row of group.requestDatas ?? []) {
|
|
12356
12418
|
allRows.push(row);
|
|
12357
|
-
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);
|
|
12358
12426
|
}
|
|
12359
12427
|
}
|
|
12360
12428
|
const detailIds = [...new Set(allRows.map((row) => row.requestId).filter(Boolean))];
|
|
@@ -12604,6 +12672,21 @@ async function runSmartGroup(args, env, options = {}) {
|
|
|
12604
12672
|
function needAiSummary(workflowName) {
|
|
12605
12673
|
return activeRuleFor(workflowName)?.needSummary ?? true;
|
|
12606
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
|
+
}
|
|
12607
12690
|
var DEFAULT_MAX_CHARS_PER_BATCH = 24e3;
|
|
12608
12691
|
var DEFAULT_MAX_ITEMS_PER_BATCH = 100;
|
|
12609
12692
|
var DEFAULT_REQUEST_SUMMARY_MAX3 = 50;
|
|
@@ -12774,20 +12857,35 @@ async function runSummaryContext(args, env, prefetched) {
|
|
|
12774
12857
|
const units = collectSummaryUnits(groups);
|
|
12775
12858
|
const skippedSatisfaction = groups.filter((group) => !needAiSummary(group.title)).reduce((sum, group) => sum + rowsOfGroup(group).length, 0);
|
|
12776
12859
|
const requestIds = [...new Set(units.flatMap((unit) => unit.rows.map((row) => row.requestId)))].filter(Boolean);
|
|
12777
|
-
const summaryMaxChars = readBoundedInt(
|
|
12778
|
-
args.summaryMaxChars,
|
|
12779
|
-
"summaryMaxChars",
|
|
12780
|
-
DEFAULT_REQUEST_SUMMARY_MAX3,
|
|
12781
|
-
10,
|
|
12782
|
-
500
|
|
12783
|
-
);
|
|
12784
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
|
+
};
|
|
12785
12866
|
let prefilled = 0;
|
|
12786
12867
|
const prefilledIds = /* @__PURE__ */ new Set();
|
|
12787
12868
|
const needsDetail = [];
|
|
12869
|
+
const workflowTitleByRequest = /* @__PURE__ */ new Map();
|
|
12788
12870
|
for (const unit of units) {
|
|
12871
|
+
if (unit.groupId === "priority") continue;
|
|
12789
12872
|
for (const row of unit.rows) {
|
|
12790
|
-
|
|
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
|
+
);
|
|
12791
12889
|
if (cached) {
|
|
12792
12890
|
row.summary = cached;
|
|
12793
12891
|
prefilled += 1;
|
|
@@ -12806,13 +12904,17 @@ async function runSummaryContext(args, env, prefetched) {
|
|
|
12806
12904
|
let contextEmpty = 0;
|
|
12807
12905
|
let titleCopied = 0;
|
|
12808
12906
|
const claimed = /* @__PURE__ */ new Set();
|
|
12809
|
-
|
|
12907
|
+
const orderedUnits = [...units].sort(
|
|
12908
|
+
(a, b) => Number(a.groupId === "priority") - Number(b.groupId === "priority")
|
|
12909
|
+
);
|
|
12910
|
+
for (const unit of orderedUnits) {
|
|
12810
12911
|
let bucket = [];
|
|
12811
12912
|
let chars = 0;
|
|
12812
12913
|
let seq = 0;
|
|
12813
12914
|
const flush = () => {
|
|
12814
12915
|
if (bucket.length === 0) return;
|
|
12815
12916
|
seq += 1;
|
|
12917
|
+
const firstName = ruleNameForRow(unit, { requestId: bucket[0].requestId });
|
|
12816
12918
|
batches.push({
|
|
12817
12919
|
batchId: `${unit.subGroupId}#${seq}`,
|
|
12818
12920
|
groupId: unit.groupId,
|
|
@@ -12823,7 +12925,8 @@ async function runSummaryContext(args, env, prefetched) {
|
|
|
12823
12925
|
charCount: chars,
|
|
12824
12926
|
kind: unit.kind,
|
|
12825
12927
|
...unit.kind === "internal-message" ? { hint: INTERNAL_MESSAGE_SUMMARY_HINT } : {},
|
|
12826
|
-
|
|
12928
|
+
...requestPromptFor(firstName) ? { prompt: requestPromptFor(firstName) } : {},
|
|
12929
|
+
suggestedMaxChars: requestMaxCharsFor(args, firstName),
|
|
12827
12930
|
items: bucket
|
|
12828
12931
|
});
|
|
12829
12932
|
bucket = [];
|
|
@@ -12894,8 +12997,8 @@ async function runSummaryContext(args, env, prefetched) {
|
|
|
12894
12997
|
titleCopied,
|
|
12895
12998
|
/** 本地摘要命中、跳过 AI 的条数 */
|
|
12896
12999
|
prefilled,
|
|
12897
|
-
/**
|
|
12898
|
-
suggestedMaxChars:
|
|
13000
|
+
/** 单条摘要的目标字数:口径一致时给数字,各组口径不同时给 distinct 列表 */
|
|
13001
|
+
...distinctBatchMaxChars(batches).length === 1 ? { suggestedMaxChars: distinctBatchMaxChars(batches)[0] } : { suggestedMaxCharsList: distinctBatchMaxChars(batches) },
|
|
12899
13002
|
/** 内部留言类批次:摘要要按「最低推理强度」写 */
|
|
12900
13003
|
internalMessageBatches: batches.filter((batch) => batch.kind === "internal-message").length,
|
|
12901
13004
|
skippedSatisfaction,
|
|
@@ -12959,16 +13062,30 @@ function readAiSummaries(value) {
|
|
|
12959
13062
|
async function runSummary(args, env) {
|
|
12960
13063
|
const groups = await readFinalGroups(args, env);
|
|
12961
13064
|
const summaries = readAiSummaries(args.aiSummaries);
|
|
12962
|
-
const
|
|
12963
|
-
|
|
12964
|
-
|
|
12965
|
-
|
|
12966
|
-
|
|
12967
|
-
|
|
12968
|
-
|
|
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
|
+
};
|
|
12969
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
|
+
};
|
|
12970
13079
|
let cacheWritten = 0;
|
|
12971
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;
|
|
12972
13089
|
for (const group of groups) {
|
|
12973
13090
|
if (!needAiSummary(group.title)) {
|
|
12974
13091
|
for (const row of rowsOfGroup(group)) {
|
|
@@ -12980,7 +13097,14 @@ async function runSummary(args, env) {
|
|
|
12980
13097
|
}
|
|
12981
13098
|
for (const row of rowsOfGroup(group)) {
|
|
12982
13099
|
if (!row?.requestId || (row.summary ?? "").trim()) continue;
|
|
12983
|
-
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
|
+
);
|
|
12984
13108
|
if (cached) {
|
|
12985
13109
|
row.summary = cached;
|
|
12986
13110
|
}
|
|
@@ -13008,7 +13132,7 @@ async function runSummary(args, env) {
|
|
|
13008
13132
|
let titleKept = 0;
|
|
13009
13133
|
let prefilledKept = 0;
|
|
13010
13134
|
const countedIds = /* @__PURE__ */ new Set();
|
|
13011
|
-
const applyAll = (rows) => {
|
|
13135
|
+
const applyAll = (rows, meta) => {
|
|
13012
13136
|
for (const row of rows) {
|
|
13013
13137
|
const summary = summaries.get(row.requestId) ?? "";
|
|
13014
13138
|
const firstTime = !row.requestId || !countedIds.has(row.requestId);
|
|
@@ -13023,9 +13147,9 @@ async function runSummary(args, env) {
|
|
|
13023
13147
|
if (summary) {
|
|
13024
13148
|
if (firstTime) {
|
|
13025
13149
|
filled += 1;
|
|
13026
|
-
if (summary.length >
|
|
13150
|
+
if (summary.length > meta(row).maxChars) tooLong += 1;
|
|
13027
13151
|
}
|
|
13028
|
-
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;
|
|
13029
13153
|
} else if (firstTime) {
|
|
13030
13154
|
empty += 1;
|
|
13031
13155
|
}
|
|
@@ -13035,17 +13159,28 @@ async function runSummary(args, env) {
|
|
|
13035
13159
|
for (const group of groups) {
|
|
13036
13160
|
if (!needAiSummary(group.title)) continue;
|
|
13037
13161
|
if (group.topPriority) {
|
|
13038
|
-
applyAll(rowsOfGroup(group))
|
|
13162
|
+
applyAll(rowsOfGroup(group), (row) => {
|
|
13163
|
+
const name = ruleNameForGroup(group, row);
|
|
13164
|
+
return { maxChars: maxCharsFor(name), pk: promptTagOf(requestPromptFor(name)) };
|
|
13165
|
+
});
|
|
13039
13166
|
continue;
|
|
13040
13167
|
}
|
|
13041
13168
|
for (const item of group.displayItems) {
|
|
13042
13169
|
if (item.type === "group") {
|
|
13043
|
-
applyAll(item.requestDatas)
|
|
13170
|
+
applyAll(item.requestDatas, (row) => {
|
|
13171
|
+
const name = ruleNameForGroup(group, row);
|
|
13172
|
+
return { maxChars: maxCharsFor(name), pk: promptTagOf(requestPromptFor(name)) };
|
|
13173
|
+
});
|
|
13044
13174
|
continue;
|
|
13045
13175
|
}
|
|
13046
|
-
applyAll([item.requestData])
|
|
13176
|
+
applyAll([item.requestData], (row) => {
|
|
13177
|
+
const name = ruleNameForGroup(group, row);
|
|
13178
|
+
return { maxChars: maxCharsFor(name), pk: promptTagOf(requestPromptFor(name)) };
|
|
13179
|
+
});
|
|
13047
13180
|
}
|
|
13048
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);
|
|
13049
13184
|
if (empty > 0) {
|
|
13050
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`);
|
|
13051
13186
|
}
|
|
@@ -13054,7 +13189,7 @@ async function runSummary(args, env) {
|
|
|
13054
13189
|
}
|
|
13055
13190
|
if (tooLong > 0) {
|
|
13056
13191
|
warnings.push(
|
|
13057
|
-
`\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`
|
|
13058
13193
|
);
|
|
13059
13194
|
}
|
|
13060
13195
|
if (prefilledKept > 0) {
|
|
@@ -13079,8 +13214,8 @@ async function runSummary(args, env) {
|
|
|
13079
13214
|
meta: {
|
|
13080
13215
|
summarized: filled,
|
|
13081
13216
|
empty,
|
|
13082
|
-
/**
|
|
13083
|
-
suggestedMaxChars:
|
|
13217
|
+
/** 单条摘要的目标字数:各组口径一致时给数字,不一致时给 distinct 列表 */
|
|
13218
|
+
...usedMaxChars.length === 1 ? { suggestedMaxChars: usedMaxChars[0] } : { suggestedMaxCharsList: usedMaxChars },
|
|
13084
13219
|
titleCopied: titleKept,
|
|
13085
13220
|
/** 本地摘要缓存命中、未重新生成的条数 */
|
|
13086
13221
|
prefilled: prefilledKept,
|
|
@@ -13099,6 +13234,22 @@ async function runSummary(args, env) {
|
|
|
13099
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";
|
|
13100
13235
|
var GROUP_SUMMARY_TAIL = GROUP_SUMMARY_TAIL_TEXT;
|
|
13101
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
|
+
}
|
|
13102
13253
|
var GROUP_AMOUNT_PATTERNS = [
|
|
13103
13254
|
/[¥¥]\s*(\d[\d,]*(?:\.\d{1,2})?)/u,
|
|
13104
13255
|
/(\d[\d,]*(?:\.\d{1,2})?)\s*元/u
|
|
@@ -13117,7 +13268,7 @@ function createrPhraseOf(creators) {
|
|
|
13117
13268
|
if (creators.length <= 3) return `\u7531${creators.join("\u3001")} \u53D1\u8D77`;
|
|
13118
13269
|
return `\u7531${creators.slice(0, 3).join("\u3001")} \u7B49 ${creators.length} \u4EBA\u53D1\u8D77`;
|
|
13119
13270
|
}
|
|
13120
|
-
function collectGroupSummaryBatches(groups, isCtxEmpty,
|
|
13271
|
+
function collectGroupSummaryBatches(groups, isCtxEmpty, maxCharsFor = () => DEFAULT_GROUP_SUMMARY_MAX) {
|
|
13121
13272
|
const batches = [];
|
|
13122
13273
|
for (const group of groups) {
|
|
13123
13274
|
if (group.topPriority) continue;
|
|
@@ -13146,6 +13297,7 @@ function collectGroupSummaryBatches(groups, isCtxEmpty, maxChars = DEFAULT_GROUP
|
|
|
13146
13297
|
if (amount !== null) amounts.push(amount);
|
|
13147
13298
|
}
|
|
13148
13299
|
const amountReliable = items.length >= 2 && amounts.length === items.length;
|
|
13300
|
+
const groupPrompt = (activeRuleFor(group.title)?.aiGroup?.groupSummary?.prompt ?? "").trim();
|
|
13149
13301
|
batches.push({
|
|
13150
13302
|
groupId: sub.id,
|
|
13151
13303
|
parentGroupId: group.id,
|
|
@@ -13155,7 +13307,8 @@ function collectGroupSummaryBatches(groups, isCtxEmpty, maxChars = DEFAULT_GROUP
|
|
|
13155
13307
|
totalCount: allRows.length,
|
|
13156
13308
|
kind,
|
|
13157
13309
|
...kind === "internal-message" ? { hint: INTERNAL_MESSAGE_SUMMARY_HINT2 } : {},
|
|
13158
|
-
|
|
13310
|
+
...groupPrompt ? { prompt: groupPrompt } : {},
|
|
13311
|
+
suggestedMaxChars: maxCharsFor(group.title),
|
|
13159
13312
|
...emptySkipped > 0 ? { emptySkipped } : {},
|
|
13160
13313
|
items,
|
|
13161
13314
|
stats: {
|
|
@@ -13200,14 +13353,9 @@ async function loadCtxEmptyPredicate(env, groups, args = {}) {
|
|
|
13200
13353
|
async function runGroupSummaryContext(args, env) {
|
|
13201
13354
|
const groups = await readFinalGroups(args, env);
|
|
13202
13355
|
const { isCtxEmpty, warnings: emptyWarnings } = await loadCtxEmptyPredicate(env, groups, args);
|
|
13203
|
-
const
|
|
13204
|
-
|
|
13205
|
-
|
|
13206
|
-
DEFAULT_GROUP_SUMMARY_MAX,
|
|
13207
|
-
20,
|
|
13208
|
-
1e3
|
|
13209
|
-
);
|
|
13210
|
-
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);
|
|
13211
13359
|
const totalCount = totalTodoCount(groups);
|
|
13212
13360
|
const warnings = [...emptyWarnings];
|
|
13213
13361
|
const skippedEmpty = batches.reduce((sum, batch) => sum + (batch.emptySkipped ?? 0), 0);
|
|
@@ -13243,7 +13391,7 @@ async function runGroupSummaryContext(args, env) {
|
|
|
13243
13391
|
/** CLI 固定文案的汇总项个数(不进批次,`smartGroup` 阶段已写好) */
|
|
13244
13392
|
deterministicGroups,
|
|
13245
13393
|
tail: GROUP_SUMMARY_TAIL,
|
|
13246
|
-
suggestedMaxChars:
|
|
13394
|
+
...distinctChars.length === 1 ? { suggestedMaxChars: distinctChars[0] } : { suggestedMaxCharsList: distinctChars }
|
|
13247
13395
|
}
|
|
13248
13396
|
},
|
|
13249
13397
|
warnings
|
|
@@ -13294,14 +13442,9 @@ async function runGroupSummary(args, env) {
|
|
|
13294
13442
|
const groups = await readFinalGroups(args, env);
|
|
13295
13443
|
const summaries = readAiGroupSummaries(args.aiGroupSummaries);
|
|
13296
13444
|
const { isCtxEmpty, warnings: emptyWarnings } = await loadCtxEmptyPredicate(env, groups, args);
|
|
13297
|
-
const
|
|
13298
|
-
|
|
13299
|
-
|
|
13300
|
-
DEFAULT_GROUP_SUMMARY_MAX,
|
|
13301
|
-
20,
|
|
13302
|
-
1e3
|
|
13303
|
-
);
|
|
13304
|
-
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);
|
|
13305
13448
|
const knownGroupIds = new Set(batches.map((batch) => batch.groupId));
|
|
13306
13449
|
for (const groupId of summaries.keys()) {
|
|
13307
13450
|
if (!knownGroupIds.has(groupId)) {
|
|
@@ -13322,6 +13465,7 @@ async function runGroupSummary(args, env) {
|
|
|
13322
13465
|
for (const group of groups) {
|
|
13323
13466
|
if (group.topPriority) continue;
|
|
13324
13467
|
const kind = detectBusinessKind(group.title);
|
|
13468
|
+
const groupMaxChars = groupMaxCharsFor(group.title);
|
|
13325
13469
|
for (const sub of groupItemsOf(group)) {
|
|
13326
13470
|
if (isDeterministicGroupKind(kind)) {
|
|
13327
13471
|
if ((sub.summary ?? "").trim() === "") {
|
|
@@ -13333,7 +13477,7 @@ async function runGroupSummary(args, env) {
|
|
|
13333
13477
|
}
|
|
13334
13478
|
filled += 1;
|
|
13335
13479
|
summarizedGroupCount += 1;
|
|
13336
|
-
if (summary2.length >
|
|
13480
|
+
if (summary2.length > groupMaxChars) tooLong += 1;
|
|
13337
13481
|
const batch2 = batches.find((item) => item.groupId === sub.id);
|
|
13338
13482
|
if (batch2 && batch2.stats.createrPhrase && !summary2.includes(batch2.stats.createrPhrase)) {
|
|
13339
13483
|
missingCreater += 1;
|
|
@@ -13352,7 +13496,7 @@ async function runGroupSummary(args, env) {
|
|
|
13352
13496
|
}
|
|
13353
13497
|
filled += 1;
|
|
13354
13498
|
summarizedGroupCount += 1;
|
|
13355
|
-
if (summary.length >
|
|
13499
|
+
if (summary.length > groupMaxChars) tooLong += 1;
|
|
13356
13500
|
const batch = batches.find((item) => item.groupId === sub.id);
|
|
13357
13501
|
if (batch && batch.stats.createrPhrase && !summary.includes(batch.stats.createrPhrase)) {
|
|
13358
13502
|
missingCreater += 1;
|
|
@@ -13361,7 +13505,7 @@ async function runGroupSummary(args, env) {
|
|
|
13361
13505
|
}
|
|
13362
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`);
|
|
13363
13507
|
if (tooLong > 0) {
|
|
13364
|
-
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`);
|
|
13365
13509
|
}
|
|
13366
13510
|
if (missingCreater > 0) {
|
|
13367
13511
|
warnings.push(
|
|
@@ -13465,8 +13609,10 @@ var inputSchema = schemaOf({
|
|
|
13465
13609
|
groupFocus: { type: "string" },
|
|
13466
13610
|
maxCharsPerBatch: { type: "integer", minimum: 500, maximum: 2e5, default: 24e3 },
|
|
13467
13611
|
maxItemsPerBatch: { type: "integer", minimum: 1, maximum: 500, default: 100 },
|
|
13468
|
-
|
|
13469
|
-
|
|
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 },
|
|
13470
13616
|
detailConcurrency: { type: "integer", minimum: 1, maximum: 32, default: 10 },
|
|
13471
13617
|
detailTimeoutMs: { type: "integer", minimum: 1e3, maximum: 6e4, default: 1e4 },
|
|
13472
13618
|
skillTiming: { type: "object" },
|