weaver-work-cli 0.1.39 → 0.1.40

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (103) hide show
  1. package/README.md +4 -2
  2. package/dist/chunks/{archive-ENZYBBME.js → archive-JHTONRST.js} +2 -2
  3. package/dist/chunks/{archive-oa-YWLEC5V4.js → archive-oa-FCHLCPHC.js} +2 -2
  4. package/dist/chunks/{asset-OOV6DWPA.js → asset-RLIHC7DB.js} +2 -2
  5. package/dist/chunks/{asset-idle-RE632MY5.js → asset-idle-KVOFTLCP.js} +2 -2
  6. package/dist/chunks/{attachment-content-RWN2FCLL.js → attachment-content-RZYDB3MB.js} +3 -3
  7. package/dist/chunks/{blog-PEPOJAL7.js → blog-42OZTJNP.js} +2 -2
  8. package/dist/chunks/{caizhilian-WYIQDVPJ.js → caizhilian-KRK547K5.js} +2 -2
  9. package/dist/chunks/{calendar-CIARBAOX.js → calendar-RTWAMKHD.js} +2 -2
  10. package/dist/chunks/{chunk-L4N7B7ZD.js → chunk-4CTESSKI.js} +4 -4
  11. package/dist/chunks/{chunk-XXJOSZTQ.js → chunk-4TEDNCON.js} +43 -5
  12. package/dist/chunks/chunk-57IECMWX.js +487 -0
  13. package/dist/chunks/{chunk-CQHGNCK2.js → chunk-7BRU4EFH.js} +13 -7
  14. package/dist/chunks/{chunk-KTCB5R5H.js → chunk-7E6MUOEK.js} +2 -2
  15. package/dist/chunks/{chunk-I2HB737U.js → chunk-7U577Q7U.js} +2 -2
  16. package/dist/chunks/{chunk-BJGXMFGD.js → chunk-CAQNBBQA.js} +2 -2
  17. package/dist/chunks/{chunk-MUQUHKPG.js → chunk-CXRQWOZ5.js} +2 -2
  18. package/dist/chunks/{chunk-T7JDJJ7H.js → chunk-FLS4DPGP.js} +110 -16
  19. package/dist/chunks/{chunk-P2DAISYW.js → chunk-I566ZYNF.js} +1 -1
  20. package/dist/chunks/{chunk-36DIFZAH.js → chunk-IZSSVYAG.js} +2 -2
  21. package/dist/chunks/{chunk-EINRJHQ3.js → chunk-JWRZM2H2.js} +3 -3
  22. package/dist/chunks/{chunk-F2EQXUEE.js → chunk-LFMSDBZN.js} +97 -14
  23. package/dist/chunks/{chunk-GVPJZXJ2.js → chunk-LN447PY2.js} +91 -50
  24. package/dist/chunks/{chunk-K3RUEEOL.js → chunk-NETCCARD.js} +2 -2
  25. package/dist/chunks/{chunk-YS5DPN4T.js → chunk-NJKREDA3.js} +1 -1
  26. package/dist/chunks/{chunk-ZXRNHZTE.js → chunk-SPRHHSVC.js} +2 -2
  27. package/dist/chunks/{chunk-HJYVHXUQ.js → chunk-T6EGVBKU.js} +1 -1
  28. package/dist/chunks/{chunk-NLK2RZKG.js → chunk-VNBU55SL.js} +428 -145
  29. package/dist/chunks/{chunk-EZGFHJFW.js → chunk-WFFNM65B.js} +26 -7
  30. package/dist/chunks/{conflict-DRMDOL56.js → conflict-VR55AOOO.js} +2 -2
  31. package/dist/chunks/{contract-73MERZWN.js → contract-HI4FNPYE.js} +2 -2
  32. package/dist/chunks/{cowork-HNGBPD7A.js → cowork-HJLI353D.js} +12 -5
  33. package/dist/chunks/{ebuilder-form-OY6DVNRK.js → ebuilder-form-HTGI63UU.js} +3 -3
  34. package/dist/chunks/{ehr-RAQNEQO7.js → ehr-GYXIYH3A.js} +2 -2
  35. package/dist/chunks/env-DW3G4HUO.js +19 -0
  36. package/dist/chunks/{esb-6XV7C7YV.js → esb-I5INCEFE.js} +4 -4
  37. package/dist/chunks/factory-TKXGXS6L.js +30 -0
  38. package/dist/chunks/{fna-XTSRB7G7.js → fna-K2MHTQ24.js} +2 -2
  39. package/dist/chunks/group-chat-VYBNMJLG.js +18 -0
  40. package/dist/chunks/{host-VGPVP7YF.js → host-256GVCAH.js} +3 -3
  41. package/dist/chunks/{host-A7J6GDUP.js → host-D5SERMAJ.js} +3 -3
  42. package/dist/chunks/{host-3F5UM5GN.js → host-JM4YVHFM.js} +3 -3
  43. package/dist/chunks/{host-YAQAPYNP.js → host-L3VLITMT.js} +3 -3
  44. package/dist/chunks/{host-YMBXWFWX.js → host-ZUQTJYYK.js} +3 -3
  45. package/dist/chunks/{hrm-TLHKC545.js → hrm-VLRBKTZB.js} +3 -3
  46. package/dist/chunks/{im-YOUCFMUK.js → im-QK3VTLXK.js} +8 -8
  47. package/dist/chunks/{invoice-WNBS2B4C.js → invoice-T5JTA32H.js} +3 -3
  48. package/dist/chunks/{jiuchuanhui-XABWS5RN.js → jiuchuanhui-P2FNEQVZ.js} +2 -2
  49. package/dist/chunks/{lazy-dispatch-NLZ5UQQI.js → lazy-dispatch-XRRI46M6.js} +4 -4
  50. package/dist/chunks/{mail-LRYMBFNL.js → mail-3Y7MJ6PS.js} +9 -4
  51. package/dist/chunks/{meeting-ESXL6MFI.js → meeting-M7LTXGJE.js} +11 -10
  52. package/dist/chunks/{okr-EOV65SSF.js → okr-OBC6S67L.js} +2 -2
  53. package/dist/chunks/{plan-YFPVKW6Y.js → plan-5H6I53SK.js} +2 -2
  54. package/dist/chunks/{project-MDVZUYQW.js → project-L75QZV4S.js} +2 -2
  55. package/dist/chunks/{registry-QCLZEDAP.js → registry-KMHCPAAD.js} +9 -8
  56. package/dist/chunks/{registry-OZSMDVPP.js → registry-QGHFNUWS.js} +2 -2
  57. package/dist/chunks/{registry-VT5Y2HLA.js → registry-RXPN6BBT.js} +4 -4
  58. package/dist/chunks/{registry-YX4CSEMD.js → registry-UGRBCBHO.js} +2 -2
  59. package/dist/chunks/{room-recommend-L3MWH4JW.js → room-recommend-A3UDC3CA.js} +4 -4
  60. package/dist/chunks/{schedule-UASAVDVD.js → schedule-5GCACCK7.js} +4 -4
  61. package/dist/chunks/{workflow-KDGIUCNW.js → workflow-M5ZJ7DWF.js} +6 -6
  62. package/dist/index.js +28 -28
  63. package/dist/internal/e10/auth/commands.js +109 -56
  64. package/dist/internal/e10/auth/session.js +11 -1
  65. package/dist/internal/e10/auth/xiaoe.js +29 -4
  66. package/dist/internal/e10/client.js +13 -0
  67. package/dist/internal/e10/context.js +14 -6
  68. package/dist/internal/e10/request-runtime.js +9 -0
  69. package/dist/shortcuts/cowork/operations/item-write.js +10 -2
  70. package/dist/shortcuts/mail/operations/mail-send.js +8 -2
  71. package/dist/shortcuts/meeting/operations/eb/catalog.js +5 -1
  72. package/dist/shortcuts/meeting/operations/eb/create-flow.js +381 -104
  73. package/dist/shortcuts/meeting/operations/eb/crm-search.js +87 -5
  74. package/dist/shortcuts/meeting/operations/eb/flow-memory.js +49 -0
  75. package/dist/shortcuts/meeting/operations/eb/group-chat.js +583 -0
  76. package/dist/shortcuts/meeting/operations/eb/index.js +2 -0
  77. package/dist/shortcuts/meeting/operations/eb/room-recommend.js +19 -3
  78. package/dist/shortcuts/meeting/operations/eb/room-summary.js +2 -0
  79. package/dist/shortcuts/meeting/operations/eb/usage-cache.js +99 -0
  80. package/dist/shortcuts/meeting/operations/from-group-chat.js +35 -12
  81. package/dist/shortcuts/workflow/operations/form.js +21 -2
  82. package/dist/shortcuts/workflow/operations/todoSmartConvert/aigroupRules.js +52 -1
  83. package/dist/shortcuts/workflow/operations/todoSmartConvert/summaryCache.js +10 -9
  84. package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.collect.js +28 -2
  85. package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.core.js +1 -0
  86. package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.group.js +17 -9
  87. package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.js +1 -0
  88. package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.summary.js +14 -2
  89. package/docs/e10-auth.md +15 -0
  90. package/package.json +1 -1
  91. package/scripts/mcp-meeting.mjs +234 -0
  92. package/skills/weaver-e10-cowork/references/cowork-write.md +1 -1
  93. package/skills/weaver-e10-mail/references/mail-send.md +2 -0
  94. package/skills/weaver-e10-meeting/SKILL.md +88 -25
  95. package/skills/weaver-e10-meeting/references/meeting-minute-file.md +25 -11
  96. package/skills/weaver-e10-meeting.zip +0 -0
  97. package/skills/weaver-e10-shared/SKILL.md +1 -1
  98. package/skills/weaver-e10-shared/references/e10-auth-and-session.md +1 -1
  99. package/skills/weaver-e10-workflow/SKILL.md +4 -0
  100. package/skills/weaver-e10-workflow/aigroup/default.json +12 -0
  101. package/skills/weaver-e10-workflow/references/todo-smart-convert.md +17 -11
  102. package/skills/weaver-e10-workflow/tools/todo-summary.cjs +73 -23
  103. package/dist/chunks/{chunk-2LV74IWP.js → chunk-E7OK5WD5.js} +5 -5
@@ -1,31 +1,43 @@
1
1
  import { createRequire as __esbuildCreateRequire } from 'node:module';
2
2
  const require = __esbuildCreateRequire(import.meta.url);
3
3
  import {
4
+ meetingEbGroupChatOperations
5
+ } from "./chunk-57IECMWX.js";
6
+ import {
7
+ dayOf,
4
8
  ebRoomRecommendOperation,
9
+ filterUsages,
10
+ invalidateDayUsages,
11
+ loadDayUsages,
5
12
  loadRooms,
6
13
  recommendRooms,
7
14
  rememberFrequentRoom
8
- } from "./chunk-T7JDJJ7H.js";
15
+ } from "./chunk-FLS4DPGP.js";
9
16
  import {
10
17
  meetingEbScheduleOperations
11
- } from "./chunk-L4N7B7ZD.js";
18
+ } from "./chunk-4CTESSKI.js";
19
+ import {
20
+ cacheScopeSuffix,
21
+ readCache,
22
+ writeCache
23
+ } from "./chunk-I566ZYNF.js";
12
24
  import {
13
25
  ebMeetingWritePreflight,
14
26
  fetchEbAppSettings,
15
27
  findCommonFreeSlots,
16
28
  meetingEbConflictOperations
17
- } from "./chunk-EINRJHQ3.js";
29
+ } from "./chunk-JWRZM2H2.js";
18
30
  import {
19
31
  PENDING_MARK,
20
32
  listMeetingAttachments,
21
33
  meetingAttachmentContentOperations,
22
34
  renderDocx
23
- } from "./chunk-KTCB5R5H.js";
35
+ } from "./chunk-7E6MUOEK.js";
24
36
  import {
25
37
  meetingEnvOperations,
26
38
  meetingStateDir,
27
39
  resolveMeetingEnvMode
28
- } from "./chunk-YS5DPN4T.js";
40
+ } from "./chunk-NJKREDA3.js";
29
41
  import {
30
42
  EB_BASE,
31
43
  EB_ENDPOINTS,
@@ -57,7 +69,7 @@ import {
57
69
  toIdString,
58
70
  verifyLease,
59
71
  writeBody
60
- } from "./chunk-CQHGNCK2.js";
72
+ } from "./chunk-7BRU4EFH.js";
61
73
 
62
74
  // src/shortcuts/meeting/operations/meetings.ts
63
75
  function overlapsDate(beginDatetime, endDatetime, date) {
@@ -2223,7 +2235,7 @@ var meetingAttachmentAttach = {
2223
2235
  if (mode === "append" && existingIds.length === 0) {
2224
2236
  existingIds.push(...beforeIds);
2225
2237
  }
2226
- const { getMeetingOperation: getMeetingOperation2 } = await import("./registry-QCLZEDAP.js");
2238
+ const { getMeetingOperation: getMeetingOperation2 } = await import("./registry-KMHCPAAD.js");
2227
2239
  const list = getMeetingOperation2("meeting.eb.meeting.list");
2228
2240
  let fileId = incomingFileId;
2229
2241
  let name = String(args.name ?? "").trim();
@@ -2311,7 +2323,7 @@ function textOf(value) {
2311
2323
  return value === void 0 || value === null ? "" : String(value);
2312
2324
  }
2313
2325
  async function readMinute(env, id) {
2314
- const { getMeetingOperation: getMeetingOperation2 } = await import("./registry-QCLZEDAP.js");
2326
+ const { getMeetingOperation: getMeetingOperation2 } = await import("./registry-KMHCPAAD.js");
2315
2327
  const detail = getMeetingOperation2("meeting.eb.minute.detail");
2316
2328
  const result = await detail.handler({ id }, env);
2317
2329
  const row = result?.data?.data;
@@ -2390,7 +2402,7 @@ var meetingMinuteWriteContent = {
2390
2402
  } else {
2391
2403
  statusReason = "\u4EC5\u6E05\u7A7A\u5185\u5BB9\uFF0C\u672A\u6539\u72B6\u6001";
2392
2404
  }
2393
- const { getMeetingOperation: getMeetingOperation2 } = await import("./registry-QCLZEDAP.js");
2405
+ const { getMeetingOperation: getMeetingOperation2 } = await import("./registry-KMHCPAAD.js");
2394
2406
  const prepare = getMeetingOperation2("meeting.eb.minute.update.prepare");
2395
2407
  const apply = getMeetingOperation2("meeting.eb.minute.update.apply");
2396
2408
  const prepared = await prepare.handler({ id, mt_id: mtId, ...patch }, env);
@@ -2506,8 +2518,9 @@ var meetingMinuteContentOperations = [
2506
2518
  ];
2507
2519
 
2508
2520
  // src/shortcuts/meeting/operations/from-group-chat.ts
2509
- var FLOW_GENERATE_MINUTES = "1325287772302863633";
2510
- var FLOW_GENERATE_DOCUMENT = "1325287772302863628";
2521
+ var FLOW_GENERATE_MINUTES = "7204936B2ACC4B12A1CECD1DAB60DD97";
2522
+ var FLOW_GENERATE_DOCUMENT = "1F638AE31BC746C28A1D9DCF26D91037";
2523
+ var DEFAULT_AI_MINUTE_PAGE = "1250830691712172036";
2511
2524
  function textOf2(value) {
2512
2525
  return value === void 0 || value === null ? "" : String(value);
2513
2526
  }
@@ -2727,13 +2740,13 @@ var meetingMinuteFromGroupChat = {
2727
2740
  },
2728
2741
  flowGenerateMinutes: {
2729
2742
  type: "string",
2730
- pattern: "^\\d+$",
2731
- description: "ESB\u300C\u6839\u636E\u89E3\u6790\u6587\u672C\u751F\u6210\u667A\u80FD\u7EAA\u8981\u6587\u672C\u300D\u6D41\u7A0B id\u3002\u7701\u7565\u65F6\u7528\u5185\u7F6E\u9ED8\u8BA4\u503C\uFF1B**\u6362\u79DF\u6237\u5FC5\u987B\u8986\u76D6**\uFF08\u6D41\u7A0B id \u662F\u79DF\u6237\u7EA7\u914D\u7F6E\uFF0C\u5404\u73AF\u5883\u4E0D\u540C\uFF09"
2743
+ pattern: "^(\\d+|[0-9A-Fa-f]{32})$",
2744
+ description: "ESB\u300C\u6839\u636E\u89E3\u6790\u6587\u672C\u751F\u6210\u667A\u80FD\u7EAA\u8981\u6587\u672C\u300D\u7684 id\u3002\u53EF\u4F20 19 \u4F4D\u6570\u5B57 id \u6216 32 \u4F4D\u5341\u516D\u8FDB\u5236 primary_key\uFF08GUID \u4F1A\u81EA\u52A8\u8D70\u552F\u4E00\u503C\u89E6\u53D1 uniqueIndent\uFF09\u3002\u7701\u7565\u65F6\u7528\u5185\u7F6E\u9ED8\u8BA4\u503C\uFF1B\u6362\u79DF\u6237\u5FC5\u987B\u8986\u76D6"
2732
2745
  },
2733
2746
  flowGenerateDocument: {
2734
2747
  type: "string",
2735
- pattern: "^\\d+$",
2736
- description: "ESB\u300C\u4FDD\u5B58\u89E3\u6790\u5E76\u751F\u6210\u6587\u6863\u300D\u6D41\u7A0B id\u3002\u7701\u7565\u65F6\u7528\u5185\u7F6E\u9ED8\u8BA4\u503C\uFF1B\u6362\u79DF\u6237\u5FC5\u987B\u8986\u76D6"
2748
+ pattern: "^(\\d+|[0-9A-Fa-f]{32})$",
2749
+ description: "ESB\u300C\u4FDD\u5B58\u89E3\u6790\u5E76\u751F\u6210\u6587\u6863\u300D\u7684 id\uFF0C\u652F\u6301\u6570\u5B57 id \u6216 32 \u4F4D primary_key\uFF1B\u7701\u7565\u65F6\u7528\u5185\u7F6E\u9ED8\u8BA4\u503C"
2737
2750
  }
2738
2751
  },
2739
2752
  required: ["mt_id"]
@@ -2748,7 +2761,7 @@ var meetingMinuteFromGroupChat = {
2748
2761
  const mtId = textOf2(args.mt_id).trim();
2749
2762
  if (!mtId) throw meetingValidationError("mt_id_required", "\u5FC5\u987B\u63D0\u4F9B\u4F1A\u8BAE id\uFF08mt_id\uFF09");
2750
2763
  const pipeline = ["text", "minutes", "document"].includes(args.pipeline) ? args.pipeline : "text";
2751
- const { getMeetingOperation: getMeetingOperation2 } = await import("./registry-QCLZEDAP.js");
2764
+ const { getMeetingOperation: getMeetingOperation2 } = await import("./registry-KMHCPAAD.js");
2752
2765
  const ctx = env.ctx;
2753
2766
  let stepStart = Date.now();
2754
2767
  const listed = await getMeetingOperation2("meeting.eb.meeting.list").handler(
@@ -2772,9 +2785,9 @@ var meetingMinuteFromGroupChat = {
2772
2785
  }
2773
2786
  mark("readMeeting", stepStart);
2774
2787
  const pullStart = Date.now();
2775
- const { createImHost } = await import("./host-3F5UM5GN.js");
2788
+ const { createImHost } = await import("./host-JM4YVHFM.js");
2776
2789
  const { createImContinuationSigner } = await import("./continuation-2CKSBLA6.js");
2777
- const { getImOperation } = await import("./registry-OZSMDVPP.js");
2790
+ const { getImOperation } = await import("./registry-QGHFNUWS.js");
2778
2791
  const imEnv = { ctx, host: createImHost(ctx), continuation: createImContinuationSigner(ctx) };
2779
2792
  const syncOp = getImOperation("im.msg.sync.group");
2780
2793
  const chatWindow = computeChatWindow(meeting);
@@ -2842,7 +2855,7 @@ var meetingMinuteFromGroupChat = {
2842
2855
  try {
2843
2856
  const { readFile: readFile5 } = await import("node:fs/promises");
2844
2857
  const buffer = await readFile5(file);
2845
- const { extractText } = await import("./attachment-content-RWN2FCLL.js");
2858
+ const { extractText } = await import("./attachment-content-RZYDB3MB.js");
2846
2859
  const extracted = extractText(buffer, file, "");
2847
2860
  if (extracted.text.trim()) {
2848
2861
  extraSections.push(`\u3010\u6750\u6599\uFF1A${file.split(/[\\/]/).pop() ?? file}\u3011
@@ -2912,7 +2925,8 @@ ${groupTranscript}` : ""
2912
2925
  } catch {
2913
2926
  }
2914
2927
  if (!aiPageId) {
2915
- warnings.push("\u672A\u53D6\u5230 mt_minutes_ai_page\uFF08\u53EF\u4F20 aiPageId\uFF09\uFF1BESB \u89E3\u6790\u8BE5\u5B57\u6BB5\u53EF\u80FD\u5FC5\u586B\uFF0C\u7F3A\u5B83\u4F1A\u5931\u8D25");
2928
+ aiPageId = DEFAULT_AI_MINUTE_PAGE;
2929
+ warnings.push(`\u672A\u4ECE\u5DF2\u6709\u7EAA\u8981\u53D6\u5230 mt_minutes_ai_page\uFF0C\u5DF2\u7528\u672C\u79DF\u6237\u9ED8\u8BA4\u503C ${DEFAULT_AI_MINUTE_PAGE}`);
2916
2930
  }
2917
2931
  }
2918
2932
  stepStart = Date.now();
@@ -2957,6 +2971,7 @@ ${groupTranscript}` : ""
2957
2971
  pipeline,
2958
2972
  aiPageId: aiPageId || null
2959
2973
  };
2974
+ let documentIdFromFlow = "";
2960
2975
  if (pipeline === "text") {
2961
2976
  result.timings = { ...timings, total: Date.now() - startedAt };
2962
2977
  return meetingSuccess("meeting.minute.fromGroupChat", result, warnings.length > 0 ? { warnings } : void 0);
@@ -2969,15 +2984,16 @@ ${groupTranscript}` : ""
2969
2984
  if (!employeeId) {
2970
2985
  warnings.push("\u672A\u53D6\u5230 ESB \u89E6\u53D1\u4EBA id\uFF08employeeId\uFF09\uFF0C\u5DF2\u8DF3\u8FC7\u540E\u7EED ESB \u8C03\u7528");
2971
2986
  } else {
2972
- const { createEsbHost } = await import("./host-VGPVP7YF.js");
2987
+ const { createEsbHost } = await import("./host-256GVCAH.js");
2973
2988
  const { createEsbContinuationSigner } = await import("./continuation-NLECEJPX.js");
2974
- const { getEsbOperation } = await import("./registry-VT5Y2HLA.js");
2989
+ const { getEsbOperation } = await import("./registry-RXPN6BBT.js");
2975
2990
  const esbEnv = { ctx, host: createEsbHost(ctx), continuation: createEsbContinuationSigner(ctx) };
2976
2991
  const prepareOp = getEsbOperation("esb.trigger.prepare");
2977
2992
  const applyOp = getEsbOperation("esb.trigger.apply");
2978
2993
  const trigger = async (flowId, mainTable) => {
2994
+ const target = /^\d+$/.test(flowId) ? { esbFlowId: flowId } : { uniqueIndent: flowId };
2979
2995
  const pre = await prepareOp.handler(
2980
- { employeeId, esbFlowId: flowId, customParams: { mainTable } },
2996
+ { employeeId, ...target, customParams: { mainTable } },
2981
2997
  esbEnv
2982
2998
  );
2983
2999
  return applyOp.handler({ continuation: pre?.data?.continuation, confirm: true }, esbEnv);
@@ -2996,7 +3012,10 @@ ${groupTranscript}` : ""
2996
3012
  warnings.push("\u7EAA\u8981\u6587\u6848\u4E3A\u7A7A\uFF0C\u5DF2\u8DF3\u8FC7\u751F\u6210\u6587\u6863\uFF08\u6587\u672C\u751F\u6210\u53EF\u80FD\u4ECD\u5728\u540E\u53F0\u8FDB\u884C\uFF0C\u53EF\u7A0D\u540E\u7528 meeting.minute.parseStatus \u590D\u67E5\uFF09");
2997
3013
  } else {
2998
3014
  try {
2999
- await trigger(flowDocument, { parse_content: parseContent, mt_minute_id: minuteId });
3015
+ const docResult = await trigger(flowDocument, { parse_content: parseContent, mt_minute_id: minuteId });
3016
+ documentIdFromFlow = textOf2(
3017
+ docResult?.data?.actionData?.responseData?.customData?.mainTable?.wdID
3018
+ );
3000
3019
  mark("esbDocument", stepDocStart);
3001
3020
  } catch (error) {
3002
3021
  warnings.push(`ESB \u751F\u6210\u6587\u6863\u672A\u6B63\u5E38\u8FD4\u56DE\uFF08${String(error?.message ?? error).slice(0, 100)}\uFF09`);
@@ -3008,7 +3027,7 @@ ${groupTranscript}` : ""
3008
3027
  const row = final?.data?.data ?? {};
3009
3028
  result.finalStatus = textOf2(row.minutes_status);
3010
3029
  result.parseContentLength = textOf2(row.parse_content).length;
3011
- result.documentId = textOf2(row.mt_minutes) || null;
3030
+ result.documentId = textOf2(row.mt_minutes) || documentIdFromFlow || null;
3012
3031
  result.timings = { ...timings, total: Date.now() - startedAt };
3013
3032
  return meetingSuccess("meeting.minute.fromGroupChat", result, warnings.length > 0 ? { warnings } : void 0);
3014
3033
  }
@@ -3155,7 +3174,7 @@ var meetingDecisionNotifyGroup = {
3155
3174
  const warnings = [];
3156
3175
  const mtId = textOf3(args.mt_id).trim();
3157
3176
  if (!mtId) throw meetingValidationError("mt_id_required", "\u5FC5\u987B\u63D0\u4F9B\u4F1A\u8BAE id\uFF08mt_id\uFF09");
3158
- const { getMeetingOperation: getMeetingOperation2 } = await import("./registry-QCLZEDAP.js");
3177
+ const { getMeetingOperation: getMeetingOperation2 } = await import("./registry-KMHCPAAD.js");
3159
3178
  const ctx = env.ctx;
3160
3179
  const listed = await getMeetingOperation2("meeting.eb.meeting.list").handler(
3161
3180
  { mt_id: mtId, pageNo: 1, pageSize: 1 },
@@ -3219,7 +3238,7 @@ var meetingDecisionNotifyGroup = {
3219
3238
  charCount: formatted.text.length,
3220
3239
  text: formatted.text
3221
3240
  };
3222
- const { createImHost } = await import("./host-3F5UM5GN.js");
3241
+ const { createImHost } = await import("./host-JM4YVHFM.js");
3223
3242
  const imHost = createImHost(ctx);
3224
3243
  let displayText = formatted.text;
3225
3244
  let wireText = formatted.text;
@@ -3227,7 +3246,7 @@ var meetingDecisionNotifyGroup = {
3227
3246
  const mentioned = [];
3228
3247
  if (args.mention !== false) {
3229
3248
  try {
3230
- const { getImOperation } = await import("./registry-OZSMDVPP.js");
3249
+ const { getImOperation } = await import("./registry-QGHFNUWS.js");
3231
3250
  const membersResult = await getImOperation("im.group.users").handler(
3232
3251
  { groupId },
3233
3252
  { ctx, host: imHost }
@@ -3457,7 +3476,7 @@ var meetingPipelineRun = {
3457
3476
  const needsConfirm = level === "tasks" || level === "notify";
3458
3477
  const confirmed = args.confirm === true;
3459
3478
  const executedLevel = needsConfirm && !confirmed ? "document" : level;
3460
- const { getMeetingOperation: getMeetingOperation2 } = await import("./registry-QCLZEDAP.js");
3479
+ const { getMeetingOperation: getMeetingOperation2 } = await import("./registry-KMHCPAAD.js");
3461
3480
  const ctx = env.ctx;
3462
3481
  let stepStart = Date.now();
3463
3482
  const reuseMinuteId = textOf4(args.minuteId).trim();
@@ -3526,7 +3545,7 @@ var meetingPipelineRun = {
3526
3545
  ]);
3527
3546
  }
3528
3547
  stepStart = Date.now();
3529
- const { createHrmHost } = await import("./host-A7J6GDUP.js");
3548
+ const { createHrmHost } = await import("./host-D5SERMAJ.js");
3530
3549
  const { getHrmOperation } = await import("./registry-NYPYMZXG.js");
3531
3550
  const hrmEnv = { ctx, host: createHrmHost(ctx) };
3532
3551
  const queryOp = getHrmOperation("hrm.employee.query");
@@ -3829,7 +3848,7 @@ function formatTimeRange(start, end) {
3829
3848
  }
3830
3849
  async function loadAgendaFromTopics(env, mtId) {
3831
3850
  try {
3832
- const { getMeetingOperation: getMeetingOperation2 } = await import("./registry-QCLZEDAP.js");
3851
+ const { getMeetingOperation: getMeetingOperation2 } = await import("./registry-KMHCPAAD.js");
3833
3852
  const operation = getMeetingOperation2("meeting.eb.topic.list");
3834
3853
  const result = await operation.handler({ mt_id: mtId, pageNo: 1, pageSize: 200 }, env);
3835
3854
  const rows = result.data?.rows ?? [];
@@ -3967,7 +3986,7 @@ async function supplementRowFromDetail(row, mtId, env) {
3967
3986
  const missing = DETAIL_FALLBACK_KEYS.filter((key) => isBlank(row[key]));
3968
3987
  if (missing.length === 0) return { row, filled: [] };
3969
3988
  try {
3970
- const { getMeetingOperation: getMeetingOperation2 } = await import("./registry-QCLZEDAP.js");
3989
+ const { getMeetingOperation: getMeetingOperation2 } = await import("./registry-KMHCPAAD.js");
3971
3990
  const detailOperation = getMeetingOperation2("meeting.eb.meeting.detail");
3972
3991
  const result = await detailOperation.handler({ id: mtId }, env);
3973
3992
  const flat = result?.data?.data ?? result?.data ?? {};
@@ -4141,7 +4160,7 @@ var meetingInvitationRender = {
4141
4160
  };
4142
4161
  dataSource = "payload";
4143
4162
  } else {
4144
- const { getMeetingOperation: getMeetingOperation2 } = await import("./registry-QCLZEDAP.js");
4163
+ const { getMeetingOperation: getMeetingOperation2 } = await import("./registry-KMHCPAAD.js");
4145
4164
  const listOperation = getMeetingOperation2("meeting.eb.meeting.list");
4146
4165
  try {
4147
4166
  const listed = await listOperation.handler({ mt_id: mtId, pageNo: 1, pageSize: 1 }, env);
@@ -4895,7 +4914,7 @@ var meetingSummaryGet = {
4895
4914
  const mtId = textOf5(args.mt_id).trim();
4896
4915
  if (!mtId) throw meetingValidationError("mt_id_required", "\u5FC5\u987B\u63D0\u4F9B\u4F1A\u8BAE id\uFF08mt_id\uFF09");
4897
4916
  const ctx = env.ctx;
4898
- const { getMeetingOperation: getMeetingOperation2 } = await import("./registry-QCLZEDAP.js");
4917
+ const { getMeetingOperation: getMeetingOperation2 } = await import("./registry-KMHCPAAD.js");
4899
4918
  const warnings = [];
4900
4919
  const timings = {};
4901
4920
  const include = Array.isArray(args.include) && args.include.length > 0 ? args.include.filter((item) => ALL_SECTIONS.includes(item)) : ALL_SECTIONS;
@@ -5031,9 +5050,9 @@ var meetingSummaryGet = {
5031
5050
  warnings.push("\u8BE5\u4F1A\u8BAE\u6CA1\u6709\u5173\u8054\u7FA4\u804A\uFF08imchat_groupid \u4E3A\u7A7A\uFF09\uFF0Cchat \u6BB5\u4E3A null");
5032
5051
  } else {
5033
5052
  try {
5034
- const { createImHost } = await import("./host-3F5UM5GN.js");
5053
+ const { createImHost } = await import("./host-JM4YVHFM.js");
5035
5054
  const { createImContinuationSigner } = await import("./continuation-2CKSBLA6.js");
5036
- const { getImOperation } = await import("./registry-OZSMDVPP.js");
5055
+ const { getImOperation } = await import("./registry-QGHFNUWS.js");
5037
5056
  const imEnv = {
5038
5057
  ctx,
5039
5058
  // 测试环境靠 env.imHost 注入假实现,否则会真的打到线上群聊
@@ -5157,7 +5176,7 @@ var meetingFormFields = {
5157
5176
  hint: "\u6CA1\u89E3\u6790\u5230\u8BE5\u8868\u7684 objId\uFF08\u53EF\u80FD\u5F53\u524D\u73AF\u5883\u6CA1\u6709\u8FD9\u5F20\u8868\uFF0C\u6216\u8D26\u53F7\u65E0\u6743\u9650\uFF09"
5158
5177
  }, { warnings: resolved.warnings });
5159
5178
  }
5160
- const { createEbuilderFormHost } = await import("./host-YMBXWFWX.js");
5179
+ const { createEbuilderFormHost } = await import("./host-ZUQTJYYK.js");
5161
5180
  const { createEbuilderFormContinuationSigner } = await import("./continuation-RN6PZN2M.js");
5162
5181
  const { executeEbuilderFormOperation } = await import("./operations-5QL3AECO.js");
5163
5182
  const formEnv = {
@@ -5217,7 +5236,7 @@ var MT_STATUS_OVER = "8";
5217
5236
  var CANCELLED_MARK_DELAY_MS = 800;
5218
5237
  async function isCancelledMeeting(env, mtId) {
5219
5238
  try {
5220
- const { getMeetingOperation: getMeetingOperation2 } = await import("./registry-QCLZEDAP.js");
5239
+ const { getMeetingOperation: getMeetingOperation2 } = await import("./registry-KMHCPAAD.js");
5221
5240
  const listed = await getMeetingOperation2("meeting.eb.meeting.list").handler(
5222
5241
  // withCount:false —— 这里只要一行状态,不必额外请求 count(少一次往返,也便于测试替身)
5223
5242
  { mt_id: mtId, pageNo: 1, pageSize: 1, withCount: false },
@@ -5798,11 +5817,33 @@ function unwrapRow(value) {
5798
5817
  const main = asRecord(record.mainTable);
5799
5818
  return main ?? record;
5800
5819
  }
5820
+ function columnarCustomerRows(record) {
5821
+ const idKey = ID_KEYS.find((key) => Array.isArray(record[key]));
5822
+ const nameKey = NAME_KEYS.find((key) => Array.isArray(record[key]));
5823
+ if (!idKey && !nameKey) return [];
5824
+ const idValues = idKey ? record[idKey] : [];
5825
+ const nameValues = nameKey ? record[nameKey] : [];
5826
+ const size = Math.max(idValues.length, nameValues.length);
5827
+ if (size <= 1) return [];
5828
+ const rows = [];
5829
+ for (let index = 0; index < size; index += 1) {
5830
+ const row = {};
5831
+ if (idKey) row[idKey] = idValues[index];
5832
+ if (nameKey) row[nameKey] = nameValues[index];
5833
+ rows.push(row);
5834
+ }
5835
+ return rows;
5836
+ }
5801
5837
  function collectCandidateLists(customData) {
5802
5838
  const found = [];
5803
5839
  const main = asRecord(customData.mainTable);
5804
5840
  if (main) {
5805
- found.push({ source: "customData.mainTable", rows: [main] });
5841
+ const columnar = columnarCustomerRows(main);
5842
+ if (columnar.length > 1) {
5843
+ found.push({ source: "customData.mainTable.columns", rows: columnar });
5844
+ } else {
5845
+ found.push({ source: "customData.mainTable", rows: [main] });
5846
+ }
5806
5847
  for (const key of LIST_KEYS) {
5807
5848
  const value = main[key];
5808
5849
  if (Array.isArray(value)) found.push({ source: `customData.mainTable.${key}`, rows: value });
@@ -5812,6 +5853,16 @@ function collectCandidateLists(customData) {
5812
5853
  const value = customData[key];
5813
5854
  if (Array.isArray(value)) found.push({ source: `customData.${key}`, rows: value });
5814
5855
  }
5856
+ for (const [key, value] of Object.entries(customData)) {
5857
+ if (LIST_KEYS.includes(key)) continue;
5858
+ if (!Array.isArray(value) || value.length === 0) continue;
5859
+ const looksLikeCustomers = value.some((raw) => {
5860
+ const row = unwrapRow(raw);
5861
+ if (!row) return false;
5862
+ return pickFirst(row, ID_KEYS) !== "" || pickFirst(row, NAME_KEYS) !== "";
5863
+ });
5864
+ if (looksLikeCustomers) found.push({ source: `customData.${key}`, rows: value });
5865
+ }
5815
5866
  return found;
5816
5867
  }
5817
5868
  var CONTACT_LIST_KEYS = ["lxr", "contacts", "contactList", "lxrList"];
@@ -5878,6 +5929,19 @@ function parseCrmAddresses(raw) {
5878
5929
  }
5879
5930
  return out;
5880
5931
  }
5932
+ function pickContactArray(row) {
5933
+ const direct = pickRawList(row, CONTACT_LIST_KEYS);
5934
+ if (direct !== void 0) return direct;
5935
+ for (const value of Object.values(row)) {
5936
+ if (!Array.isArray(value) || value.length === 0) continue;
5937
+ const first = asRecord(value[0]);
5938
+ if (!first) continue;
5939
+ const hasName = CONTACT_NAME_KEYS.some((key) => String(first[key] ?? "").trim() !== "");
5940
+ const hasMobile = CONTACT_MOBILE_KEYS.some((key) => String(first[key] ?? "").trim() !== "");
5941
+ if (hasName || hasMobile) return value;
5942
+ }
5943
+ return void 0;
5944
+ }
5881
5945
  function normalizeCustomers(rows, limit) {
5882
5946
  const seen = /* @__PURE__ */ new Map();
5883
5947
  for (const raw of rows) {
@@ -5888,7 +5952,7 @@ function normalizeCustomers(rows, limit) {
5888
5952
  if (customerId === "" && name === "") continue;
5889
5953
  const key = customerId !== "" ? customerId : `name:${name}`;
5890
5954
  if (seen.has(key)) continue;
5891
- const contacts = parseCrmContacts(pickRawList(row, CONTACT_LIST_KEYS));
5955
+ const contacts = parseCrmContacts(pickContactArray(row));
5892
5956
  const addresses = parseCrmAddresses(pickRawList(row, ADDRESS_LIST_KEYS));
5893
5957
  seen.set(key, {
5894
5958
  customerId,
@@ -5985,9 +6049,9 @@ async function runCrmSearchFlow(env, input) {
5985
6049
  if (!employeeId) {
5986
6050
  throw meetingValidationError("crm_employee_required", "\u53D6\u4E0D\u5230\u5F53\u524D\u767B\u5F55\u7528\u6237 id\uFF0C\u65E0\u6CD5\u89E6\u53D1 ESB \u5BA2\u6237\u67E5\u8BE2");
5987
6051
  }
5988
- const { createEsbHost } = await import("./host-VGPVP7YF.js");
6052
+ const { createEsbHost } = await import("./host-256GVCAH.js");
5989
6053
  const { createEsbContinuationSigner } = await import("./continuation-NLECEJPX.js");
5990
- const { getEsbOperation } = await import("./registry-VT5Y2HLA.js");
6054
+ const { getEsbOperation } = await import("./registry-RXPN6BBT.js");
5991
6055
  const esbEnv = {
5992
6056
  ctx: env.ctx,
5993
6057
  host: createEsbHost(env.ctx),
@@ -6055,7 +6119,7 @@ var ebCrmSearch = {
6055
6119
  minLength: 1,
6056
6120
  description: "\u5BA2\u6237\u540D\u79F0\uFF0C\u8D70\u52A8\u4F5C\u6D41\u5165\u53C2 custom_name\uFF08\u5305\u542B\u5339\u914D\uFF09\uFF1A\u7ED9\u5168\u79F0\u6700\u7A33\uFF0C\u7247\u6BB5\u53EA\u56DE\u9996\u4E2A\u5339\u914D"
6057
6121
  },
6058
- limit: { type: "number", description: "\u8FD4\u56DE\u6761\u6570\u4E0A\u9650\uFF0C\u9ED8\u8BA4 10\uFF08\u5F53\u524D\u52A8\u4F5C\u6D41\u4E00\u6B21\u53EA\u56DE 1 \u6761\uFF0C\u4EC5\u4F5C\u517C\u5BB9\uFF09" },
6122
+ limit: { type: "number", description: "\u8FD4\u56DE\u6761\u6570\u4E0A\u9650\uFF0C\u9ED8\u8BA4 10\u3002\u52A8\u4F5C\u6D41\u662F\u6A21\u7CCA\u67E5\uFF0C\u53EF\u80FD\u547D\u4E2D\u591A\u4E2A\u8FD1\u540D\u5BA2\u6237\uFF1B\u5217\u5F0F\u8F93\u51FA\uFF08mc/sjID \u5E73\u884C\u6570\u7EC4\uFF09\u4F1A\u6309\u7D22\u5F15\u62C6\u6210\u591A\u884C\u8FD4\u56DE" },
6059
6123
  flowId: { type: "string", description: "\u8986\u76D6 ESB \u52A8\u4F5C\u6D41 id\uFF08\u9ED8\u8BA4 904205116264026112\uFF09" },
6060
6124
  employeeId: { type: "string", description: "\u8986\u76D6\u89E6\u53D1\u4EBA\u5458 id\uFF08\u9ED8\u8BA4\u5F53\u524D\u767B\u5F55\u7528\u6237\uFF09" },
6061
6125
  includeRaw: { type: "boolean", description: "true=\u9644\u5E26 ESB \u539F\u59CB\u8FD4\u56DE\uFF0C\u4FBF\u4E8E\u6392\u67E5\u8F93\u51FA\u7ED3\u6784" }
@@ -6115,6 +6179,47 @@ import { existsSync as existsSync3 } from "node:fs";
6115
6179
  import { mkdir as mkdir4, readFile as readFile4, writeFile as writeFile4 } from "node:fs/promises";
6116
6180
  import { homedir } from "node:os";
6117
6181
  import { resolve as resolve5 } from "node:path";
6182
+
6183
+ // src/shortcuts/meeting/operations/eb/flow-memory.ts
6184
+ var FLOW_PICK_TTL_MS = 30 * 24 * 60 * 60 * 1e3;
6185
+ function flowPickKey(scope) {
6186
+ return `flow-pick-${scope}`;
6187
+ }
6188
+ async function readFlowPick(env) {
6189
+ const scope = await cacheScopeSuffix(env);
6190
+ const hit = await readCache(env, flowPickKey(scope), { ttlMs: FLOW_PICK_TTL_MS });
6191
+ if (!hit?.data?.workflowId) return null;
6192
+ try {
6193
+ const session = await env.host.getSession();
6194
+ const userId = String(session?.userId ?? "");
6195
+ if (hit.data.userId && userId && hit.data.userId !== userId) return null;
6196
+ } catch {
6197
+ }
6198
+ return hit.data;
6199
+ }
6200
+ async function rememberFlowPick(env, workflowId, name) {
6201
+ const id = String(workflowId ?? "").trim();
6202
+ if (id === "") return;
6203
+ let userId = "";
6204
+ try {
6205
+ const session = await env.host.getSession();
6206
+ userId = String(session?.userId ?? "");
6207
+ } catch {
6208
+ }
6209
+ const scope = await cacheScopeSuffix(env);
6210
+ await writeCache(env, flowPickKey(scope), {
6211
+ workflowId: id,
6212
+ ...name ? { name: String(name) } : {},
6213
+ ...userId ? { userId } : {},
6214
+ savedAt: Date.now()
6215
+ });
6216
+ }
6217
+ function pickRememberedFlow(launchable, remembered) {
6218
+ if (!remembered?.workflowId) return null;
6219
+ return launchable.find((probe) => probe.workflowId === remembered.workflowId) ?? null;
6220
+ }
6221
+
6222
+ // src/shortcuts/meeting/operations/eb/create-flow.ts
6118
6223
  var FIELD_ALIASES = {
6119
6224
  mt_name: ["\u4F1A\u8BAE\u540D\u79F0", "\u4F1A\u8BAE\u4E3B\u9898", "\u4E3B\u9898"],
6120
6225
  begin_datetime: ["\u5F00\u59CB\u65F6\u95F4", "\u4F1A\u8BAE\u5F00\u59CB\u65F6\u95F4"],
@@ -6137,9 +6242,9 @@ function workflowEnv(env) {
6137
6242
  return env;
6138
6243
  }
6139
6244
  async function loadCreateForm(env, workflowId) {
6140
- const { createWorkflowHost } = await import("./host-YAQAPYNP.js");
6245
+ const { createWorkflowHost } = await import("./host-L3VLITMT.js");
6141
6246
  const { createWorkflowContinuationSigner } = await import("./continuation-HZIZRZBX.js");
6142
- const { getWorkflowOperation } = await import("./registry-YX4CSEMD.js");
6247
+ const { getWorkflowOperation } = await import("./registry-UGRBCBHO.js");
6143
6248
  const wfEnv = {
6144
6249
  ...workflowEnv(env),
6145
6250
  host: createWorkflowHost(env.ctx),
@@ -6258,7 +6363,7 @@ async function resolveAddressRoom(env, input) {
6258
6363
  const text = String(input ?? "").trim();
6259
6364
  if (!text) return null;
6260
6365
  const ref = parseRoomRef(text);
6261
- const { loadRooms: loadRooms2 } = await import("./room-recommend-L3MWH4JW.js");
6366
+ const { loadRooms: loadRooms2 } = await import("./room-recommend-A3UDC3CA.js");
6262
6367
  let rooms = [];
6263
6368
  try {
6264
6369
  rooms = (await loadRooms2(env, {})).rooms;
@@ -6280,7 +6385,7 @@ async function resolveRoomValue(env, input) {
6280
6385
  const ref = parseRoomRef(text);
6281
6386
  if (ref.id) {
6282
6387
  try {
6283
- const { getMeetingOperation: getMeetingOperation2 } = await import("./registry-QCLZEDAP.js");
6388
+ const { getMeetingOperation: getMeetingOperation2 } = await import("./registry-KMHCPAAD.js");
6284
6389
  const detail = await getMeetingOperation2("meeting.eb.room.detail").handler({ id: ref.id }, env);
6285
6390
  const main = detail?.data?.mainTable ?? detail?.data?.data?.mainTable ?? {};
6286
6391
  const name = String(main.room_name ?? "").trim() || ref.name || "";
@@ -6386,7 +6491,7 @@ async function shapeBrowserValues(env, values) {
6386
6491
  const nameOnly = rows.filter((row) => row.id === "" && row.name !== "");
6387
6492
  if (nameOnly.length > 0) {
6388
6493
  try {
6389
- const { getMeetingOperation: getMeetingOperation2 } = await import("./registry-QCLZEDAP.js");
6494
+ const { getMeetingOperation: getMeetingOperation2 } = await import("./registry-KMHCPAAD.js");
6390
6495
  const search = getMeetingOperation2("meeting.eb.crm.search");
6391
6496
  for (const row of nameOnly) {
6392
6497
  const found = await search.handler({ keyword: row.name, limit: 5 }, env).catch(() => null);
@@ -6580,38 +6685,31 @@ async function resolveAutoCrmDetailRows(env, raw) {
6580
6685
  const missing = [];
6581
6686
  if (entries.length > 0) {
6582
6687
  try {
6583
- const { getMeetingOperation: getMeetingOperation2 } = await import("./registry-QCLZEDAP.js");
6688
+ const { getMeetingOperation: getMeetingOperation2 } = await import("./registry-KMHCPAAD.js");
6584
6689
  const search = getMeetingOperation2("meeting.eb.crm.search");
6585
6690
  for (const entry of entries) {
6691
+ if (entry.contacts.length > 0) continue;
6586
6692
  const keyword = (entry.name || entry.id).trim();
6587
6693
  if (keyword === "") {
6588
6694
  missing.push(entry.id);
6589
6695
  continue;
6590
6696
  }
6591
- const searchOnce = async (kw) => {
6592
- const found = await search.handler({ keyword: kw, limit: 5 }, env).catch(() => null);
6697
+ const shortBase = keyword.split("--")[0].trim();
6698
+ const stripped = shortBase.replace(/[((][^))]*[))]/gu, "").replace(/(股份有限公司|有限责任公司|集团有限公司|有限公司|集团|公司)$/u, "").trim();
6699
+ const candidates = [...new Set([keyword, shortBase, stripped, shortBase.slice(0, 4)].filter((one) => one !== ""))];
6700
+ let live = [];
6701
+ for (const candidate of candidates) {
6702
+ const found = await search.handler({ keyword: candidate, limit: 50 }, env).catch(() => null);
6593
6703
  const items = found?.data?.items ?? [];
6594
- const hit = items.find((item) => String(item?.customerId ?? "") === entry.id) ?? items[0];
6595
- return hit?.contacts ?? [];
6596
- };
6597
- let live = await searchOnce(keyword);
6598
- if (live.length === 0 && keyword.includes("--")) {
6599
- const short = keyword.split("--")[0].trim();
6600
- if (short !== "") live = await searchOnce(short);
6704
+ const hit = entry.id !== "" ? items.find((item) => String(item?.customerId ?? "") === entry.id) : void 0;
6705
+ const contacts = hit?.contacts ?? [];
6706
+ if (contacts.length > live.length) live = contacts;
6601
6707
  }
6602
6708
  if (live.length === 0) {
6603
- if (entry.contacts.length === 0) missing.push(entry.name || entry.id);
6709
+ missing.push(entry.name || entry.id);
6604
6710
  continue;
6605
6711
  }
6606
- const keyOf = (one) => `${String(one.name ?? "").trim()}|${String(one.mobile ?? "").trim()}`;
6607
- const merged = /* @__PURE__ */ new Map();
6608
- for (const one of live) merged.set(keyOf(one), one);
6609
- for (const one of entry.contacts) {
6610
- const key = keyOf(one);
6611
- const base = merged.get(key);
6612
- merged.set(key, base ? { ...base, ...one } : one);
6613
- }
6614
- entry.contacts = [...merged.values()];
6712
+ entry.contacts = live;
6615
6713
  }
6616
6714
  } catch {
6617
6715
  }
@@ -6799,7 +6897,7 @@ function normalizeWorkflowIds(raw) {
6799
6897
  }
6800
6898
  return ids;
6801
6899
  }
6802
- var FIXED_FLOW_IDS = ["1325677244111462606", "1326190634427154474"];
6900
+ var FIXED_FLOW_IDS = ["1326190634427154474", "1325677244111462606"];
6803
6901
  var FIXED_FLOW_PROFILES = [
6804
6902
  {
6805
6903
  host: "www.e-cology.com.cn",
@@ -6975,7 +7073,12 @@ var ebMeetingCreateFlowPrepare = {
6975
7073
  },
6976
7074
  dateFrom: {
6977
7075
  type: "string",
6978
- description: "\u6CA1\u7ED9\u5177\u4F53\u65F6\u95F4\u65F6\u6309\u54EA\u4E00\u5929\u63A8\u8350\u65F6\u6BB5\uFF08yyyy-MM-dd\uFF1B\u4E0D\u4F20\u9ED8\u8BA4\u660E\u5929\uFF09"
7076
+ description: "\u6CA1\u7ED9\u5177\u4F53\u65F6\u95F4\u65F6\u6309\u54EA\u4E00\u5929\u63A8\u8350\u65F6\u6BB5\uFF08yyyy-MM-dd\uFF1B\u4E0D\u4F20\u9ED8\u8BA4\u660E\u5929\uFF09\u3002\u26A0\uFE0F \u7528\u6237\u8BF4\u4E86\u300C\u4E0A\u5348/\u4E0B\u5348/\u665A\u4E0A\u300D\u5C31\u5FC5\u987B\u540C\u65F6\u4F20 time_slot \u2014\u2014 \u53EA\u4F20 dateFrom \u4F1A\u5F39\u65F6\u6BB5\u9009\u62E9\u5668\u8BA9\u7528\u6237\u518D\u9009\u4E00\u6B21"
7077
+ },
7078
+ time_slot: {
7079
+ type: "string",
7080
+ enum: ["\u4E0A\u5348", "\u65E9\u4E0A", "\u4E0B\u5348", "\u665A\u4E0A"],
7081
+ description: '\u7528\u6237\u53EA\u8BF4\u4E86\u300C\u4E0A\u5348/\u4E0B\u5348/\u665A\u4E0A\u300D\u65F6\u4F20\u8FD9\u4E2A\uFF08\u914D\u5408 dateFrom\uFF09\uFF1A\u4E0A\u5348/\u65E9\u4E0A=09:00\u201312:00\u3001\u4E0B\u5348=13:00\u201318:00\u3001\u665A\u4E0A=18:00\u201321:00\uFF0CCLI \u76F4\u63A5\u5B9A\u4E0B\u6765\u3001\u4E0D\u518D\u8FD4\u56DE\u65F6\u6BB5\u5019\u9009\u3002\u26D4 \u4E0D\u8981\u53EA\u4F20 dateFrom \u5C31\u671F\u5F85"\u8BA9\u7528\u6237\u9009\u65F6\u6BB5"\u2014\u2014\u7528\u6237\u5DF2\u7ECF\u8BF4\u4E86\u65F6\u6BB5\u5C31\u522B\u518D\u95EE'
6979
7082
  },
6980
7083
  durationMinutes: {
6981
7084
  type: "number",
@@ -6991,7 +7094,7 @@ var ebMeetingCreateFlowPrepare = {
6991
7094
  flowChoice: {
6992
7095
  type: "string",
6993
7096
  enum: ["auto", "ask"],
6994
- description: "\u591A\u4E2A\u5EFA\u4F1A\u6D41\u7A0B**\u90FD\u6709\u53D1\u8D77\u6743\u9650**\u65F6\u600E\u4E48\u529E\uFF1A**\u9ED8\u8BA4\uFF08\u4E0D\u4F20 / ask\uFF09= \u8FD4\u56DE\u9009\u9879\u8BA9\u7528\u6237\u6311**\uFF1Bauto = \u81EA\u52A8\u53D6\u4F18\u5148\u7EA7\u6700\u9AD8\u7684\u90A3\u4E2A\uFF08\u7701\u4E00\u8F6E\uFF0C\u4F46\u9009\u9519\u6D41\u7A0B\u4F1A\u6F0F\u5B57\u6BB5\uFF0C\u614E\u7528\uFF09\u3002\u53EA\u6709 1 \u4E2A\u6709\u6743\u9650\u65F6\u4E0D\u53D7\u6B64\u53C2\u6570\u5F71\u54CD\uFF0CCLI \u76F4\u63A5\u53D1\u8D77"
7097
+ description: '\u591A\u4E2A\u5EFA\u4F1A\u6D41\u7A0B**\u90FD\u6709\u53D1\u8D77\u6743\u9650**\u65F6\u600E\u4E48\u529E\uFF1A\u9ED8\u8BA4\uFF08\u4E0D\u4F20 / ask\uFF09= \u8FD4\u56DE\u9009\u9879\u8BA9\u7528\u6237\u6311\uFF1Bauto = \u81EA\u52A8\u53D6\u4F18\u5148\u7EA7\u6700\u9AD8\u7684\u90A3\u4E2A\uFF08\u7701\u4E00\u8F6E\uFF0C\u4F46\u9009\u9519\u6D41\u7A0B\u4F1A\u6F0F\u5B57\u6BB5\uFF0C\u614E\u7528\uFF09\u3002\u6709**\u6D41\u7A0B\u8BB0\u5FC6**\uFF08\u8BE5\u8D26\u53F7\u4E0A\u6B21\u6210\u529F\u7528\u8FC7\u7684\u6D41\u7A0B\uFF09\u4E14\u672C\u6B21\u4ECD\u53EF\u53D1\u8D77\u65F6\uFF0C\u9ED8\u8BA4\u76F4\u63A5\u6CBF\u7528\u4E0A\u6B21\u9009\u62E9\u5E76\u7559\u75D5\uFF0C\u4E0D\u518D\u5F39\u9009\u9879\uFF1B\u8981\u5F3A\u5236\u56DE\u5230"\u6BCF\u6B21\u90FD\u95EE"\u624D\u4F20 ask\u3002\u53EA\u6709 1 \u4E2A\u6709\u6743\u9650\u65F6\u4E0D\u53D7\u6B64\u53C2\u6570\u5F71\u54CD\uFF0CCLI \u76F4\u63A5\u53D1\u8D77'
6995
7098
  }
6996
7099
  },
6997
7100
  { required: ["mt_name"] }
@@ -7001,13 +7104,64 @@ var ebMeetingCreateFlowPrepare = {
7001
7104
  let flowPickNote = null;
7002
7105
  const decisions = {};
7003
7106
  const enrich = args.enrich !== false;
7004
- const beginText = String(args.begin_datetime ?? "").trim();
7107
+ let beginText = String(args.begin_datetime ?? "").trim();
7005
7108
  let endText = String(args.end_datetime ?? "").trim();
7109
+ const TIME_SLOT_RANGES = {
7110
+ \u4E0A\u5348: ["09:00", "12:00"],
7111
+ \u65E9\u4E0A: ["09:00", "12:00"],
7112
+ \u4E0B\u5348: ["13:00", "18:00"],
7113
+ \u665A\u4E0A: ["18:00", "21:00"]
7114
+ };
7115
+ let slotConfirmed = false;
7116
+ const slotArg = String(args.time_slot ?? "").trim();
7117
+ if (slotArg !== "" && !/^\d{4}-\d{2}-\d{2}[ T]\d{2}:\d{2}/.test(beginText)) {
7118
+ const range = TIME_SLOT_RANGES[slotArg];
7119
+ const day2 = String(args.dateFrom ?? "").trim().slice(0, 10) || beginText.slice(0, 10) || tomorrowIso();
7120
+ if (range && /^\d{4}-\d{2}-\d{2}$/.test(day2)) {
7121
+ beginText = `${day2} ${range[0]}`;
7122
+ endText = `${day2} ${range[1]}`;
7123
+ slotConfirmed = true;
7124
+ }
7125
+ }
7126
+ if (!slotConfirmed && !/\d{1,2}:\d{2}/.test(beginText)) {
7127
+ const workStart = Number(args.workStartHour);
7128
+ const workEnd = Number(args.workEndHour);
7129
+ if (Number.isFinite(workStart) && Number.isFinite(workEnd) && workEnd > workStart) {
7130
+ const slotName = workEnd <= 12 && workStart < 12 ? "\u4E0A\u5348" : workStart >= 13 && workEnd <= 18 ? "\u4E0B\u5348" : workStart >= 18 ? "\u665A\u4E0A" : "";
7131
+ const range = slotName ? TIME_SLOT_RANGES[slotName] : void 0;
7132
+ const day2 = String(args.dateFrom ?? "").trim().slice(0, 10) || beginText.slice(0, 10) || tomorrowIso();
7133
+ if (range && /^\d{4}-\d{2}-\d{2}$/.test(day2)) {
7134
+ beginText = `${day2} ${range[0]}`;
7135
+ endText = `${day2} ${range[1]}`;
7136
+ slotConfirmed = true;
7137
+ }
7138
+ }
7139
+ }
7140
+ const slotHit = beginText.match(/(\d{4}-\d{2}-\d{2})?\s*(上午|早上|下午|晚上)/u);
7141
+ if (slotHit) {
7142
+ const range = TIME_SLOT_RANGES[slotHit[2]];
7143
+ const day2 = slotHit[1] || beginText.slice(0, 10) || String(args.dateFrom ?? "").trim().slice(0, 10) || tomorrowIso();
7144
+ const rest = beginText.replace(slotHit[0], "");
7145
+ if (range && /^\d{4}-\d{2}-\d{2}$/.test(day2) && !/\d{1,2}:\d{2}/.test(rest)) {
7146
+ beginText = `${day2} ${range[0]}`;
7147
+ endText = `${day2} ${range[1]}`;
7148
+ slotConfirmed = true;
7149
+ }
7150
+ }
7006
7151
  const rawMembers = String(args.hrm_members ?? "").split(/[,;,;\s]+/).map((item) => item.trim()).filter((item) => item !== "");
7152
+ let membersDefaulted = false;
7153
+ if (rawMembers.length === 0) {
7154
+ const self = await resolveSelfPerson(env);
7155
+ if (self) {
7156
+ rawMembers.push(self.id);
7157
+ membersDefaulted = true;
7158
+ args.hrm_members = rawMembers.join(",");
7159
+ }
7160
+ }
7007
7161
  const nameLike = rawMembers.filter((item) => !/^\d+$/.test(item));
7008
- const nameToId = nameLike.length > 0 ? await import("./schedule-UASAVDVD.js").then((m) => m.resolveMemberIdsByName(env, nameLike)).catch(() => /* @__PURE__ */ new Map()) : /* @__PURE__ */ new Map();
7162
+ const nameToId = nameLike.length > 0 ? await import("./schedule-5GCACCK7.js").then((m) => m.resolveMemberIdsByName(env, nameLike)).catch(() => /* @__PURE__ */ new Map()) : /* @__PURE__ */ new Map();
7009
7163
  const memberIds = rawMembers.map((item) => nameToId.get(item) ?? item);
7010
- const timeConfirmed = args.timeConfirmed === true;
7164
+ const timeConfirmed = args.timeConfirmed === true || slotConfirmed;
7011
7165
  const callerWorkflowId = String(args.workflowId ?? "").trim();
7012
7166
  const earlyWorkflowNote = callerWorkflowId === "" ? "" : `\u26D4 \u4F60\u4F20\u4E86 workflowId=${callerWorkflowId}\uFF0C\u4F46**\u6D41\u7A0B\u8FD8\u6CA1\u5230\u786E\u8BA4\u6B65\u9AA4**\uFF08\u987A\u5E8F\u662F \u540D\u79F0\u2192\u65F6\u95F4\u2192\u53C2\u4F1A\u4EBA\u2192\u5730\u70B9\u2192\u6D41\u7A0B\uFF09\u3002\u672C\u6B21\u53EA\u5904\u7406\u65F6\u95F4/\u5730\u70B9\uFF1B\u26D4 \u4E0D\u8981\u5728\u56DE\u590D\u91CC\u8BF4"\u6309 X \u6D41\u7A0B\u53D1\u8D77"\u2014\u2014\u56DB\u8981\u7D20\u5B9A\u5B8C\u540E CLI \u4F1A\u8FD4\u56DE\u6D41\u7A0B\u9009\u9879\u8BA9\u7528\u6237\u70B9\u3002`;
7013
7167
  const beginHasTime = /^\d{4}-\d{2}-\d{2}[ T]\d{2}:\d{2}/.test(beginText);
@@ -7020,7 +7174,7 @@ var ebMeetingCreateFlowPrepare = {
7020
7174
  if (!beginHasTime || !timeConfirmed) {
7021
7175
  const day2 = /^\d{4}-\d{2}-\d{2}/.test(beginText) ? beginText.slice(0, 10) : String(args.dateFrom ?? "").trim().slice(0, 10) || tomorrowIso();
7022
7176
  const duration = Number(args.durationMinutes) > 0 ? Math.round(Number(args.durationMinutes)) : 60;
7023
- const { getMeetingOperation: getMeetingOperation2 } = await import("./registry-QCLZEDAP.js");
7177
+ const { getMeetingOperation: getMeetingOperation2 } = await import("./registry-KMHCPAAD.js");
7024
7178
  const suggested = await getMeetingOperation2("meeting.eb.meeting.create.suggest").handler(
7025
7179
  {
7026
7180
  dateFrom: day2,
@@ -7098,21 +7252,43 @@ var ebMeetingCreateFlowPrepare = {
7098
7252
  const callerToken = String(args.caller ?? "").trim();
7099
7253
  const callerInMembers = callerToken !== "" && (rawMembers.includes(callerToken) || memberIds.includes(callerToken));
7100
7254
  const roomMemberCount = declaredTotal ?? (memberIds.length > 0 ? memberIds.length + (callerInMembers ? 0 : 1) : void 0);
7101
- const roomTask = enrich && beginText && endText ? recommendRooms(env, {
7102
- beginDatetime: beginText,
7103
- endDatetime: endText,
7104
- ...roomMemberCount ? { memberCount: roomMemberCount } : {},
7105
- // 建会是"要下单"的场景:宁可多一次请求也必须拿最新台账(24h 缓存会让刚导入的会议室看不到)。
7106
- refreshRooms: true,
7107
- topN: 3
7108
- }).catch(noteFailure("\u4F1A\u8BAE\u5BA4\u63A8\u8350")) : Promise.resolve(null);
7255
+ const hasCustomer = Array.isArray(args.crm_members) ? args.crm_members.length > 0 : String(args.crm_members ?? "").trim() !== "";
7256
+ const dayUsagesTask = enrich && beginText && endText ? loadDayUsages(env, day) : Promise.resolve(null);
7257
+ const roomTask = enrich && beginText && endText ? (async () => {
7258
+ const usageData = await dayUsagesTask;
7259
+ return recommendRooms(env, {
7260
+ beginDatetime: beginText,
7261
+ endDatetime: endText,
7262
+ ...roomMemberCount ? { memberCount: roomMemberCount } : {},
7263
+ // 带客户时优先接待类会议室(2026-11-02 用户口径:加了客户就推接待类)
7264
+ ...hasCustomer ? { hasCustomer: true } : {},
7265
+ // 2026-11-03 用户批准松绑:不再每次强制重拉台账(省 ~1s + 2 请求)。
7266
+ // 兜底在 recommendRooms 内部:24h 缓存凑不出候选时自动强制重拉一次再算;
7267
+ // 代价是刚导入的会议室在缓存期可能按名称查不到(按 id 指定不受影响)。
7268
+ topN: 3,
7269
+ // 占用走全天缓存(usageData 为 null 时 recommendRooms 内部自己查,行为不变)
7270
+ ...usageData ? { dayUsages: usageData.rows } : {}
7271
+ });
7272
+ })().catch(noteFailure("\u4F1A\u8BAE\u5BA4\u63A8\u8350")) : Promise.resolve(null);
7109
7273
  const addressId = String(addressInput ?? "").trim();
7110
7274
  const roomConfirmed = args.roomConfirmed === true;
7111
7275
  const roomConflictTask = enrich && beginText && endText && addressId !== "" ? (async () => {
7112
7276
  const room = await resolveAddressRoom(env, addressId);
7113
7277
  if (!room) return { unresolved: true, input: addressId };
7114
7278
  if (!room.id || room.lookupFailed || room.status !== "0") return { room };
7115
- const { getMeetingOperation: getMeetingOperation2 } = await import("./registry-QCLZEDAP.js");
7279
+ const usageData = await dayUsagesTask.catch(() => null);
7280
+ if (usageData) {
7281
+ const conflicts = filterUsages(usageData.rows, { roomId: room.id, begin: beginText, end: endText }).map((usage) => ({ mtId: usage.mtId, begin: usage.start, end: usage.end }));
7282
+ return {
7283
+ room,
7284
+ hasConflict: conflicts.length > 0,
7285
+ conflicts,
7286
+ verdict: conflicts.length > 0 ? "warn" : "ok",
7287
+ requests: usageData.requests,
7288
+ usageFromCache: usageData.fromCache
7289
+ };
7290
+ }
7291
+ const { getMeetingOperation: getMeetingOperation2 } = await import("./registry-KMHCPAAD.js");
7116
7292
  const result = await getMeetingOperation2("meeting.eb.conflict.room").handler(
7117
7293
  { beginDatetime: beginText, endDatetime: endText, address: room.id },
7118
7294
  env
@@ -7120,7 +7296,7 @@ var ebMeetingCreateFlowPrepare = {
7120
7296
  return { room, ...result?.data ?? {} };
7121
7297
  })().catch(noteFailure("\u4F1A\u8BAE\u5BA4**\u5360\u7528**\u68C0\u6D4B")) : Promise.resolve(null);
7122
7298
  const conflictTask = enrich && beginText && endText && memberIds.length > 0 ? (async () => {
7123
- const { getMeetingOperation: getMeetingOperation2 } = await import("./registry-QCLZEDAP.js");
7299
+ const { getMeetingOperation: getMeetingOperation2 } = await import("./registry-KMHCPAAD.js");
7124
7300
  return getMeetingOperation2("meeting.eb.conflict.member").handler(
7125
7301
  { beginDatetime: beginText, endDatetime: endText, hrmMembers: memberIds.join(",") },
7126
7302
  env
@@ -7374,54 +7550,62 @@ var ebMeetingCreateFlowPrepare = {
7374
7550
  );
7375
7551
  }
7376
7552
  if (launchable.length > 1 && !autoPick) {
7377
- return meetingSuccess("meeting.eb.meeting.create.flow.prepare", {
7378
- status: "NEEDS_SELECTION",
7379
- // ⚠️ 以前漏了这个字段(agent 拿到 undefined 无法判断是哪类选择,2026-10-30 真机发现)。
7380
- selectionType: "flow",
7381
- // 明确告诉调用方"这是一道选择题,请用选项控件呈现",不要降级成文本列表
7382
- // (2026-10-30 用户反馈:agent 把会议室候选写成文本 + "需要你指定一间",没给选项卡)。
7383
- ui: { component: "choice", multiple: false, recommendedKey: "W1" },
7384
- // 四要素已经确认到这一步了:摘要一起给出去,用户只需点一下流程,就能直接提交。
7385
- confirmed: {
7386
- mt_name: String(args.mt_name ?? ""),
7387
- begin_datetime: beginText,
7388
- end_datetime: endText,
7389
- address: confirmedAddressId || null,
7390
- addressName: confirmedAddressLabel || null,
7391
- hrm_members: memberIds
7392
- },
7393
- message: `\u4F1A\u8BAE\u8981\u7D20\u5DF2\u786E\u8BA4\uFF08${String(args.mt_name ?? "")} \xB7 ${confirmedWhen}${confirmedAddressLabel ? ` \xB7 ${confirmedAddressLabel}` : " \xB7 \u65E0\u4F1A\u8BAE\u5BA4"}\uFF09\uFF1B\u5F53\u524D\u8D26\u53F7\u5BF9 ${sourceLabel}\u7684 ${candidates.length} \u4E2A\u5EFA\u4F1A\u6D41\u7A0B**\u90FD\u6709\u53D1\u8D77\u6743\u9650**\uFF0C\u8BF7\u8BA9\u7528\u6237\u6700\u540E\u9009\u4E00\u4E0B\u300C\u7528\u54EA\u6761\u6D41\u7A0B\u53D1\u8D77\u300D\u2014\u2014 **\u4E0D\u8981\u9ED8\u8BA4\u53D6\u7B2C\u4E00\u4E2A**\uFF08\u5404\u6D41\u7A0B\u8868\u5355\u5B57\u6BB5\u53EF\u80FD\u5B8C\u5168\u4E0D\u540C\uFF0C\u9009\u9519\u4F1A\u6F0F\u5B57\u6BB5\uFF1B2026-10-29 \u771F\u5B9E\u4E8B\u6545\uFF1A\u53D6\u7B2C\u4E00\u4E2A\u5BFC\u81F4\u5B57\u6BB5\u5168\u586B\u4E0D\u8FDB\u53E6\u4E00\u6761\u6D41\u7A0B\uFF0C\u7528\u6237\u4EE5\u4E3A"\u7CFB\u7EDF\u53EA\u652F\u6301\u4E00\u6761\u6D41\u7A0B"\uFF09\u3002\u26A0\uFE0F \u53EA\u6709\u5176\u4E2D 1 \u4E2A\u6709\u6743\u9650\u65F6 CLI \u4F1A\u76F4\u63A5\u53D1\u8D77\uFF0C\u4E0D\u4F1A\u8D70\u5230\u8FD9\u4E00\u6B65`,
7394
- options: launchable.map((probe, index) => ({
7395
- key: `W${index + 1}`,
7396
- label: probe.name ? `${probe.name}\uFF08${probe.workflowId}\uFF09` : probe.workflowId,
7397
- // ⛔ 把已确认的四要素一起带回去:用户点选流程后**原样回传 value** 就能直接出确认摘要,
7398
- // 不用再走一遍时间/房间闸门(否则"先定四要素再选流程"会多出一轮无效往返)。
7399
- value: {
7400
- workflowId: probe.workflowId,
7553
+ const remembered = args.flowChoice === "ask" ? null : await readFlowPick(env).catch(() => null);
7554
+ const rememberedHit = pickRememberedFlow(launchable, remembered);
7555
+ if (rememberedHit) {
7556
+ workflowId = rememberedHit.workflowId;
7557
+ const others = launchable.filter((probe) => probe.workflowId !== rememberedHit.workflowId).map((probe) => probe.name ? `${probe.name}\uFF08${probe.workflowId}\uFF09` : probe.workflowId);
7558
+ flowPickNote = `${sourceLabel}\uFF1A\u5F53\u524D\u8D26\u53F7\u53EF\u53D1\u8D77 ${launchable.length} \u4E2A\u5EFA\u4F1A\u6D41\u7A0B\uFF0C\u5DF2\u6CBF\u7528\u4F60\u4E0A\u6B21\u9009\u7684\u300C${rememberedHit.name ?? rememberedHit.workflowId}\u300D\uFF08${rememberedHit.workflowId}\uFF09\u53D1\u8D77 \u2014\u2014 \u8981\u6362\u7684\u8BDD\u8BF4\u4E00\u58F0${others.length > 0 ? `\uFF08\u5176\u4ED6\u53EF\u7528\uFF1A${others.join("\u3001")}\uFF09` : ""}\u3002`;
7559
+ } else {
7560
+ return meetingSuccess("meeting.eb.meeting.create.flow.prepare", {
7561
+ status: "NEEDS_SELECTION",
7562
+ // ⚠️ 以前漏了这个字段(agent 拿到 undefined 无法判断是哪类选择,2026-10-30 真机发现)。
7563
+ selectionType: "flow",
7564
+ // 明确告诉调用方"这是一道选择题,请用选项控件呈现",不要降级成文本列表
7565
+ // (2026-10-30 用户反馈:agent 把会议室候选写成文本 + "需要你指定一间",没给选项卡)。
7566
+ ui: { component: "choice", multiple: false, recommendedKey: "W1" },
7567
+ // 四要素已经确认到这一步了:摘要一起给出去,用户只需点一下流程,就能直接提交。
7568
+ confirmed: {
7569
+ mt_name: String(args.mt_name ?? ""),
7401
7570
  begin_datetime: beginText,
7402
7571
  end_datetime: endText,
7403
- timeConfirmed: true,
7404
- ...confirmedAddressId ? { address: confirmedAddressId, roomConfirmed: true } : {}
7572
+ address: confirmedAddressId || null,
7573
+ addressName: confirmedAddressLabel || null,
7574
+ hrm_members: memberIds
7405
7575
  },
7406
- reason: "\u5F53\u524D\u8D26\u53F7\u6709\u53D1\u8D77\u6743\u9650",
7407
- // 把该流程的字段名如实带出来:不同流程字段差异很大(有的有设备需求/涉密项目,有的没有),
7408
- // 用户要靠这个才能选对(2026-10-29 用户反馈:选错方式后字段全填不进去)。
7409
- fields: (loadedForms.get(probe.workflowId)?.fields ?? []).map((f) => f.name).filter(Boolean)
7410
- })),
7411
- probes
7412
- }, {
7413
- warnings: [
7414
- `${sourceLabel}\uFF1A\u5171 ${candidates.length} \u4E2A\u5EFA\u4F1A\u6D41\u7A0B\uFF0C\u5176\u4E2D ${launchable.length} \u4E2A\u5F53\u524D\u8D26\u53F7\u53EF\u53D1\u8D77\uFF1B**\u5FC5\u987B\u628A\u8FD9\u51E0\u4E2A\u6D41\u7A0B\u505A\u6210\u9009\u9879\u8BA9\u7528\u6237\u6311\u4E00\u4E2A\uFF0C\u7981\u6B62\u81EA\u5DF1\u66FF\u7528\u6237\u9009**\uFF1B\u9009\u5B9A\u540E\u5E26\u5355\u4E2A workflowId \u91CD\u65B0 prepare\u3002`,
7415
- ...probes.filter((probe) => !probe.launchable).map((probe) => `\u6D41\u7A0B ${probe.workflowId} \u5F53\u524D\u8D26\u53F7\u65E0\u6CD5\u53D1\u8D77\uFF08${probe.reason ?? "\u65E0\u6743\u9650"}\uFF09\uFF0C\u5DF2\u6392\u9664`)
7416
- ]
7417
- });
7576
+ message: `\u4F1A\u8BAE\u8981\u7D20\u5DF2\u786E\u8BA4\uFF08${String(args.mt_name ?? "")} \xB7 ${confirmedWhen}${confirmedAddressLabel ? ` \xB7 ${confirmedAddressLabel}` : " \xB7 \u65E0\u4F1A\u8BAE\u5BA4"}\uFF09\uFF1B\u5F53\u524D\u8D26\u53F7\u5BF9 ${sourceLabel}\u7684 ${candidates.length} \u4E2A\u5EFA\u4F1A\u6D41\u7A0B**\u90FD\u6709\u53D1\u8D77\u6743\u9650**\uFF0C\u8BF7\u8BA9\u7528\u6237\u6700\u540E\u9009\u4E00\u4E0B\u300C\u7528\u54EA\u6761\u6D41\u7A0B\u53D1\u8D77\u300D\u2014\u2014 **\u4E0D\u8981\u9ED8\u8BA4\u53D6\u7B2C\u4E00\u4E2A**\uFF08\u5404\u6D41\u7A0B\u8868\u5355\u5B57\u6BB5\u53EF\u80FD\u5B8C\u5168\u4E0D\u540C\uFF0C\u9009\u9519\u4F1A\u6F0F\u5B57\u6BB5\uFF1B2026-10-29 \u771F\u5B9E\u4E8B\u6545\uFF1A\u53D6\u7B2C\u4E00\u4E2A\u5BFC\u81F4\u5B57\u6BB5\u5168\u586B\u4E0D\u8FDB\u53E6\u4E00\u6761\u6D41\u7A0B\uFF0C\u7528\u6237\u4EE5\u4E3A"\u7CFB\u7EDF\u53EA\u652F\u6301\u4E00\u6761\u6D41\u7A0B"\uFF09\u3002\u26A0\uFE0F \u53EA\u6709\u5176\u4E2D 1 \u4E2A\u6709\u6743\u9650\u65F6 CLI \u4F1A\u76F4\u63A5\u53D1\u8D77\uFF0C\u4E0D\u4F1A\u8D70\u5230\u8FD9\u4E00\u6B65`,
7577
+ options: launchable.map((probe, index) => ({
7578
+ key: `W${index + 1}`,
7579
+ label: probe.name ? `${probe.name}\uFF08${probe.workflowId}\uFF09` : probe.workflowId,
7580
+ // ⛔ 把已确认的四要素一起带回去:用户点选流程后**原样回传 value** 就能直接出确认摘要,
7581
+ // 不用再走一遍时间/房间闸门(否则"先定四要素再选流程"会多出一轮无效往返)。
7582
+ value: {
7583
+ workflowId: probe.workflowId,
7584
+ begin_datetime: beginText,
7585
+ end_datetime: endText,
7586
+ timeConfirmed: true,
7587
+ ...confirmedAddressId ? { address: confirmedAddressId, roomConfirmed: true } : {}
7588
+ },
7589
+ reason: "\u5F53\u524D\u8D26\u53F7\u6709\u53D1\u8D77\u6743\u9650",
7590
+ // 把该流程的字段名如实带出来:不同流程字段差异很大(有的有设备需求/涉密项目,有的没有),
7591
+ // 用户要靠这个才能选对(2026-10-29 用户反馈:选错方式后字段全填不进去)。
7592
+ fields: (loadedForms.get(probe.workflowId)?.fields ?? []).map((f) => f.name).filter(Boolean)
7593
+ })),
7594
+ probes
7595
+ }, {
7596
+ warnings: [
7597
+ `${sourceLabel}\uFF1A\u5171 ${candidates.length} \u4E2A\u5EFA\u4F1A\u6D41\u7A0B\uFF0C\u5176\u4E2D ${launchable.length} \u4E2A\u5F53\u524D\u8D26\u53F7\u53EF\u53D1\u8D77\uFF1B**\u5FC5\u987B\u628A\u8FD9\u51E0\u4E2A\u6D41\u7A0B\u505A\u6210\u9009\u9879\u8BA9\u7528\u6237\u6311\u4E00\u4E2A\uFF0C\u7981\u6B62\u81EA\u5DF1\u66FF\u7528\u6237\u9009**\uFF1B\u9009\u5B9A\u540E\u5E26\u5355\u4E2A workflowId \u91CD\u65B0 prepare\u3002`,
7598
+ ...probes.filter((probe) => !probe.launchable).map((probe) => `\u6D41\u7A0B ${probe.workflowId} \u5F53\u524D\u8D26\u53F7\u65E0\u6CD5\u53D1\u8D77\uFF08${probe.reason ?? "\u65E0\u6743\u9650"}\uFF09\uFF0C\u5DF2\u6392\u9664`)
7599
+ ]
7600
+ });
7601
+ }
7418
7602
  }
7419
- workflowId = launchable[0].workflowId;
7420
- if (launchable.length === 1 && candidates.length > 1) {
7603
+ if (workflowId === "") workflowId = launchable[0].workflowId;
7604
+ if (launchable.length === 1 && candidates.length > 1 && flowPickNote === null) {
7421
7605
  const only = launchable[0];
7422
7606
  flowPickNote = `${sourceLabel}\uFF1A\u5171 ${candidates.length} \u4E2A\u5EFA\u4F1A\u6D41\u7A0B\uFF0C\u5F53\u524D\u8D26\u53F7\u53EA\u6709\u300C${only.name ?? only.workflowId}\u300D\uFF08${only.workflowId}\uFF09\u6709\u53D1\u8D77\u6743\u9650\uFF0C\u5DF2\u76F4\u63A5\u7528\u5B83\u53D1\u8D77`;
7423
7607
  }
7424
- if (launchable.length > 1) {
7608
+ if (launchable.length > 1 && flowPickNote === null) {
7425
7609
  const picked2 = launchable[0];
7426
7610
  const others = launchable.slice(1).map((probe) => probe.name ? `${probe.name}\uFF08${probe.workflowId}\uFF09` : probe.workflowId);
7427
7611
  flowPickNote = `${sourceLabel}\uFF1A\u5171 ${candidates.length} \u4E2A\u5EFA\u4F1A\u6D41\u7A0B\uFF0C\u5F53\u524D\u8D26\u53F7\u53EF\u53D1\u8D77 ${launchable.length} \u4E2A\uFF0C\u5DF2\u6309\u4F18\u5148\u7EA7\u81EA\u52A8\u9009\u7528\u300C${picked2.name ?? picked2.workflowId}\u300D\uFF08${picked2.workflowId}\uFF09\uFF1B\u5176\u4ED6\u53EF\u7528\u6D41\u7A0B\uFF1A${others.join("\u3001")} \u2014\u2014 \u8981\u7528\u5B83\u4EEC\u8BF7\u663E\u5F0F\u4F20 workflowId\u3002`;
@@ -7508,7 +7692,7 @@ var ebMeetingCreateFlowPrepare = {
7508
7692
  if (crmMembersGiven && !onlyDetailMode) {
7509
7693
  const detailTarget = resolveCrmDetailTarget(form.fields);
7510
7694
  if (detailTarget) {
7511
- const auto = await resolveAutoCrmDetailRows(env, args.crm_members);
7695
+ const auto = await resolveAutoCrmDetailRows(env, shaped.values.crm_members ?? args.crm_members);
7512
7696
  if (auto.rows.length > 0) {
7513
7697
  crmDetailRows = auto.rows;
7514
7698
  if (providedCrmDetailRows.length > 0) {
@@ -7605,6 +7789,7 @@ var ebMeetingCreateFlowPrepare = {
7605
7789
  );
7606
7790
  }
7607
7791
  const crmPatchIds = (Array.isArray(shaped.values.crm_members) ? shaped.values.crm_members : []).map((row) => String(row?.id ?? "").trim()).filter((id) => id !== "");
7792
+ const groupMemberIds = (Array.isArray(shaped.values.hrm_members) ? shaped.values.hrm_members : []).map((one) => String(one?.id ?? one ?? "").trim()).filter((id) => id !== "");
7608
7793
  const session = await env.host.getSession();
7609
7794
  const continuation = await env.continuation.issue(
7610
7795
  {
@@ -7614,8 +7799,9 @@ var ebMeetingCreateFlowPrepare = {
7614
7799
  userId: session.userId,
7615
7800
  payload: {
7616
7801
  workflowId,
7617
- requestName: String(args.mt_name),
7618
- mtName: String(args.mt_name),
7802
+ requestName: String(args.mt_name ?? args.mt_subject ?? ""),
7803
+ mtName: String(args.mt_name ?? args.mt_subject ?? ""),
7804
+ workflowName: String(form.workflowName ?? ""),
7619
7805
  data: { main, ...detailPayload ? { details: detailPayload } : {} },
7620
7806
  surfaceContinuation: form.continuation,
7621
7807
  // 供 apply 在「会议还没生成」时按申请单信息预生成邀请函(预置函)
@@ -7625,7 +7811,14 @@ var ebMeetingCreateFlowPrepare = {
7625
7811
  // 已确认的「人员 id → 姓名」,供 apply 回显时把裸 id 换成姓名
7626
7812
  ...autoFilledPerson.length > 0 ? { personLabels: Object.fromEntries(autoFilledPerson.map((one) => [one.id, one.name])) } : {},
7627
7813
  // 会议记录的客户要靠 apply 补写(表单「参会客户」是 Ebuilder,单据↔会议表不同步)
7628
- ...crmPatchIds.length > 0 ? { crmPatch: { ids: crmPatchIds, count: crmMemberCount === void 0 ? crmPatchIds.length : crmMemberCount } } : {}
7814
+ ...crmPatchIds.length > 0 ? { crmPatch: { ids: crmPatchIds, count: crmMemberCount === void 0 ? crmPatchIds.length : crmMemberCount } } : {},
7815
+ // 建群要素:apply 拿到会议 id 后先建群、再把群 id 回写 imchat_groupid
7816
+ groupChat: {
7817
+ memberIds: groupMemberIds,
7818
+ beginDatetime: String(shaped.values.begin_datetime ?? ""),
7819
+ endDatetime: String(shaped.values.end_datetime ?? ""),
7820
+ address: String(shaped.values.address ?? "")
7821
+ }
7629
7822
  },
7630
7823
  fingerprint: JSON.stringify({ workflowId, main, ...detailPayload ? { details: detailPayload } : {} })
7631
7824
  },
@@ -7640,7 +7833,7 @@ var ebMeetingCreateFlowPrepare = {
7640
7833
  workflowCandidates: candidates,
7641
7834
  ...probes.length > 0 ? { workflowProbes: probes } : {},
7642
7835
  ...flowPickNote ? { workflowAutoPicked: { workflowId, source: resolved.source, note: flowPickNote } } : {},
7643
- requestName: String(args.mt_name),
7836
+ requestName: String(args.mt_name ?? args.mt_subject ?? ""),
7644
7837
  fieldMapping: mapped,
7645
7838
  formData: { main },
7646
7839
  // 人话版「即将提交的内容」—— 提交前必须先贴给用户核对(见 SKILL 建会章节)。
@@ -7695,7 +7888,7 @@ async function patchMeetingCrmMembers(env, meetingId, ids, count, settleMsList =
7695
7888
  });
7696
7889
  };
7697
7890
  const readBack = async () => {
7698
- const { getMeetingOperation: getMeetingOperation2 } = await import("./registry-QCLZEDAP.js");
7891
+ const { getMeetingOperation: getMeetingOperation2 } = await import("./registry-KMHCPAAD.js");
7699
7892
  const detail = getMeetingOperation2("meeting.eb.meeting.detail");
7700
7893
  const read = await detail.handler({ id: String(meetingId).trim() }, env);
7701
7894
  return String(read?.data?.data?.crm_members ?? "").trim();
@@ -7722,7 +7915,7 @@ async function renderPreInvitation(payload, env) {
7722
7915
  const fields = payload?.invitationFields ?? {};
7723
7916
  const started = Date.now();
7724
7917
  try {
7725
- const { getMeetingOperation: getMeetingOperation2 } = await import("./registry-QCLZEDAP.js");
7918
+ const { getMeetingOperation: getMeetingOperation2 } = await import("./registry-KMHCPAAD.js");
7726
7919
  const render = getMeetingOperation2("meeting.invitation.render");
7727
7920
  const rendered = await render.handler(
7728
7921
  {
@@ -7793,9 +7986,9 @@ var ebMeetingCreateFlowApply = {
7793
7986
  throw meetingValidationError("context_mismatch", "\u786E\u8BA4\u4E0A\u4E0B\u6587\u5DF2\u53D8\u5316\uFF08\u79DF\u6237\u6216\u767B\u5F55\u8D26\u53F7\u4E0D\u540C\uFF09\uFF0C\u8BF7\u91CD\u65B0\u6267\u884C prepare");
7794
7987
  }
7795
7988
  const payload = lease?.payload ?? {};
7796
- const { createWorkflowHost } = await import("./host-YAQAPYNP.js");
7989
+ const { createWorkflowHost } = await import("./host-L3VLITMT.js");
7797
7990
  const { createWorkflowContinuationSigner } = await import("./continuation-HZIZRZBX.js");
7798
- const { getWorkflowOperation } = await import("./registry-YX4CSEMD.js");
7991
+ const { getWorkflowOperation } = await import("./registry-UGRBCBHO.js");
7799
7992
  const wfEnv = {
7800
7993
  ...workflowEnv(env),
7801
7994
  host: createWorkflowHost(env.ctx),
@@ -7841,6 +8034,37 @@ var ebMeetingCreateFlowApply = {
7841
8034
  const submitStatus = String(submittedData.status ?? submitted?.status ?? "");
7842
8035
  if (submitStatus === "BROWSER_FILL") {
7843
8036
  const pre = await renderPreInvitation(payload, env);
8037
+ let groupChat2;
8038
+ const groupPayload2 = payload?.groupChat;
8039
+ if (groupPayload2) {
8040
+ try {
8041
+ const { ensureMeetingGroupChat } = await import("./group-chat-VYBNMJLG.js");
8042
+ groupChat2 = {
8043
+ ...await ensureMeetingGroupChat(env, {
8044
+ meetingName: String(payload.mtName ?? ""),
8045
+ beginDatetime: String(groupPayload2.beginDatetime ?? ""),
8046
+ endDatetime: String(groupPayload2.endDatetime ?? ""),
8047
+ memberIds: Array.isArray(groupPayload2.memberIds) ? groupPayload2.memberIds : [],
8048
+ ...groupPayload2.address ? { address: String(groupPayload2.address) } : {}
8049
+ })
8050
+ };
8051
+ } catch (error) {
8052
+ groupChat2 = { ok: false, error: String(error?.message ?? error).slice(0, 200) };
8053
+ }
8054
+ }
8055
+ if (groupChat2 && groupChat2.ok) {
8056
+ try {
8057
+ const { savePendingForm } = await import("./group-chat-VYBNMJLG.js");
8058
+ await savePendingForm(env, {
8059
+ workflowId: String(payload.workflowId ?? ""),
8060
+ workflowName: String(payload.workflowName ?? ""),
8061
+ mtName: String(payload.mtName ?? ""),
8062
+ groupId: String(groupChat2.groupId ?? ""),
8063
+ groupName: String(groupChat2.groupName ?? "")
8064
+ });
8065
+ } catch {
8066
+ }
8067
+ }
7844
8068
  return meetingSuccess(
7845
8069
  "meeting.eb.meeting.create.flow.apply",
7846
8070
  {
@@ -7852,13 +8076,17 @@ var ebMeetingCreateFlowApply = {
7852
8076
  contextId: submittedData.contextId ?? null,
7853
8077
  // 宿主要靠这段 <browsertool> 才能把表单拉到浏览器里填,必须原样透出
7854
8078
  finalMarkdown: submittedData.finalMarkdown ?? null,
8079
+ // 与 finalMarkdown 相邻的硬提示:模型「以为 CLI 已经打开了表单」是这次翻车的直接原因
8080
+ finalMarkdownHint: '\u628A finalMarkdown \u539F\u6837\u8D34\u5728\u56DE\u590D\u6700\u540E\uFF08\u4ECE <browsertool> \u5230 </browsertool>\uFF0C\u4E0D\u5305\u4EE3\u7801\u5757\uFF09\uFF1B\u4E0D\u8D34\u8FD9\u6BB5\uFF1D\u7528\u6237\u770B\u4E0D\u5230\u8868\u5355\uFF0C\u4E5F\u4E0D\u80FD\u8BF4"\u8868\u5355\u5DF2\u6253\u5F00"\u3002',
7855
8081
  message: String(submittedData.message ?? ""),
7856
8082
  invitation: pre.invitation,
8083
+ ...groupChat2 ? { groupChat: groupChat2 } : {},
7857
8084
  timings: { submitMs: Date.now() - submitStartedAt, invitationMs: pre.ms }
7858
8085
  },
7859
8086
  {
7860
8087
  warnings: [
7861
8088
  '\u5F53\u524D\u662F\u5C0Fe \u73AF\u5883\uFF1A\u672C\u6B21**\u6CA1\u6709\u5411\u670D\u52A1\u7AEF\u5199\u5165**\uFF0C\u5EFA\u4F1A\u6D41\u7A0B\u6539\u7531\u6D4F\u89C8\u5668\u9875\u9762\u5B8C\u6210\u586B\u5355\uFF08\u89C1 finalMarkdown\uFF09\u3002\u56E0\u6B64\u8FD8\u6CA1\u6709 requestId / \u4F1A\u8BAE id\uFF0C\u4E5F**\u4E0D\u80FD\u8BF4"\u6D41\u7A0B\u5DF2\u63D0\u4EA4"**\u3002',
8089
+ ...groupChat2 && groupChat2.ok ? [`\u7FA4\u804A\u5DF2\u540C\u6B65\u5EFA\u597D\uFF08\u7FA4 id ${String(groupChat2.groupId)}\uFF0C\u7FA4\u540D ${String(groupChat2.groupName)}\uFF09\uFF1A\u6D41\u7A0B\u8FD8\u6CA1\u63D0\u4EA4\u3001\u6CA1\u6709\u4F1A\u8BAE id\uFF0C\u6240\u4EE5 imchat_groupid \u6682\u65F6\u6CA1\u56DE\u5199\uFF1B\u4F1A\u8BAE\u751F\u6210\u540E\u518D\u8DD1\u4E00\u6B21 meeting.eb.meeting.group.ensure\uFF08\u4F20 meetingId + groupId\uFF09\u7ED1\u5B9A\u3002`] : groupChat2 ? [`\u7FA4\u804A\u6CA1\u5EFA\u6210\u529F\uFF08${String(groupChat2.error ?? "\u672A\u77E5\u539F\u56E0")}\uFF09\uFF1A\u4F1A\u8BAE\u7167\u5E38\u53EF\u4EE5\u5728\u9875\u9762\u91CC\u63D0\u4EA4\uFF0C\u7FA4\u9700\u8981\u624B\u5DE5\u5EFA\u6216\u7A0D\u540E\u91CD\u8BD5\u3002`] : [],
7862
8090
  `\u9080\u8BF7\u51FD\u5DF2\u6309\u7533\u8BF7\u5355\u4FE1\u606F**\u9884\u751F\u6210**\uFF08\u9884\u7F6E\u51FD\uFF0C${String(pre.invitation.filePath ?? "\u89C1 filePath")}\uFF09\uFF1A\u8BF7\u4E0B\u8F7D\u540E\u4EBA\u5DE5\u6838\u5BF9\u3001\u81EA\u884C\u53D1\u9001\uFF1B\u6D41\u7A0B\u5BA1\u6279\u901A\u8FC7\u3001\u4F1A\u8BAE\u751F\u6210\u540E\u53EF\u7528 mtId \u518D\u8DD1\u4E00\u6B21 meeting.invitation.render \u62FF\u5B8C\u6574\u5B57\u6BB5\u7248\u672C\u3002`,
7863
8091
  '\u26D4 \u4E0D\u8981\u56E0\u4E3A"\u6CA1\u6709 requestId / \u6CA1\u6709\u4F1A\u8BAE id"\u91CD\u590D apply \u2014\u2014 \u586B\u5355\u8981\u5728\u90A3\u4E2A\u6D4F\u89C8\u5668\u9875\u9762\u91CC\u70B9\u63D0\u4EA4\u3002'
7864
8092
  ]
@@ -7873,15 +8101,24 @@ var ebMeetingCreateFlowApply = {
7873
8101
  );
7874
8102
  }
7875
8103
  const warnings = [];
8104
+ const submitDay = dayOf(String(payload?.groupChat?.beginDatetime ?? ""));
8105
+ if (submitDay !== "") void invalidateDayUsages(env, submitDay).catch(() => void 0);
8106
+ void rememberFlowPick(
8107
+ env,
8108
+ String(payload?.workflowId ?? ""),
8109
+ typeof payload?.workflowName === "string" ? payload.workflowName : void 0
8110
+ ).catch(() => void 0);
7876
8111
  const waitSeconds = args.waitSeconds === void 0 ? 20 : Math.max(0, Math.min(180, Number(args.waitSeconds)));
7877
8112
  let meetingId = "";
7878
8113
  const timings = { submitMs: Date.now() - submitStartedAt };
7879
8114
  if (waitSeconds > 0) {
7880
- const { getMeetingOperation: getMeetingOperation2 } = await import("./registry-QCLZEDAP.js");
8115
+ const { getMeetingOperation: getMeetingOperation2 } = await import("./registry-KMHCPAAD.js");
7881
8116
  const list = getMeetingOperation2("meeting.eb.meeting.list");
7882
8117
  const deadline = Date.now() + Math.min(waitSeconds, 30) * 1e3;
7883
8118
  const pollStart = Date.now();
7884
8119
  let waited = 0;
8120
+ let stepIndex = 0;
8121
+ const pollSteps = [500, 1e3, 2e3, 4e3];
7885
8122
  while (Date.now() <= deadline) {
7886
8123
  try {
7887
8124
  const page = await list.handler({ mt_name: payload.mtName, pageSize: 5 }, env);
@@ -7893,9 +8130,11 @@ var ebMeetingCreateFlowApply = {
7893
8130
  }
7894
8131
  } catch {
7895
8132
  }
7896
- if (waited >= 5e3) break;
7897
- await new Promise((resolve6) => setTimeout(resolve6, 5e3));
7898
- waited += 5e3;
8133
+ if (waited >= 7500) break;
8134
+ const step = pollSteps[Math.min(stepIndex, pollSteps.length - 1)];
8135
+ stepIndex += 1;
8136
+ await new Promise((resolve6) => setTimeout(resolve6, step));
8137
+ waited += step;
7899
8138
  }
7900
8139
  timings.pollMs = Date.now() - pollStart;
7901
8140
  }
@@ -7918,11 +8157,44 @@ var ebMeetingCreateFlowApply = {
7918
8157
  );
7919
8158
  }
7920
8159
  }
8160
+ let groupChat;
8161
+ const groupPayload = payload?.groupChat;
8162
+ if (groupPayload) {
8163
+ const groupStart = Date.now();
8164
+ try {
8165
+ const { ensureMeetingGroupChat } = await import("./group-chat-VYBNMJLG.js");
8166
+ const group = await ensureMeetingGroupChat(env, {
8167
+ meetingName: String(payload.mtName ?? ""),
8168
+ beginDatetime: String(groupPayload.beginDatetime ?? ""),
8169
+ endDatetime: String(groupPayload.endDatetime ?? ""),
8170
+ memberIds: Array.isArray(groupPayload.memberIds) ? groupPayload.memberIds : [],
8171
+ ...groupPayload.address ? { address: String(groupPayload.address) } : {},
8172
+ ...meetingId ? { meetingId } : {}
8173
+ });
8174
+ groupChat = { ...group };
8175
+ if (group.ok && group.bound) {
8176
+ warnings.push(
8177
+ `\u5DF2\u6309\u4F1A\u8BAE\u540C\u6B65\u5EFA\u7FA4\u300C${group.groupName ?? payload.mtName}\u300D\uFF08\u7FA4 id ${group.groupId}\uFF09\uFF0C\u5E76\u56DE\u5199\u5230\u4F1A\u8BAE\u8BB0\u5F55 imchat_groupid${group.readBack ? `\uFF08\u56DE\u8BFB ${group.readBack}\uFF09` : ""}\u3002`
8178
+ );
8179
+ } else if (group.ok) {
8180
+ warnings.push(
8181
+ `\u7FA4\u5DF2\u5EFA\u597D\uFF08\u7FA4 id ${group.groupId}\uFF09\uFF0C\u4F46\u4F1A\u8BAE\u8FD8\u6CA1\u751F\u6210\uFF0C\u6682\u65F6\u6CA1\u6CD5\u56DE\u5199 imchat_groupid\uFF1B\u4F1A\u8BAE\u751F\u6210\u540E\u4F20 meetingId+groupId \u8DD1\u4E00\u6B21 meeting.eb.meeting.group.ensure \u7ED1\u5B9A\u5373\u53EF\u3002`
8182
+ );
8183
+ } else {
8184
+ warnings.push(
8185
+ `\u7FA4\u804A\u6CA1\u5EFA\u6210\u529F/\u6CA1\u7ED1\u4E0A\uFF08${group.error ?? "\u672A\u77E5\u539F\u56E0"}\uFF09\uFF1A\u4F1A\u8BAE\u672C\u8EAB\u5DF2\u5EFA\u597D\uFF0C\u7FA4\u53EF\u5728 IM \u91CC\u624B\u5DE5\u5EFA\uFF0C\u518D\u628A\u7FA4 id \u4F20\u5230 meeting.eb.meeting.group.ensure \u7684 groupId \u7ED1\u5B9A\u3002`
8186
+ );
8187
+ }
8188
+ } catch (error) {
8189
+ warnings.push(`\u5EFA\u7FA4\u5F02\u5E38\uFF08\u4E0D\u5F71\u54CD\u5EFA\u4F1A\uFF09\uFF1A${String(error?.message ?? error).slice(0, 200)}`);
8190
+ }
8191
+ timings.groupMs = Date.now() - groupStart;
8192
+ }
7921
8193
  let invitation = { pending: true };
7922
8194
  if (meetingId) {
7923
8195
  const invitationStart = Date.now();
7924
8196
  try {
7925
- const { getMeetingOperation: getMeetingOperation2 } = await import("./registry-QCLZEDAP.js");
8197
+ const { getMeetingOperation: getMeetingOperation2 } = await import("./registry-KMHCPAAD.js");
7926
8198
  const render = getMeetingOperation2("meeting.invitation.render");
7927
8199
  const rendered = await render.handler(
7928
8200
  {
@@ -7960,6 +8232,8 @@ var ebMeetingCreateFlowApply = {
7960
8232
  meetingId: meetingId || null,
7961
8233
  // 参会客户有没有真的写进会议记录(表单侧是 Ebuilder,需 apply 补写;回读确认才算 ok)
7962
8234
  ...crmLinked ? { crmLinked } : {},
8235
+ // 同步建的群(群 id / 群名 / 有没有回写 imchat_groupid)
8236
+ ...groupChat ? { groupChat } : {},
7963
8237
  // 提交后回显「实际提交了什么」:字段名 → 值(人员/客户显示姓名,不显示 id)。
7964
8238
  // 用户要的就是"能看见内容",替代走不通的浏览器填单核对。
7965
8239
  submittedPreview: renderFormPreview(
@@ -8033,7 +8307,12 @@ var ebMeetingCreateFlowQuick = {
8033
8307
  },
8034
8308
  dateFrom: {
8035
8309
  type: "string",
8036
- description: "\u6CA1\u7ED9\u5177\u4F53\u65F6\u95F4\u65F6\u6309\u54EA\u4E00\u5929\u63A8\u8350\u65F6\u6BB5\uFF08yyyy-MM-dd\uFF1B\u4E0D\u4F20\u9ED8\u8BA4\u660E\u5929\uFF09"
8310
+ description: "\u6CA1\u7ED9\u5177\u4F53\u65F6\u95F4\u65F6\u6309\u54EA\u4E00\u5929\u63A8\u8350\u65F6\u6BB5\uFF08yyyy-MM-dd\uFF1B\u4E0D\u4F20\u9ED8\u8BA4\u660E\u5929\uFF09\u3002\u26A0\uFE0F \u7528\u6237\u8BF4\u4E86\u300C\u4E0A\u5348/\u4E0B\u5348/\u665A\u4E0A\u300D\u5C31\u5FC5\u987B\u540C\u65F6\u4F20 time_slot \u2014\u2014 \u53EA\u4F20 dateFrom \u4F1A\u5F39\u65F6\u6BB5\u9009\u62E9\u5668\u8BA9\u7528\u6237\u518D\u9009\u4E00\u6B21"
8311
+ },
8312
+ time_slot: {
8313
+ type: "string",
8314
+ enum: ["\u4E0A\u5348", "\u65E9\u4E0A", "\u4E0B\u5348", "\u665A\u4E0A"],
8315
+ description: '\u7528\u6237\u53EA\u8BF4\u4E86\u300C\u4E0A\u5348/\u4E0B\u5348/\u665A\u4E0A\u300D\u65F6\u4F20\u8FD9\u4E2A\uFF08\u914D\u5408 dateFrom\uFF09\uFF1A\u4E0A\u5348/\u65E9\u4E0A=09:00\u201312:00\u3001\u4E0B\u5348=13:00\u201318:00\u3001\u665A\u4E0A=18:00\u201321:00\uFF0CCLI \u76F4\u63A5\u5B9A\u4E0B\u6765\u3001\u4E0D\u518D\u8FD4\u56DE\u65F6\u6BB5\u5019\u9009\u3002\u26D4 \u4E0D\u8981\u53EA\u4F20 dateFrom \u5C31\u671F\u5F85"\u8BA9\u7528\u6237\u9009\u65F6\u6BB5"\u2014\u2014\u7528\u6237\u5DF2\u7ECF\u8BF4\u4E86\u65F6\u6BB5\u5C31\u522B\u518D\u95EE'
8037
8316
  },
8038
8317
  durationMinutes: {
8039
8318
  type: "number",
@@ -8049,7 +8328,7 @@ var ebMeetingCreateFlowQuick = {
8049
8328
  flowChoice: {
8050
8329
  type: "string",
8051
8330
  enum: ["auto", "ask"],
8052
- description: "\u591A\u4E2A\u5EFA\u4F1A\u6D41\u7A0B**\u90FD\u6709\u53D1\u8D77\u6743\u9650**\u65F6\uFF1A\u9ED8\u8BA4\uFF08\u4E0D\u4F20 / ask\uFF09= \u8FD4\u56DE\u9009\u9879\u8BA9\u7528\u6237\u6311\uFF1Bauto = \u81EA\u52A8\u53D6\u4F18\u5148\u7EA7\u6700\u9AD8\u7684\u3002\u53EA\u6709 1 \u4E2A\u6709\u6743\u9650\u65F6\u76F4\u63A5\u53D1\u8D77"
8331
+ description: "\u591A\u4E2A\u5EFA\u4F1A\u6D41\u7A0B**\u90FD\u6709\u53D1\u8D77\u6743\u9650**\u65F6\uFF1A\u9ED8\u8BA4\uFF08\u4E0D\u4F20 / ask\uFF09= \u8FD4\u56DE\u9009\u9879\u8BA9\u7528\u6237\u6311\uFF1Bauto = \u81EA\u52A8\u53D6\u4F18\u5148\u7EA7\u6700\u9AD8\u7684\u3002\u6709\u6D41\u7A0B\u8BB0\u5FC6\uFF08\u4E0A\u6B21\u6210\u529F\u7528\u8FC7\u7684\u6D41\u7A0B\uFF09\u4E14\u4ECD\u53EF\u53D1\u8D77\u65F6\u9ED8\u8BA4\u6CBF\u7528\u4E0A\u6B21\u9009\u62E9\uFF0C\u4F20 ask \u5F3A\u5236\u6BCF\u6B21\u90FD\u95EE\u3002\u53EA\u6709 1 \u4E2A\u6709\u6743\u9650\u65F6\u76F4\u63A5\u53D1\u8D77"
8053
8332
  },
8054
8333
  crm_skip: {
8055
8334
  type: "boolean",
@@ -8078,7 +8357,7 @@ var ebMeetingCreateFlowQuick = {
8078
8357
  `\u4F1A\u8BAE\u540D\u79F0/\u5185\u5BB9\u91CC\u63D0\u5230\u5BA2\u6237\u300C${crmMentioned}\u300D\uFF0C\u4F46\u6CA1\u4F20 crm_members \u2014\u2014 \u63D0\u4EA4\u540E\u300C\u53C2\u4F1A\u5BA2\u6237\u300D\u4F1A\u662F\u7A7A\u7684\u3002\u5148 meeting.eb.crm.search {"keyword":"${crmMentioned}"} \u62FF items[].customerId\uFF0C\u518D\u628A crm_members:[{"id":"<customerId>","name":"<\u5B8C\u6574\u5BA2\u6237\u540D>"}] \u4E00\u8D77\u4F20\uFF08\u5FC5\u987B\u5E26\u540D\u79F0\uFF0C\u53EA\u7ED9 id \u4F1A\u88AB\u9759\u9ED8\u5B58\u7A7A\uFF09\uFF1B\u786E\u5B9E\u4E0D\u9700\u8981\u586B\u53C2\u4F1A\u5BA2\u6237\u5C31\u4F20 crm_skip:true\u3002`
8079
8358
  );
8080
8359
  }
8081
- const { getMeetingOperation: getMeetingOperation2 } = await import("./registry-QCLZEDAP.js");
8360
+ const { getMeetingOperation: getMeetingOperation2 } = await import("./registry-KMHCPAAD.js");
8082
8361
  const prepareStartedAt = Date.now();
8083
8362
  const { submit_mode: _submitMode, confirm: _confirm, ...prepareArgs } = args;
8084
8363
  const prepared = await getMeetingOperation2("meeting.eb.meeting.create.flow.prepare").handler(
@@ -8116,12 +8395,15 @@ var ebMeetingCreateFlowQuick = {
8116
8395
  requestId: applied?.data?.requestId,
8117
8396
  meetingId: applied?.data?.meetingId ?? null,
8118
8397
  invitation: applied?.data?.invitation ?? null,
8398
+ // 同步建的群(群 id / 群名 / 有没有回写 imchat_groupid)
8399
+ ...applied?.data?.groupChat ? { groupChat: (applied?.data).groupChat } : {},
8119
8400
  // 已提交内容回显(字段名 → 值),提交后可直接贴给用户看"到底填进去了什么"
8120
8401
  submittedPreview: applied?.data?.submittedPreview ?? null,
8121
8402
  // 小e 环境(BROWSER_FILL)不写服务端,表单靠这段 <browsertool> 在浏览器里填 —— 必须一起透出,
8122
8403
  // 否则宿主拿不到表单,用户看到的就是"提交了但没反应"。
8123
8404
  ...applied?.data?.contextId ? { contextId: (applied?.data).contextId } : {},
8124
8405
  ...applied?.data?.finalMarkdown ? { finalMarkdown: (applied?.data).finalMarkdown } : {},
8406
+ ...applied?.data?.finalMarkdownHint ? { finalMarkdownHint: (applied?.data).finalMarkdownHint } : {},
8125
8407
  decisions: prepared?.data?.preview?.decisions ?? null,
8126
8408
  timings: {
8127
8409
  ...prepared?.data?.preview?.decisions?.timings ?? {},
@@ -8173,7 +8455,7 @@ var ebMeetingCreateSuggest = {
8173
8455
  const topN = Math.max(1, Math.min(5, Number(args.topN) || 3));
8174
8456
  const rawMembers = String(args.hrm_members ?? "").split(/[,;,;\s]+/).map((item) => item.trim()).filter((item) => item !== "");
8175
8457
  const nameLike = rawMembers.filter((item) => !/^\d+$/.test(item));
8176
- const nameToId = nameLike.length > 0 ? await import("./schedule-UASAVDVD.js").then((m) => m.resolveMemberIdsByName(env, nameLike)).catch(() => /* @__PURE__ */ new Map()) : /* @__PURE__ */ new Map();
8458
+ const nameToId = nameLike.length > 0 ? await import("./schedule-5GCACCK7.js").then((m) => m.resolveMemberIdsByName(env, nameLike)).catch(() => /* @__PURE__ */ new Map()) : /* @__PURE__ */ new Map();
8177
8459
  const memberIds = rawMembers.map((item) => nameToId.get(item) ?? item);
8178
8460
  const unresolved = rawMembers.filter((item) => nameToId.get(item) === void 0 && !/^\d+$/.test(item));
8179
8461
  const selfId = await env.host.getSession().then((s) => String(s?.userId ?? "")).catch(() => "");
@@ -8345,7 +8627,7 @@ var ebAutoInvitationAfterWrite = async (context) => {
8345
8627
  const mtId = String(context.dataIds?.[0] ?? "").trim();
8346
8628
  if (!isCreate || !enabled || !mtId) return association;
8347
8629
  try {
8348
- const { getMeetingOperation: getMeetingOperation2 } = await import("./registry-QCLZEDAP.js");
8630
+ const { getMeetingOperation: getMeetingOperation2 } = await import("./registry-KMHCPAAD.js");
8349
8631
  const render = getMeetingOperation2("meeting.invitation.render");
8350
8632
  const result = await render.handler({ mtId }, context.env);
8351
8633
  return { ...association ?? {}, invitation: result?.data ?? null };
@@ -8370,6 +8652,7 @@ var meetingEbOperations = [
8370
8652
  ...meetingEbScheduleOperations,
8371
8653
  ...meetingEbCrmOperations,
8372
8654
  ...meetingEbCreateFlowOperations,
8655
+ ...meetingEbGroupChatOperations,
8373
8656
  ebRoomRecommendOperation
8374
8657
  ];
8375
8658